ARM按键中断

do_irq.c 

#include "key.h"
extern void printf(const char *fmt, ...);
unsigned int i = 0;
unsigned int num1 = 0, num2 = 0,num3 = 0; //用于记录按键按下次数
void do_irq(void) 
{
    int irqno;//保存中断号
    irqno=GICC->IAR & 0X3FF;
    switch(irqno)
    {
        case 99://key1
            //按键1中断处理
            printf("KEY1 INT\n");
            //灯亮
            if(num1 == 0)
            {
                //PF10
                GPIOF->ODR |= (0x1<<10);
                //PE10 PE8
                GPIOE->ODR |= (0x5<<8);
                num1++;
            }
            //灯灭
            else if(num1 > 0)
            {
                //PF10
                GPIOF->ODR &= ~(0x1<<10);
                //PE10 PE8
                GPIOE->ODR &= ~(0x5<<8);
                num1 = 0;
            }
            //清除挂起中断标志位GICD_ICPENDRx
            GICD->ICPENDR[3] |= (0x1<<3);
            //清除中断触发标志位EXTI_FPR1
            EXTI->FPR1 |= (0x1<<9);
            break;
        case 97://key2
            //按键2中断处理
            printf("KEY2 INT\n");
            //蜂鸣器转
            if(num2 == 0)
            {
                //PB6
                GPIOF->ODR |= (0x1<<6);
                num2++;
            }
            //蜂鸣器停
            else if(num2 > 0)
            {
                //PB6
                GPIOF->ODR &= ~(0x1<<6);
                num2 = 0;
            }
            //清除挂起中断标志位GICD_ICPENDRx
            GICD->ICPENDR[3] |= (0x1<<1);
            //清除中断触发标志位EXTI_FPR1
            EXTI->FPR1 |= (0x1<<7);
            break;
        case 98://key3
            //按键3中断处理
            printf("KEY3 INT\n");
            //风扇转
            if(num3 == 0)
            {
                //PE9
                GPIOE->ODR |= (0x1<<9);
                num3++;
            }
            //风扇停
            else if(num3 > 0)
            {
                //PE9
                GPIOE->ODR &= ~(0x1<<9);
                num3 = 0;
            }
            //清除挂起中断标志位GICD_ICPENDRx
            GICD->ICPENDR[3] |= (0x1<<2);
            //清除中断触发标志位EXTI_FPR1
            EXTI->FPR1 |= (0x1<<8);
            break;
    }
    //清除处理完的中断号GICC_EOIR
    GICC->EOIR =irqno;
}

key.h 

#ifndef __KEY_H__
#define __KEY_H__
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gic.h"
void key_config();
void key3_config();
#endif

 key.c

#include "key.h"
extern void printf(const char *fmt, ...);
unsigned int i = 0;
unsigned int num1 = 0, num2 = 0,num3 = 0; //用于记录按键按下次数
void do_irq(void) 
{
    int irqno;//保存中断号
    irqno=GICC->IAR & 0X3FF;
    switch(irqno)
    {
        case 99://key1
            //按键1中断处理
            printf("KEY1 INT\n");
            //灯亮
            if(num1 == 0)
            {
                //PF10
                GPIOF->ODR |= (0x1<<10);
                //PE10 PE8
                GPIOE->ODR |= (0x5<<8);
                num1++;
            }
            //灯灭
            else if(num1 > 0)
            {
                //PF10
                GPIOF->ODR &= ~(0x1<<10);
                //PE10 PE8
                GPIOE->ODR &= ~(0x5<<8);
                num1 = 0;
            }
            //清除挂起中断标志位GICD_ICPENDRx
            GICD->ICPENDR[3] |= (0x1<<3);
            //清除中断触发标志位EXTI_FPR1
            EXTI->FPR1 |= (0x1<<9);
            break;
        case 97://key2
            //按键2中断处理
            printf("KEY2 INT\n");
            //蜂鸣器转
            if(num2 == 0)
            {
                //PB6
                GPIOF->ODR |= (0x1<<6);
                num2++;
            }
            //蜂鸣器停
            else if(num2 > 0)
            {
                //PB6
                GPIOF->ODR &= ~(0x1<<6);
                num2 = 0;
            }
            //清除挂起中断标志位GICD_ICPENDRx
            GICD->ICPENDR[3] |= (0x1<<1);
            //清除中断触发标志位EXTI_FPR1
            EXTI->FPR1 |= (0x1<<7);
            break;
        case 98://key3
            //按键3中断处理
            printf("KEY3 INT\n");
            //风扇转
            if(num3 == 0)
            {
                //PE9
                GPIOE->ODR |= (0x1<<9);
                num3++;
            }
            //风扇停
            else if(num3 > 0)
            {
                //PE9
                GPIOE->ODR &= ~(0x1<<9);
                num3 = 0;
            }
            //清除挂起中断标志位GICD_ICPENDRx
            GICD->ICPENDR[3] |= (0x1<<2);
            //清除中断触发标志位EXTI_FPR1
            EXTI->FPR1 |= (0x1<<8);
            break;
    }
    //清除处理完的中断号GICC_EOIR
    GICC->EOIR =irqno;
}

