ARM 按钮中断控制灯 2023.12.12

本文详细描述了在STM32MP1xx平台上的GPIOF引脚配置中断,使用EXTI和GIC实现中断触发、优先级设置以及与LED灯控制的关联,展示了关键中断99、97和98的配置过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

include

#ifndef __KET_IT_H__
#define __KEY_IT_H__
 
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include  "stm32mp1xx_gic.h"
#include  "stm32mp1xx_exti.h"
 
 
void  key1_it_config();
void  key2_it_config();
void  key3_it_config();
 
 
 
#endif

test.c

#include "key_it.h"
 
//key1   PF9        99中断号      中断事件9
//key2  PF7         97中断号     中断事件7
//key3  PF8         98中断号       中断事件8
 
void  key1_it_config()
{
    //设置GPIOF时钟
    RCC->MP_AHB4ENSETR  |= (0x1<<5);
    //输入
    GPIOF->MODER &= (~(0x3<<18));
    //设置PF9产生EXIT9事件
    EXTI->EXTICR3 &= (~(0xff<<8));
    EXTI->EXTICR3 |= (0x05<<8);
    //设置下降沿检测
    EXTI->FTSR1  |= (0x1<<9);
    //设置中断不屏蔽  可以被转到GIC
    EXTI->C1IMR1 |= (0x1<<9);
    //将PF9中断保存在0组  GIC接受  使能
     GICD->ISENABLER[3] |= (0x1<<3);
     //设置中断优先级
     GICD->IPRIORITYR[24] &= (0x1f<<27);
     GICD->IPRIORITYR[24] |= (0x0<<27);
     //设置99号中断可以被CPU0处
     GICD->ITARGETSR[24] &= (~(0x3<<24));
     GICD->ITARGETSR[24] |= (0x1<<24);
     //将99号中断转发GICC层
     GICD->CTRL |=0x1;
     //设置中断优先级掩码
     GICC->PMR |=(0x1f<<3);
     //允许中断发送cpu
     GICC->CTRL |= 0x1;
 
}
 
//key2  PF7         97中断号     中断事件7
void  key2_it_config()
{
    //输入
    GPIOF->MODER &= (~(0x3<<14));
    //设置PF7产生EXIT9事件
    EXTI->EXTICR2 &= (~(0xff<<24));
    EXTI->EXTICR2 |= (0x05<<24);
    //设置下降沿检测
    EXTI->FTSR1  |= (0x1<<7);
    //设置中断不屏蔽  可以被转到GIC
    EXTI->C1IMR1 |= (0x1<<7);
    //将PF9中断保存在0组  GIC接受  使能
     GICD->ISENABLER[3] |= (0x1<<1);
     //设置中断优先级
     GICD->IPRIORITYR[24] &= (0x1f<<11);
     GICD->IPRIORITYR[24] |= (0x0<<11);
     //设置99号中断可以被CPU0处
     GICD->ITARGETSR[24] &= (~(0x3<<8));
     GICD->ITARGETSR[24] |= (0x1<<8);
     //将99号中断转发GICC层
     GICD->CTRL |=0x1;
     //设置中断优先级掩码
     GICC->PMR |=(0x1f<<3);
     //允许中断发送cpu
     GICC->CTRL |= 0x1;
 
}
//key3  PF8         98中断号       中断事件8
void  key3_it_config()
{
     //输入
    GPIOF->MODER &= (~(0x3<<16));
    //设置PF7产生EXIT9事件
    EXTI->EXTICR3 &= (~0xff);
    EXTI->EXTICR3 |= 0x05;
    //设置下降沿检测
    EXTI->FTSR1  |= (0x1<<8);
    //设置中断不屏蔽  可以被转到GIC
    EXTI->C1IMR1 |= (0x1<<8);
    //将PF9中断保存在0组  GIC接受  使能
     GICD->ISENABLER[3] |= (0x1<<2);
     //设置中断优先级
     GICD->IPRIORITYR[24] &= (0x1f<<19);
     GICD->IPRIORITYR[24] |= (0x0<<19);
     //设置99号中断可以被CPU0处
     GICD->ITARGETSR[24] &= (~(0x3<<16));
     GICD->ITARGETSR[24] |= (0x1<<16);
     //将99号中断转发GICC层
     GICD->CTRL |=0x1;
     //设置中断优先级掩码
     GICC->PMR |=(0x1f<<3);
     //允许中断发送cpu
     GICC->CTRL |= 0x1;
}

do_lrq.c 

#include "key_it.h"
#include "myled.h"
 
extern void printf(const char *fmt, ...);
unsigned int i = 0;
 
int flag1 = 0, flag2 = 0, flag3 = 0;
 
void do_irq(void)
{
    int i;
    i = GICC->IAR & 0x3ff;
    switch (i)
    {
    case 99:
    {
        if (flag1 == 0)
        {
            led1_off();
            flag1=1;
        }
        else 
        {
            led1_on();
            flag1=0;
        }
        printf("key_1\n");
 
        EXTI->FPR1 |= (0X1 << 9);
        GICD->ICPENDR[3] = (0X1 << 3);
        break;
    }
 
    case 97:
    {
            if (flag2 == 0)
        {
            led2_off();
            flag2=1;
        }
        else 
        {
            led2_on();
            flag2=0;
        }
        printf("key_2\n");
        EXTI->FPR1 |= (0X1 << 9);
        GICD->ICPENDR[3] = (0X1 << 1);
        break;
    }
 
    case 98:
    {
           if (flag3 == 0)
        {
            led3_off();
            flag3=1;
        }
        else 
        {
            led3_on();
            flag3=0;
        }
        printf("key_3\n");
        EXTI->FPR1 |= (0X1 << 9);
        GICD->ICPENDR[3] = (0X1 << 2);
        break;
    }
    }
    GICC->EOIR = i;
}

main.c 

#include "myled.h"
 
#include "key_it.h"
 
 
 
int main()
 
{
  key1_it_config();
 
  key2_it_config();
 
  key3_it_config();
 
  all_led_init();
 
  led1_on();
 
  led2_on();
 
  led3_on();
 
  while (1)
 
  {
 
    
 
  }
 
  return 0;
 
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值