ARM按键中断

do_irq.c

判断中断号

#include "key_it.h"
extern void printf(const char *fmt, ...);
unsigned int i = 0;
void do_irq(void)
{
    // 获取中断号,根据中断号的不同进行不同的中断处理
    int irqno;
    irqno = GICC->IAR & 0x3ff;
    switch (irqno)
    {
    case 99:
        printf("key1 int\n");
        // 清除exti中断标志位
        EXTI->FPR1 |= (0x1 << 9);
        // 清除GICD中断标志位  99/32=3...3
        GICD->ICPENDR[3] = (0x1 << 3);
        led1_on();
        break;
    case 97:
        printf("key2 int\n");
        // 清除exti中断标志位
        EXTI->FPR1 |= (0x1 << 7);
        // 清除GICD中断标志位
        GICD->ICPENDR[3] = (0x1 << 1);
        led1_off();
        break;
    case 98:
        printf("key3 int\n");
        // 清除exti中断标志位
        EXTI->FPR1 |= (0x1 << 8);
        // 清除GICD中断标志位
        GICD->ICPENDR[3] = (0x1 << 2);
        break;
    }
    // 清除IAR寄存器的值,也就是中断号
    GICC->EOIR = irqno;
}

 key_it.c

按钮操作

#include "key_it.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->CTRL |= 0x1;
    //10.设置中断优先级掩码
    GICC->PMR |= (0x1f << 3);
    //11.允许中断被转发给CPU处理
    GICC->CTRL |= 0x1;
}
void key2_it_config()
{
    //1.设置GPIOF时钟使能
    RCC->MP_AHB4ENSETR |= (0X1 << 5);
    // 2.将PF7管脚设置为输入
    GPIOF->MODER &= (~(0x3 << 14));
    //3.设置由PF7产生EXTI7事件
    EXTI->EXTICR2 &= (~(0XFF << 24));
    EXTI->EXTICR2 |= (0x05 << 24);
    // 4.设置EXTI7事件的检测方式为下降沿检测
    EXTI->FTSR1 |= (0x1 << 7);
    // 5.允许中断不屏蔽,可以被转发到GIC
    EXTI->C1IMR1 |= (0x1 << 7);
    // 6.允许EXTI7(97号)中断被保存在组0中
    GICD->ISENABLER[3] |= (0x1 << 1);
    // 7.设置97号中断优先级
    GICD->IPRIORITYR[24] &= (~(0x1f << 11));
    GICD->IPRIORITYR[24] |= (0x0 << 11);
    // 8.设置97号中断可以被CPU0处理
    GICD->ITARGETSR[24] &= (~(0x3 << 8));
    GICD->ITARGETSR[24] |= (0x1 << 8);
    //9.允许97号中断被转发到CPU接口层
    GICD->CTRL |= 0x1;
    //10.设置中断优先级掩码
    GICC->PMR |= (0x1f << 3);
    //11.允许中断被转发给CPU处理
    GICC->CTRL |= 0x1;
}
void key3_it_config()
{
    //1.设置GPIOF时钟使能
    RCC->MP_AHB4ENSETR |= (0X1 << 5);
    // 2.将PF8管脚设置为输入
    GPIOF->MODER &= (~(0x3 << 16));
    //3.设置由PF8产生EXTI8事件
    EXTI->EXTICR3 &= (~(0XFF << 0));
    EXTI->EXTICR3 |= (0x05 << 0);
    // 4.设置EXTI8事件的检测方式为下降沿检测
    EXTI->FTSR1 |= (0x1 << 8);
    // 5.允许中断不屏蔽,可以被转发到GIC
    EXTI->C1IMR1 |= (0x1 << 8);
    // 6.允许EXTI8(98号)中断被保存在组0中 98/32=3...2
    GICD->ISENABLER[3] |= (0x1 << 2);
    // 7.设置98号中断优先级   98/4=24...2     2*8+3=19
    GICD->IPRIORITYR[24] &= (~(0x1f << 19));
    GICD->IPRIORITYR[24] |= (0x0 << 19);
    // 8.设置98号中断可以被CPU0处理 98/4=24...2
    GICD->ITARGETSR[24] &= (~(0x3 << 16));
    GICD->ITARGETSR[24] |= (0x1 << 16);
    //9.允许97号中断被转发到CPU接口层
    GICD->CTRL |= 0x1;
    //10.设置中断优先级掩码
    GICC->PMR |= (0x1f << 3);
    //11.允许中断被转发给CPU处理
    GICC->CTRL |= 0x1;
}
void all_led_init()
{
   //1.使能外设时钟
  (*((unsigned int*)0X50000A28)) |= (0x3<<4);
  //2.设置PF9为输出输出
  (*((unsigned int*)0X50007000)) &= (~(0x3<<12));
  (*((unsigned int*)0X50007000)) |= (0x1<<12);
  //3.设置推挽输出
  (*((unsigned int*)0X50007004)) &= (~(0x1<<6));
  //4.设置输出速度为低速
  (*((unsigned int*)0X50007008)) &= (~(0x3<<12));
//5.设置无上拉下拉
  (*((unsigned int*)0X5000700c)) &= (~(0x3<<12));
  
}

