控制按键key1、2、3,实现,按下按钮时,串口工具内输出对应按键名
本开发板为:stm32mp157
查找芯片手册得:key1、2、3的引脚分别对应PF9、PF7、PF8。
以Key1为例:
PF9对应GPIOF寄存器,用RCC寄存器使能,再设置为输入模式。
以下归属于函数:void pf9_exti_init();
//使能GPIOF
RCC->MP_AHB4ENSETR = (0x1 << 5);
/*****GPIO章节初始化*****/
//设置PF9引脚为输入模式
//GPIOF_MODER[19:18] = 0b00
GPIOF->MODER &= (~(0x3 << 18));
设置PF9与EXTI9连接,这样才能把信号传递进去
/*******EXTI章节初始化********/
//1.设置PF9引脚和EXTI9控制器进行链接
//EXIT_EXTICR3[15:8] = 0x05
EXTI->EXTICR3 &= (~(0xff << 8)); //清零
EXTI->EXTICR3 |= (0x05 << 8); //置1
因为我们采取的是按下按钮响应,所以要监控下降沿
//2.设置PF9引脚检测方式为下降沿
//EXTI_FTSR1[9] = 0x01
EXTI->FTSR1 |= (0x1 << 9);
//3.设置PF9引脚中断不屏蔽
//EXTI_IMR1[9] = 0x01
EXTI->C1IMR1 |= (0x01 << 9);
设置GIC部分,以下归属于函数:void pf9_gicd_init() ;
初始化GICD
先设置全局中断使能寄存器
GICD->CTRL |= (0X01 << 0);
设置GICD层中断使能寄存器
//EXTI9-->99号-->GICD_ISENABLER[3][3] = 1
GICD->ISENABLER[3] |= (0x1 << 3);
设置GICD层中断优先级寄存器
//99号中断-->GICD_IPRIORITYR24[31:27] = 10 //数字随意
GICD->IPRIORITYR[24] &= (~(0x1F << 27)); //清零
GICD->IPRIORITYR[24] |= (0x1 << 27);
设置GICD层中断目标分配器
//99号中断 --> 99/4 = 24....3 --> GICD_ITARGETSR24[25:24] = 0bx1(x代表0、1任意值)
GICD->ITARGETSR[24] &= (~(0x3 << 24));
GICD->ITARGETSR[24] |= (0x1 << 24);
设置GICC层,以下归属于函数:void pf9_gicc_init();
//设置GICC层全局中断使能寄存器
GICC->CTRL |= (0x1 << 0);
//设置GICC层中断优先级寄存器
GICC->PMR &= (~(0x1F << 3));
GICC->PMR |= (0xF << 3); //优先级设置为15
这样初始化要写三个函数有点麻烦,于是把三个函数集成到另一个函数中
//包裹pf9
void PF9_init()
{
pf9_exti_init();
pf9_gicd_init();
pf9_gicc_init();
}
在irq.c文件中,获取中断信号
//获取中断信号
unsigned int num = 0;
num = GICC->IAR;
调用switch选择结构
case 99:
delay_ms(500); //防按键抖动
printf("key1######\n");
//清除EXTI中断挂起标志位
EXTI->FPR1 |= (0x1 << 9);
//清除GICD层中断挂起标志位
//key1-->PF9-->EXTI9-->事件9-->中断号99
//99 / 32 = 3...3
GICD->ICPENDR[3] |= (0x1 << 3);
break;
在选择结构外,清除中断信号
//清除中断信号
GICC->EOIR &= (~(0x3FF << 0));
GICC->EOIR |= num;
附上完整代码,
尤其要注意,由于该板的问题,key2和key1、3部分寄存器不在同一个。比如 EXIT_EXTICRx 寄存器,key1、3是EXIT_EXTICR3,而key2是EXIT_EXTICR2,不要写错了。
头文件
#ifndef __KEY_H__
#define __KEY_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gic.h"
//初始化
/******KEY1----->PF9******/
//初始化EXTI层
void pf9_exti_init();
//初始化GICD层
void pf9_gicd_init();
//初始化GICC层
void pf9_gicc_init();
//包裹pf9
void PF9_init();
/******KEY2----->PF7******/
//初始化EXTI层
void pf7_exti_init();
//初始化GICD层
void pf7_gicd_init();
//初始化GICC层
void pf7_gicc_init();
//包裹pf9
void PF7_init();
/******KEY3----->PF9******/
//初始化EXTI层
void pf8_exti_init();
//初始化GICD层
void pf8_gicd_init();
//初始化GICC层
void pf8_gicc_init();
//包裹pf8
void PF8_init();
#endif
功能函数:
#include "key.h"
//初始化EXTI层
void pf9_exti_init()
{
/***********RCC初始化**************/
//使能GPIOF
RCC->MP_AHB4ENSETR = (0x1 << 5);
/*****GPIO章节初始化*****/
//设置PF9引脚为输入模式
//GPIOF_MODER[19:18] = 0b00
GPIOF->MODER &= (~(0x3 << 18));
/*******EXTI章节初始化********/
//1.设置PF9引脚和EXTI9控制器进行链接
//EXIT_EXTICR3[15:8] = 0x05
EXTI->EXTICR3 &= (~(0xff << 8)); //清零
EXTI->EXTICR3 |= (0x05 << 8); //置1
//2.设置PF9引脚检测方式为下降沿
//EXTI_FTSR1[9] = 0x01
EXTI->FTSR1 |= (0x1 << 9);
//3.设置PF9引脚中断不屏蔽
//EXTI_IMR1[9] = 0x01
EXTI->C1IMR1 |= (0x01 << 9);
}
//初始化GICD层
void pf9_gicd_init()
{
//设置GICD层全局中断使能寄存器
GICD->CTRL |= (0X01 << 0);
//设置GICD层中断使能寄存器
//EXTI9-->99号-->GICD_ISENABLER[3][3] = 1
GICD->ISENABLER[3] |= (0x1 << 3);
//设置GICD层中断优先级寄存器
//99号中断-->GICD_IPRIORITYR24[31:27] = 10 //数字随意
GICD->IPRIORITYR[24] &= (~(0x1F << 27)); //清零
GICD->IPRIORITYR[24] |= (0x1 << 27);
//设置GICD层中断目标分配器
//99号中断 --> 99/4 = 24....3 --> GICD_ITARGETSR24[25:24] = 0bx1(x代表0、1任意值)
GICD->ITARGETSR[24] &= (~(0x3 << 24));
GICD->ITARGETSR[24] |= (0x1 << 24);
}
//初始化GICC
void pf9_gicc_init()
{
//设置GICC层全局中断使能寄存器
GICC->CTRL |= (0x1 << 0);
//设置GICC层中断优先级寄存器
GICC->PMR &= (~(0x1F << 3));
GICC->PMR |= (0xF << 3); //优先级设置为15
}
//初始化EXTI层
void pf7_exti_init()
{
/***********RCC初始化**************/
//使能GPIOF
//RCC->MP_AHB4ENSETR = (0x1 << 5);
/*****GPIO章节初始化*****/
//设置PF7引脚为输入模式
//GPIOF_MODER[15:14] = 0b00
GPIOF->MODER &= (~(0x3 << 14));
/*******EXTI章节初始化********/
//1.设置PF7引脚和EXTI控制器进行链接
//EXIT_EXTICR2[31:24] = 0x05
EXTI->EXTICR2 &= (~(0xff << 24)); //清零
EXTI->EXTICR2 |= (0x05 << 24); //置1
//2.设置PF7引脚检测方式为下降沿
//EXTI_FTSR1[7] = 0x01
EXTI->FTSR1 |= (0x1 << 7);
//3.设置PF7引脚中断不屏蔽
//EXTI_IMR1[7] = 0x01
EXTI->C1IMR1 |= (0x01 << 7);
}
//初始化GICD层
void pf7_gicd_init()
{
//设置GICD层全局中断使能寄存器
//GICD->CTRL |= (0X01 << 0);
//设置GICD层中断使能寄存器
//EXTI7-->97号-->GICD_ISENABLER[3][1] = 1
GICD->ISENABLER[3] |= (0x1 << 1);
//设置GICD层中断优先级寄存器
//99号中断-->GICD_IPRIORITYR24[31:27] = 2 //数字随意
GICD->IPRIORITYR[24] &= (~(0x1F << 11)); //清零
GICD->IPRIORITYR[24] |= (0x2 << 11);
//设置GICD层中断目标分配器
//99号中断 --> 97/4 = 24....1 --> GICD_ITARGETSR24[9:8] = 0bx1(x代表0、1任意值)
GICD->ITARGETSR[24] &= (~(0x3 << 8));
GICD->ITARGETSR[24] |= (0x1 << 8);
}
//初始化GICC
void pf7_gicc_init()
{
//设置GICC层全局中断使能寄存器
//GICC->CTRL |= (0x1 << 0);
//设置GICC层中断优先级寄存器
GICC->PMR &= (~(0x1F << 3));
GICC->PMR |= (0x10 << 3); //优先级设置为15
}
//初始化EXTI层
void pf8_exti_init()
{
/***********RCC初始化**************/
//使能GPIOF
//RCC->MP_AHB4ENSETR = (0x1 << 5);
/*****GPIO章节初始化*****/
//设置PF8引脚为输入模式
//GPIOF_MODER[17:16] = 0b00
GPIOF->MODER &= (~(0x3 << 16));
/*******EXTI章节初始化********/
//1.设置PF8引脚和EXTI8控制器进行链接
//EXIT_EXTICR3[7:0] = 0x05
EXTI->EXTICR3 &= (~(0xff << 0)); //清零
EXTI->EXTICR3 |= (0x05 << 0); //置1
//2.设置PF8引脚检测方式为下降沿
//EXTI_FTSR1[8] = 0x01
EXTI->FTSR1 |= (0x1 << 8);
//3.设置PF9引脚中断不屏蔽
//EXTI_IMR1[8] = 0x01
EXTI->C1IMR1 |= (0x01 << 8);
}
//初始化GICD层
void pf8_gicd_init()
{
//设置GICD层全局中断使能寄存器
//GICD->CTRL |= (0X01 << 0);
//设置GICD层中断使能寄存器
//EXTI8-->98号-->GICD_ISENABLER[3][2] = 1
GICD->ISENABLER[3] |= (0x1 << 2);
//设置GICD层中断优先级寄存器
//98号中断-->GICD_IPRIORITYR24[23:19] = 3 //数字随意
GICD->IPRIORITYR[24] &= (~(0x1F << 27)); //清零
GICD->IPRIORITYR[24] |= (0x3 << 27);
//设置GICD层中断目标分配器
//98号中断 --> 98/4 = 24....2 --> GICD_ITARGETSR24[17:16] = 0bx1(x代表0、1任意值)
GICD->ITARGETSR[24] &= (~(0x3 << 16));
GICD->ITARGETSR[24] |= (0x1 << 16);
}
//初始化GICC
void pf8_gicc_init()
{
//设置GICC层全局中断使能寄存器
//GICC->CTRL |= (0x1 << 0);
//设置GICC层中断优先级寄存器
GICC->PMR &= (~(0x1F << 3));
GICC->PMR |= (0x11 << 3); //优先级设置为17
}
//包裹pf9
void PF7_init()
{
pf7_exti_init();
pf7_gicd_init();
pf7_gicc_init();
}
//包裹pf9
void PF8_init()
{
pf8_exti_init();
pf8_gicd_init();
pf8_gicc_init();
}
//包裹pf9
void PF9_init()
{
pf9_exti_init();
pf9_gicd_init();
pf9_gicc_init();
}
irq.c
#include "key.h"
extern void delay_ms(int ms);
extern void printf(const char *fmt, ...);
//unsigned int i = 0;
void do_irq(void)
{
unsigned int num = 0;
//获取中断信号
num = GICC->IAR;
switch(num)
{
case 97:
delay_ms(500); //防按键抖动
printf("key2######\n");
//清除EXTI中断挂起标志位
EXTI->FPR1 |= (0x1 << 7);
//清除GICD层中断挂起标志位
//key1-->PF9-->EXTI9-->事件9-->中断号99
//97 / 32 = 3...1
GICD->ICPENDR[3] |= (0x1 << 1);
break;
case 98:
delay_ms(500); //防按键抖动
printf("key3######\n");
//清除EXTI中断挂起标志位
EXTI->FPR1 |= (0x1 << 8);
//清除GICD层中断挂起标志位
//key1-->PF9-->EXTI9-->事件9-->中断号99
//98 / 32 = 3...2
GICD->ICPENDR[3] |= (0x1 << 2);
break;
case 99:
delay_ms(500); //防按键抖动
printf("key1######\n");
//清除EXTI中断挂起标志位
EXTI->FPR1 |= (0x1 << 9);
//清除GICD层中断挂起标志位
//key1-->PF9-->EXTI9-->事件9-->中断号99
//99 / 32 = 3...3
GICD->ICPENDR[3] |= (0x1 << 3);
break;
}
//清除中断信号
GICC->EOIR &= (~(0x3FF << 0));
GICC->EOIR |= num;
}