ARM(中断实验) 2023.12.12

main.h

cpp 复制代码
#include "key_interrupt.h"

#include "myuart.h"



void delay(int ms)

{

  int i,j;

  for(i=0;i<ms;i++)

  {

  for(j=0;j<2000;j++);

  }

}

int main()

{

    //中断初始化

    key1_it_config();

    key2_it_config();

    key3_it_config();

    //灯初始化

    led_init();

    

    //现象是发送一个a串口工具打印一个b

    while(1)

    {



    }

    return 0;

}

key_interrupt.h

cpp 复制代码
#ifndef __KEY_INTERRUPT_H__
#define __KEY_INTERRUPT_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gic.h"



void key1_it_config();
void key2_it_config();
void key3_it_config();
#endif

key_interrupt.c

cpp 复制代码
#include"key_interrupt.h"

void key1_it_config()
{
    
    //   1.设置GPIOF时钟使能
    RCC->MP_AHB4ENSETR |= (0x1 << 5);
    //   2.将PF9管脚设置为输入
    GPIOF->MODER &= (~(0x3 << 18));
    //   3.设置由PF9产生EXTI9事件
    EXTI->EXTICR3 &= (~(0xff << 8));
    EXTI->EXTICR3 |= (0x05 <<8);
    //   4.设置EXTI9事件的检测方式为下降沿检测
    EXTI->FTSR1 |= (0x1 << 9);
    //   5.允许中断不屏蔽,可以被转发到GIC
    EXTI->C1IMR1 |= (0x1 << 9);
    //   6.允许EXTI9(99号)中断被保存在组0中
    GICD->ISENABLER[3] |= (0x1 << 3);
    //   7.设置99号中断优先级
    GICD->IPRIORITYR[24] &= (~(0x1f << 27));
    GICD->IPRIORITYR[24] |= (0x0 << 27);
    //   8.设置99号中断可以被CPU0处理
    GICD->ITARGETSR[24] &= (~(0x3 << 24));
    GICD->ITARGETSR[24] |= (0x1 << 24);
    //   9.允许99号中断被转发到CPU接口层
    GICD->CTLR |= (0x1);
    //   10.设置中断优先级掩码
    GICC->PMR |= (0x1f<<3);
    //   11.允许中断被转发给CPU处理
    GICC->CTRL |= (0x1);
    

}
void key3_it_config()
{
    //设置GPIOF时钟使能
    RCC->MP_AHB4ENSETR |= (0x1 << 5);
    //将PF8设置为输入模式
    GPIOF->MODER &= (~(0x3 << 16));
    //设置由PF8产生EXIT8事件---[7:0]的8位先清零,再置位为0x05
    EXTI->EXTICR3 &= (~(0xff));
    EXTI->EXTICR3 |= (0x05);
    //设置下降沿检测
    EXTI->FTSR1 |= (0x1 << 8);
    //设置中断不屏蔽
    EXTI->C1IMR1 |= (0x1 << 8);
    //设置允许中断发送到GICD中
    GICD->ISENABLER[3] |= (0x1 << 2);
    //设置优先级
    GICD->IPRIORITYR[24] &= (~(0x1f << 19));
    GICD->IPRIORITYR[24] |= (0x0 << 19);
    //选择进程目标处理器
    GICD->ITARGETSR[24] &= (~(0x3 << 16));
    GICD->ITARGETSR[24] |= (0x1 << 16);
    //允许中断到CPU接口层
    GICD->CTLR |= (0x1);
    //使能中断转发到CPU中
    GICC->CTRL |= 0x1;
    //设置优先级掩码
    GICC->PMR |= (0x1f << 3);
    
}


