中断案例
利用外部中断检测按键KEY3,当按键按下,翻转LED1显示
1.1 硬件电路设计
1.1.1LED1的硬件电路
1.1.2 KEY的硬件电路
如下图:
- PF10对应的是KEY_3(SW5),我们可以设置PF10的模式为下拉输入,则当按键没有按下的时候是低电平,当按键按下的时候是高电平。
- 由于按键没有设置硬件防抖,则我们需要软件设计防抖。一般延时10-15ms即可实现软件防抖。
1.2 开启时钟
LED设置见之前文章,本文不再赘述;
需要开启GPIOF、AFIO时钟。EXTI和NVIC时钟始终开启,无需手动开启;
/* 1.1 开启 GPIOF 时钟 */
RCC->APB2ENR |= RCC_APB2ENR_IOPFEN; // RCC_APB2ENR_IOPFEN: 10000000
/* 1.2 开启AFIO时钟 */
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // 00000001
- 寄存器
1.3 GPIO模式配置
配置GPIOF10 为输入模式, 另外还需要把ODR寄存器对应的位设为0(0-下拉模式 1-上拉)
// 输入模式- cnf: 10 mode: 00
GPIOF->CRH &= ~GPIO_CRH_MODE10; // 110 000 000 0
GPIOF->CRH |= GPIO_CRH_CNF10_1; // 100 000 000 000
GPIOF->CRH &= ~GPIO_CRH_CNF10_0; // 100 000 000 00
// 0 - 下拉模式
GPIOF->ODR &= ~GPIO_ODR_ODR10; // 100 000 000 00
- 寄存器
1.4 配置AFIO引脚复用
配置 AFIO, 用于引脚复用为外部中断
// PF10
AFIO->EXTICR[2] &= ~AFIO_EXTICR3_EXTI10 // 1111 0000 0000
AFIO->EXTICR[2] |= AFIO_EXTICR3_EXTI10_PF; // 101 0000 0000
- 寄存器
1.5 配置EXTI
配置引脚的上升沿触发中断,同时开启EXTI10 线
/* 4.1 PG0的上升沿触发中断 */
EXTI->RTSR |= EXTI_RTSR_TR10; // 10 000 000 000
/* 4.2 开启 EXTI10 线 */
EXTI->IMR |= EXTI_IMR_MR10; // 10 000 000 000
- 寄存器
1.6 清除中断标志位
清除中断标志. 写1清除中断
/* 1 */
EXTI->PR |= EXTI_PR_PR10; // 10 000 000 000
- 寄存器
1.7 代码
/**
* @description: 初始化按键.
* 1. 给按键对应的io口设置工作模式: 下拉输入
* 2. 配置复用为外部中断
* 3. 配置外部中断控制器 EXTI
* 4. 配置NVIC
*/
void Driver_Key_Init(void)
{
/* 1. 开启时钟 */
/* 1.1 GPIOF*/
RCC->APB2ENR |= RCC_APB2ENR_IOPFEN;
/* 1.2 AFIO*/
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
/* 2. 配置 PF10为下拉输入: MODE=00 CNF=10 ODR=0 */
GPIOF->CRH &= ~GPIO_CRH_MODE10;
GPIOF->CRH |= GPIO_CRH_CNF10_1;
GPIOF->CRH &= ~GPIO_CRH_CNF10_0;
GPIOF->ODR &= ~GPIO_ODR_ODR10; // 告诉硬件:PF10 使用内部下拉电阻
/* 3. 配置AFIO 配置PF10引脚为外部中断 EXTICR3 0101 */
AFIO->EXTICR[2] &= ~AFIO_EXTICR3_EXTI10; // EXTICR[2]: EXTI8 ~ EXTI11
AFIO->EXTICR[2] |= AFIO_EXTICR3_EXTI10_PF;
/* 4. 配置EXTI */
/* 4.1. 配置上升沿触发 RTSR TR10=1*/
EXTI->RTSR |= EXTI_RTSR_TR10;
/* 4.2 开启 LINE10, 配置的中断屏蔽寄存器 */
EXTI->IMR |= EXTI_IMR_MR10;
/* 5. 配置 NVIC */
/* 5.1 配置优先级组 */
NVIC_SetPriorityGrouping(4);
/* 5.2 配置优先级 参数1:中断号*/
NVIC_SetPriority(EXTI15_10_IRQn, 4);
/* 5.3 使能Line10 */
NVIC_EnableIRQ(EXTI15_10_IRQn);
}
/**
* @description: line 15-10的中断服务函数.
* 一旦按键下按键1,则会执行一次这个函数
* @return {*}
*/
void EXTI15_10_IRQHandler(void)
{
/* 务必一定必须要清除中断标志位 */
EXTI->PR |= EXTI_PR_PR10;
Delay_ms(5);
if ((GPIOF->IDR & GPIO_IDR_IDR10) != 0) // 如果 PF10 引脚为高电平
{
// 开关led
Driver_LED_Toggle(LED_1);
}
}
- 配置 NVIC的:
EXTI15_10_IRQn
- void EXTI15_10_IRQHandler()函数
固定名字,对应 EXTI10~EXTI15 的中断向量, 在startup_stm32f10x_hd.s
文件可以找到:
1 游客 2025-09-01 11:26 回复
1
1 游客 2025-09-01 12:01 回复
1
@@JOdm5 游客 2025-09-01 12:02 回复
1
1 游客 2025-09-01 12:04 回复
1
1 游客 2025-09-01 12:05 回复
6WJTlX26