void led1_on()
{
    
  (*((unsigned int*)0X50007014)) |= (0x1<<6);

}


void led1_off()
{
  (*((unsigned int*)0X50007014)) &= (~(0x1<<6));

}

key_it.h

#ifndef __KEY_IT_H__
#define __KEY_IT_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();
void all_led_init();
void led1_on();
void led1_off();
#endif

main.c

#include "key_it.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();

    all_led_init();

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

    while(1)

    {

        printf("main func\n");

        delay(2000);



    }

    return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 您好!以下是如何在STM32上编写按键中断程序的步骤: 1. 首先,需要确定使用的按键的引脚和对应的GPIO端口。根据STM32芯片型号和具体硬件设计,可以查找对应的引脚和GPIO端口的信息。 2. 在程序中,需要初始化对应的GPIO端口为输入模式,以使其能够接受按键的输入信号。可以使用STM32提供的库函数进行初始化。 3. 接下来,需要设置对应GPIO端口的中断触发方式,以便在按键被按下时,能够触发中断。可以使用STM32提供的库函数进行设置。 4. 定义中断服务函数,在按键被按下时执行相应的操作。可以在中断服务函数中编写相应的代码,比如改变LED的状态等。 5. 在主函数中,开启中断并等待按键中断的发生。可以使用STM32提供的库函数进行中断开启。 以上是在STM32上编写按键中断程序的基本步骤,希望能对您有所帮助! ### 回答2: STM32是一种具有强大功能的微控制器系列,它采用了ARM Cortex-M内核,并且广泛应用于各种嵌入式系统中。下面我将提供一个大致的按键中断编程示例。 首先,我们需要将按键连接到STM32开发板上的某个IO口上。假设我们使用的是GPIOA的第0号引脚作为按键输入口。 接下来,我们需要在STM32的引脚配置寄存器中,将GPIOA的引脚0配置为输入模式。可以通过修改GPIOA_MODER寄存器来实现: GPIOA->MODER &= ~(GPIO_MODER_MODE0); // 将第0号引脚的MODER位清零 GPIOA->MODER |= (GPIO_MODER_MODE0_0); // 设置第0号引脚为输入模式 然后,我们需要在STM32中使能外部中断。在这个例子中,我们将使用外部中断线0,对应于EXTI0_IRQn。 EXTI->IMR |= (EXTI_IMR_MR0); // 使能外部中断线0 EXTI->FTSR |= (EXTI_FTSR_TR0); // 配置为下降沿触发 接下来,我们需要编写中断服务程序,当按键被按下时,该中断服务程序将被调用。 void EXTI0_IRQHandler(void) { if(EXTI->PR & EXTI_PR_PR0) // 检查外部中断线0的中断标志位 { // 执行按键按下后的操作 // 这里可以编写按键按下后需要执行的代码 EXTI->PR |= (EXTI_PR_PR0); // 清除中断标志位 } } 最后,我们需要在主程序中将中断服务程序注册到对应的中断向量中。 NVIC_EnableIRQ(EXTI0_IRQn); // 使能外部中断线0的中断 NVIC_SetPriority(EXTI0_IRQn, 0); // 设置中断优先级 通过以上步骤,我们就可以实现按键中断功能。当按键被按下时,中断服务程序将被执行。我们可以在中断服务程序中编写相应的代码,来处理按键按下后的操作。 ### 回答3: STM32写按键中断程序的基本步骤如下: 1. 首先,需要配置GPIO作为输入引脚,用于连接按键。可以选择合适的GPIO引脚,并设置为输入模式。 2. 配置NVIC(Nested Vectored Interrupt Controller),使能外部中断。选择适当的中断线、中断优先级等配置。 3. 配置外部中断触发方式。可以选择上升沿触发、下降沿触发或双边沿触发。根据实际需求配置。 4. 实现中断服务程序。当按键产生中断时,MCU会自动跳转到中断服务程序。在中断服务程序中,可以对按键事件进行处理。 5. 根据实际需求,可以在中断服务程序中进行按键的消抖处理。可以通过软件延时或硬件电路设计等方式进行按键消抖。 6. 根据需要,在中断服务程序中进行按键事件的处理。可以通过编写逻辑代码来实现按键的各种功能操作,比如控制LED灯的亮灭等。 7. 最后,记得在主函数中使能全局中断,以便正常触发和处理按键中断。 以上是编写STM32按键中断程序的基本步骤。根据具体的开发环境和需求,可以根据以上步骤进行相应的配置和编程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值