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;

}
相关推荐
TeYiToKu16 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
w微信150135078121 天前
小华一级 代理商 HC32F005C6PA-TSSOP20 HC32F005系列
c语言·arm开发·单片机·嵌入式硬件
憧憬一下1 天前
Pinctrl子系统中Pincontroller和client驱动程序的编写
arm开发·嵌入式·c/c++·linux驱动开发
上海知从科技2 天前
知从科技受邀出席ARM日产技术日
arm开发·科技
极客小张3 天前
基于STM32的智能温室环境监测与控制系统设计(代码示例)
c语言·arm开发·stm32·单片机·嵌入式硬件·物联网·毕业设计
TeYiToKu3 天前
笔记整理—linux驱动开发部分(6)platform平台总线
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件
飞腾开发者4 天前
飞腾平台Arm ComputeLibrary编译安装指南
linux·服务器·arm开发·后端·性能优化
CodingCos4 天前
【ARM Linux 系统稳定性分析入门及渐进 1.1 -- Crash 工具功能概述】
linux·arm开发·crash tools·linux crash·crash 工具使用
@haihi5 天前
IIC和SPI的区别和相同之处
arm开发·stm32·mcu
@@庆5 天前
FreeRTOS 数据传输方法(环形buffer,队列的本质)队列实验—多设备玩游戏
arm开发·stm32·单片机·嵌入式硬件·freertos