1 概述
1.1 资源概述
开发板:ST官方NUCLEO-F103RB开发板
CUBEMX版本:1.3.0
MDK版本:5.23
主控芯片型号:STM32F103RBT6
1.2 引脚资源分配
[tr]序号引脚资源备注[/tr]
1 | PA13 | SWDIO | SWD输入输出信号 |
2 | PA14 | SWDCLK | SWD时钟信号 |
3 | PC13 | BUTTON | 用户按键配置为中断 |
4 | PA5 | LED2 | 指示灯 |
1.3 中断概述
外部中断/事件控制器框图
优先级分组可以设置为5种方式。分别是1个抢占优先级/16个子优先级到16个抢占优先级/1个子优先级。
1.4 实现功能
实现功能:
1、上电初始化后,LED2灯亮。
2、若按键被按下,触发外部中断,则将LED2灯状态翻转。
2 软件开发,使用中断的方式
2.1 CUBEMX配置
Button部分原理图如下,PC13为低输入有效。电路中与按键并联的100nF是按键消抖用,使用正点原子的开发板没有此电容,会出现按一次,LED灯亮灭各一次的现象,说明抖动了,执行了两次中断。
PC13配置为中断模式,下降沿触发,上拉。
中断分组设置,采用默认设置,抢占优先级0,子优先级0。
中断优先级说明,线10到线15使用同一个中断优先级,PC13对应的是线13。
[tr]位置优先级优先级类型名称说明地址[/tr]
40 | 47 | 可设置 | EXTI15_10 | EXTI线[15:10]中断 | 0x0000_00E0 |
2.2 程序代码
生成程序代码,系统自动对LED2和Button进行了初始化,并对Button对应的中断进行了分组和使能。
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = Button_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(Button_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = LED2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}
在main函数中增加初始化LED2,让上电初始化时亮灯。
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);//上电初始化将LED2灯点亮
1
增加中断回调函数,当检测到中断时执行中断回调函数,翻转LED2灯的状态。
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)//中断回调函数,当有中断发生时,将LED2灯进行翻转
{
HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
}
while(1)函数保留为空,编程到此完成。
实现过程分析。
1、在stm32f1xx_it.c中定义了EXIT15-10中断服务函数。
void EXTI15_10_IRQHandler(void)//中断处理函数,当检测到中断,即Button被按下时,检测到下降沿即为有效
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
}
2、在stm32f1xx_hal_gpio.c中定义了HAL_GPIO_EXTI_IRQHandler。
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* 检测到了中断 */
if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);//清除中断状态
HAL_GPIO_EXTI_Callback(GPIO_Pin);//调用回调函数
}
}
3、在main函数中定义了回调函数HAL_GPIO_EXTI_Callback。
4、当Button被按下时,1到3会依次执行。
3 使用两次检测电平的方式
程序源代码如下,使用了gg=G VIm的自动调整格式功能,这个工具是真香,实现的功能是循环,当第一次按时,1S闪烁一次,再按一次时,500mS闪烁2次,按第三下时250mS闪烁4次。在写程序过程中同样用到了ALT +/的补全提示功能。
while (1)
{
/* USER CODE END WHILE */
if(HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin)==0)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin)==0)
{
key=1;
}
else
key=0;
}
while(key==1)
{
switch(time)
{
case 0:
for(int i=0;i<2;i++)
{
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);//翻转LED灯
HAL_Delay(1000);//延迟1s
key=0;
}
break;
case 1:
for(int i=0;i<4;i++)
{
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);//翻转LED灯
HAL_Delay(500);//延迟1s
key=0;
}
break;
case 2:
for(int i=0;i<8;i++)
{
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);//翻转LED灯
HAL_Delay(250);//延迟1s
key=0;
}
break;
default:break;
}
time++;
if(time==3)
time=0;
}
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
4 实现结果
上电后LED灯常亮,当有按键按下时,LED翻转状态。黑色按键是复位键Reset,蓝色按键是用户按键(PC13 Button)。
Tips:在使用中断时请务必配置好gpio的上下拉,若为下降沿触发,则配置为上拉。若为上升沿触发,则配置为下拉。否则有可能导致中断不可用。
1 概述
1.1 资源概述
开发板:ST官方NUCLEO-F103RB开发板
CUBEMX版本:1.3.0
MDK版本:5.23
主控芯片型号:STM32F103RBT6
1.2 引脚资源分配
[tr]序号引脚资源备注[/tr]
1 | PA13 | SWDIO | SWD输入输出信号 |
2 | PA14 | SWDCLK | SWD时钟信号 |
3 | PC13 | BUTTON | 用户按键配置为中断 |
4 | PA5 | LED2 | 指示灯 |
1.3 中断概述
外部中断/事件控制器框图
优先级分组可以设置为5种方式。分别是1个抢占优先级/16个子优先级到16个抢占优先级/1个子优先级。
1.4 实现功能
实现功能:
1、上电初始化后,LED2灯亮。
2、若按键被按下,触发外部中断,则将LED2灯状态翻转。
2 软件开发,使用中断的方式
2.1 CUBEMX配置
Button部分原理图如下,PC13为低输入有效。电路中与按键并联的100nF是按键消抖用,使用正点原子的开发板没有此电容,会出现按一次,LED灯亮灭各一次的现象,说明抖动了,执行了两次中断。
PC13配置为中断模式,下降沿触发,上拉。
中断分组设置,采用默认设置,抢占优先级0,子优先级0。
中断优先级说明,线10到线15使用同一个中断优先级,PC13对应的是线13。
[tr]位置优先级优先级类型名称说明地址[/tr]
40 | 47 | 可设置 | EXTI15_10 | EXTI线[15:10]中断 | 0x0000_00E0 |
2.2 程序代码
生成程序代码,系统自动对LED2和Button进行了初始化,并对Button对应的中断进行了分组和使能。
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = Button_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(Button_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = LED2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}
在main函数中增加初始化LED2,让上电初始化时亮灯。
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);//上电初始化将LED2灯点亮
1
增加中断回调函数,当检测到中断时执行中断回调函数,翻转LED2灯的状态。
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)//中断回调函数,当有中断发生时,将LED2灯进行翻转
{
HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
}
while(1)函数保留为空,编程到此完成。
实现过程分析。
1、在stm32f1xx_it.c中定义了EXIT15-10中断服务函数。
void EXTI15_10_IRQHandler(void)//中断处理函数,当检测到中断,即Button被按下时,检测到下降沿即为有效
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
}
2、在stm32f1xx_hal_gpio.c中定义了HAL_GPIO_EXTI_IRQHandler。
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* 检测到了中断 */
if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);//清除中断状态
HAL_GPIO_EXTI_Callback(GPIO_Pin);//调用回调函数
}
}
3、在main函数中定义了回调函数HAL_GPIO_EXTI_Callback。
4、当Button被按下时,1到3会依次执行。
3 使用两次检测电平的方式
程序源代码如下,使用了gg=G VIm的自动调整格式功能,这个工具是真香,实现的功能是循环,当第一次按时,1S闪烁一次,再按一次时,500mS闪烁2次,按第三下时250mS闪烁4次。在写程序过程中同样用到了ALT +/的补全提示功能。
while (1)
{
/* USER CODE END WHILE */
if(HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin)==0)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin)==0)
{
key=1;
}
else
key=0;
}
while(key==1)
{
switch(time)
{
case 0:
for(int i=0;i<2;i++)
{
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);//翻转LED灯
HAL_Delay(1000);//延迟1s
key=0;
}
break;
case 1:
for(int i=0;i<4;i++)
{
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);//翻转LED灯
HAL_Delay(500);//延迟1s
key=0;
}
break;
case 2:
for(int i=0;i<8;i++)
{
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);//翻转LED灯
HAL_Delay(250);//延迟1s
key=0;
}
break;
default:break;
}
time++;
if(time==3)
time=0;
}
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
4 实现结果
上电后LED灯常亮,当有按键按下时,LED翻转状态。黑色按键是复位键Reset,蓝色按键是用户按键(PC13 Button)。
Tips:在使用中断时请务必配置好gpio的上下拉,若为下降沿触发,则配置为上拉。若为上升沿触发,则配置为下拉。否则有可能导致中断不可用。
举报