void key2_it_config()
{
    //1.设置GPIOF组使能----------------------PF7
    RCC->MP_AHB4ENSETR |= (0x1<<5);
    //2.设置PF7为输入模式
    GPIOF->MODER &= (~(0x3 << 14));
    //3.设置exti的事件选择为exti7模式
    EXTI->EXTICR2 &= (~(0xff << 24));
    EXTI->EXTICR2 |= (0x05 << 24);
    //4.设置不屏蔽中断
    EXTI->C1IMR1 |= (0x1 << 7);
    //5.设置下降沿检测
    EXTI->FTSR1 |= (0x1 << 7);
    //6.GICD允许中断进入GICD中
    GICD->ISENABLER[3] |= (0x1 << 1);
    //7.设置优先级
    GICD->IPRIORITYR[24] &= (~(0x1f << 11));
    GICD->IPRIORITYR[24] |= (0x0 << 11);
    //8.设置目标处理器
    GICD->ITARGETSR[24] &= ((~0x3 << 8));
    GICD->ITARGETSR[24] |= (0x1 << 8);
    //9.设置使能进入GICC
    GICD->CTLR |= (0x1);
    //11.设置优先级掩码
    GICC->PMR |= (0x1f << 3);
    //10.设置允许进入GICC
    GICC->CTRL |= 0x1;  
}

do_irq

cpp 复制代码
#include "key_interrupt.h"
#include "myuart.h"


extern void printf(const char *fmt, ...);
unsigned int i = 0;
void do_irq(void) 
{
    //获取中断号,根据中断号的不同进行不同的中断处理

    int irqno;
    irqno=GICC->IAR&0x3ff;
    static int i=0,j=0,k=0;
    switch(irqno)
    {
        case 99:
            printf("key1 int\n");
            if(i==0)
            {
                led1_on();
                i = 1;
            }
            else if(i==1)
            {
                led1_off();
                i = 0;
            }
            //清除exti中断标志位
            EXTI->FPR1 |= (0x1 << 9);
            //清除GICD中断标志位
            GICD->ICPENDR[3] = (0x1 << 3);
            break;
        case 98:
            printf("key3 int\n");
            if(k==0)
            {
                led3_on();
                k = 1;
            }
            else if(k==1)
            {
                led3_off();
                k = 0;
            }
            //清除exti中断标志位
            EXTI->FPR1 |= (0x1 <<8);
            //清除GICD中断标志位
            GICD->ICPENDR[3] |= (0x1 <<2);
            break;
        case 97:
            printf("key2 int\n");
            if(j==0)
            {
                led2_on();
                j = 1;
            }
            else if(j==1)
            {
                led2_off();
                j = 0;
            }
            EXTI->FPR1 |= (0x1 << 7);
            GICD->ICPENDR[3] |= (0x1 << 1);
            break;
    }
    //清除IAR寄存器的值
    GICC->EOIR = irqno;

}
相关推荐
珞光电子USRP SDR软件无线电平台2 天前
国产嵌入式SDR平台LW-E320-G详解:射频、FPGA、ARM架构与应用选型
arm开发·fpga开发·架构
Jason_zhao_MR2 天前
Linux与采集MCU通信为什么我们用了双SPI
linux·arm开发·单片机·嵌入式硬件·嵌入式
ARM|X86+FPGA工业主板厂家2 天前
基于嵌入式 GPU 的智能服务机器人
linux·运维·arm开发·fpga开发·机器人
一池秋_3 天前
arm低配linux设备,桌面应用冷启动提速方法
linux·运维·arm开发
qq_402995754 天前
诊断协议栈配置Agent
arm开发·人工智能·stm32·单片机·mcu
一木 之林6 天前
三.C++ 内存管理(进阶)(二)
开发语言·arm开发·c++
hongmai6668886 天前
MP2348GTL-Z:这颗24V/4A同步降压芯片,把性能和体积平衡得恰到好处
c语言·开发语言·arm开发·单片机·5g
隔窗听雨眠8 天前
ARM架构下Logstash与Elasticsearch集群部署完全指南:从环境适配到生产验证
arm开发·elasticsearch·架构
郭老师-嵌入式8 天前
arm linux 移植 udhcp 与 使用
linux·服务器·arm开发
深念Y8 天前
登录日志与管理员审计日志存储决策
前端·arm开发·后端·微服务·云原生·架构