ARM(中断实验) 2023.12.12

发布时间:2023年12月18日

main.h

#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

#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

#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

#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;

}

文章来源:https://blog.csdn.net/m0_72948049/article/details/134959715
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。