led.c

#include "led.h"
// 毫秒延时
void delay(int ms)
{
    int i, j;
    for (i = 0; i < ms; i++)
    {
        for (j = 0; j < 2000; j++);
    }
}
// 微秒延时
void delay_um(int us)
{
    int i = 0;
    while (us--)
    {
        i = 10;
        while (i--){}
    }
}
// GPIO初始化
void led_start()
{
    // 使能GPIO的外设时钟
    RCC->MP_AHB4ENSETR |= (0X3 << 4);
    // 设置PE10为输出
    GPIOE->MODER &= (~(0X3 << 20));
    GPIOE->MODER |= (0x1 << 20);
    // 设置PF10为输出
    GPIOF->MODER &= (~(0X3 << 20));
    GPIOF->MODER |= (0x1 << 20);
    // 设置PE8为输出
    GPIOE->MODER &= (~(0X3 << 16));
    GPIOE->MODER |= (0x1 << 16);
    // 设置PE9为输出
    GPIOE->MODER &= (~(0X3 << 18));
    GPIOE->MODER |= (0x1 << 18);
    // 设置PB6为输出
    GPIOB->MODER &= (~(0X3 << 12));
    GPIOB->MODER |= (0x1 << 12);
    // 设置PF6为输出
    GPIOF->MODER &= (~(0X3 << 12));
    GPIOF->MODER |= (0x1 << 12);

    // 设置PE10为推挽输出
    GPIOE->OTYPER &= (~(0X1 << 10));
    // 设置PF10为推挽输出
    GPIOF->OTYPER &= (~(0X1 << 10));
    // 设置PE8为推挽输出
    GPIOE->OTYPER &= (~(0X1 << 8));
    // 设置PE9为推挽输出
    GPIOE->OTYPER &= (~(0X1 << 9));
    // 设置PB6为推挽输出
    GPIOB->OTYPER &= (~(0X1 << 6));
    // 设置PF6为推挽输出
    GPIOF->OTYPER &= (~(0X1 << 6));

    // 设置PE10为低速输出
    GPIOE->OSPEEDR &= (~(0X3 << 20));
    // 设置PF10为低速输出
    GPIOF->OSPEEDR &= (~(0X3 << 20));
    // 设置PE8为低速输出
    GPIOE->OSPEEDR &= (~(0X3 << 16));
    // 设置PE9为低速输出
    GPIOE->OSPEEDR &= (~(0X3 << 18));
    // 设置PB6为低速输出
    GPIOB->OSPEEDR &= (~(0X3 << 12));
    // 设置PF6为低速输出
    GPIOF->OSPEEDR &= (~(0X3 << 12));

    // 设置PE10输出无上拉下拉电阻
    GPIOE->PUPDR &= (~(0X3 << 20));
    // 设置PF10输出无上拉下拉电阻
    GPIOF->PUPDR &= (~(0X3 << 20));
    // 设置PE8输出无上拉下拉电阻
    GPIOE->PUPDR &= (~(0X3 << 16));
    // 设置PE9输出无上拉下拉电阻
    GPIOE->PUPDR &= (~(0X3 << 18));
    // 设置PB6输出无上拉下拉电阻
    GPIOB->PUPDR &= (~(0X3 << 12));
    // 设置PF6输出无上拉下拉电阻
    GPIOF->PUPDR &= (~(0X3 << 12));

    // 三盏灯默认是关闭
    GPIOE->ODR &= (~(0X1 << 10));
    GPIOF->ODR &= (~(0X1 << 10));
    GPIOE->ODR &= (~(0X1 << 8));
    // 风扇默认关闭
    GPIOE->ODR &= (~(0X1 << 9));
    // 蜂鸣器默认关闭
    GPIOB->ODR &= (~(0X1 << 6));
    // 马达默认关闭
    GPIOF->ODR &= (~(0X1 << 6));
}
void buzzer(int flag)
{
    if (flag == 1)
    {
        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(200); // 微秒级的延时
        GPIOB->ODR &= (~(0X1 << 6)); // 蜂鸣器停
        delay(200);

        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(400); // 微秒级的延时
        GPIOB->ODR &= (~(0X1 << 6)); // 蜂鸣器停
        delay(200);

        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(200); // 微秒级的延时
        GPIOB->ODR &= (~(0X1 << 6)); // 蜂鸣器停
        delay(200);

        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(200); // 微秒级的延时
        GPIOB->ODR &= (~(0X1 << 6)); // 蜂鸣器停
        delay(400);

        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(200); // 微秒级的延时
        GPIOB->ODR &= (~(0X1 << 6)); // 蜂鸣器停
        delay(200);

        delay(400);

        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(200); // 微秒级的延时
        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(200); // 微秒级的延时

        GPIOB->ODR &= (~(0X1 << 6)); // 蜂鸣器停
        delay(200);
        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(200); // 微秒级的延时
        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(200); // 微秒级的延时

        delay(200);

        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(200); // 微秒级的延时
        GPIOB->ODR &= (~(0X1 << 6)); // 蜂鸣器停
        delay(200);
        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(200); // 微秒级的延时

        delay(400);

        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(200); // 微秒级的延时
        GPIOB->ODR &= (~(0X1 << 6)); // 蜂鸣器停
        delay(200);

        delay(200); // 微秒级的延时

        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(400); // 微秒级的延时
        GPIOB->ODR &= (~(0X1 << 6)); // 蜂鸣器停
        delay(200);
        GPIOB->ODR |= (0x1 << 6); // 蜂鸣器响
        delay(200); // 微秒级的延时
        GPIOB->ODR &= (~(0X1 << 6)); // 蜂鸣器停
    }
    else if (flag == 0)
    {
        GPIOB->ODR &= (~(0X1 << 6));
    }
}
void LED1_CTRL(int flag)
{
    if (flag == 1) // 开灯
    {
        GPIOE->ODR |= (0X1 << 10);
    }
    else if (flag == 0)
    {
        GPIOE->ODR &= (~(0X1 << 10));
    }
}
void LED2_CTRL(int flag)
{
    if (flag == 1) // 开灯
    {
        GPIOF->ODR |= (0X1 << 10);
    }
    else if (flag == 0)
    {
        GPIOF->ODR &= (~(0X1 << 10));
    }
}
void LED3_CTRL(int flag)
{
    if (flag == 1) // 开灯
    {
        GPIOE->ODR |= (0X1 << 8);
    }
    else if (flag == 0)
    {
        GPIOE->ODR &= (~(0X1 << 8));
    }
}

led.h

#ifndef __LED_H__
#define __LED_H__
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gic.h"
// 毫秒延时
void delay(int ms);
// 微秒延时
void delay_um(int us);
//GPIO初始化
void led_start();
void LED1_CTRL(int flag); // 控制LED1
void LED2_CTRL(int flag); // 控制LED2
void LED3_CTRL(int flag); // 控制LED3
void buzzer(int flag); // 控制蜂鸣器
#endif

main.c

#include "uart4.h"
#include "led.h"
#include "key.h"
int main()
{
    key_config();
    key3_config();
    led_start();
    while(1)
    {
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值