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;

}
相关推荐
CinzWS3 小时前
A53多核协同(上):核间通信与缓存一致性协议——ARM多核的“心灵感应“
arm开发·嵌入式·芯片验证·原型验证·a53
CinzWS9 小时前
A53多核协同(下):一致性内存模型与内存屏障——ARM多核的“时间魔法“
arm开发·嵌入式·原型验证·a53
EnglishJun10 小时前
ARM嵌入式学习(二十四)--- 库移植(移植到开发板)
arm开发·学习
AI服务老曹21 小时前
异构计算时代的安防底座:基于 Docker 的 X86/ARM 双模部署与 NPU 资源池化实战
arm开发·docker·容器
EnglishJun1 天前
ARM嵌入式学习(二十三)--- I2C总线和SPI总线
arm开发·学习
wwwlyj1233211 天前
arm dap
arm开发
想放学的刺客2 天前
单片机嵌入式试题(第34期)嵌入式开发的利器:逻辑分析仪与示波器深度解析
arm开发·stm32·单片机·嵌入式硬件·物联网
CinzWS3 天前
A53电源管理(下):DVFS与热管理的硬件实现——ARM芯片的“冷静艺术“
arm开发·嵌入式·芯片验证·原型验证·a53
誰能久伴不乏3 天前
剥开协议的伪装:用 Wireshark 显微镜级拆解 TCP 握手与挥手
arm开发·tcp/ip·wireshark
somi73 天前
ARM-驱动-10自定义通信协议
linux·arm开发·自用