按键中断讲解
蓝桥杯嵌入式开发板有多个外部中断,可以通过按键打开中断,执行中断处理函数。但是在往届比赛中很少使用。可以简单了解。
按键中断的初始化及使用
需要包含misc.c、misc.h、stm32f10x_exti.c和stm32f10x_exti.h文件。
初始化函数为
/**
* @说明 配置相关引脚为EXTI工作模式
* @参数 none
* @返回值 None
*/
void EXTI_Config(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable GPIOA clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//PA0-BUTTON1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
/* Configure EXTI0 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set EXTI0 Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//PA8-BUTTON2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource8);
/* Configure EXTI9_5 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line8;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set EXTI0 Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
按键1(PA0)与中断0结合,按键2(PA8)与中断9结合。
可以参考CT117E嵌入式竞赛板\STM32_MCU\stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\EXTI\EXTI_Config中的main.c文件。源码为
/**
* @brief Configure PA.00 in interrupt mode
* @param None
* @retval None
*/
void EXTI0_Config(void)
{
/* Enable GPIOA clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Configure PA.00 pin as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Enable AFIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/* Connect EXTI0 Line to PA.00 pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
/* Configure EXTI0 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set EXTI0 Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief Configure PB.09 or PG.08 in interrupt mode
* @param None
* @retval None
*/
void EXTI9_5_Config(void)
{
#if defined (STM32F10X_HD_VL) || defined (STM32F10X_HD) || defined (STM32F10X_XL)
/* Enable GPIOG clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);
/* Configure PG.08 pin as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOG, &GPIO_InitStructure);
/* Enable AFIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/* Connect EXTI8 Line to PG.08 pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOG, GPIO_PinSource8);
/* Configure EXTI8 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line8;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set EXTI9_5 Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#else
/* Enable GPIOB clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* Configure PB.09 pin as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Enable AFIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/* Connect EXTI9 Line to PB.09 pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9);
/* Configure EXTI9 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line9;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set EXTI9_5 Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
}
EXTI0的初始化只需将结构体EXTI_InitStructure的元素EXTI_Trigger 的值改为EXTI_Trigger_Falling即可。EXTI9只需前面的初始化,即else以前的。将GPIOG改为GPIOA即可。
EXTI的中断处理函数在stm32f10x_it.c中改写。代码为
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
EXTI_Status = 1;
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
/**
* @brief This function handles EXTI9_5 interrupt request.
* @param None
* @retval None
*/
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line8) != RESET)
{
EXTI_Status = 2;
EXTI_ClearITPendingBit(EXTI_Line8);
}
}
变量EXTI_Status在stm32f10x_it.c中的定义为
extern uint8_t EXTI_Status;
在main.c中的定义为
uint8_t EXTI_Status = 0;
是中断状态标志标量,记录最近哪个中断打开。
中断处理函数可以参考同文件夹下的stm32f10x_it.c文件。源代码为
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
/* Toggle LED1 */
STM_EVAL_LEDToggle(LED1);
/* Clear the EXTI line 0 pending bit */
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
在main.c文件中判断中断状态标志变量即可知道哪个按键按下。
蜂鸣器讲解
在蓝桥杯开发板中设有一个蜂鸣器,但是因为考场上不希望蜂鸣器常响,否则会使其他考生无法正常发挥。所以一般不会考,但需要注意一下。
蜂鸣器的初始化及使用方法
蜂鸣器的电路连接为
蜂鸣器的初始化代码为
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST,ENABLE); //PB4 重映射
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
GPIO_Configuration();
其中因为蜂鸣器的I/O与JTAG或SWD(即代码下载串口)相同,所以需要关闭I/O口代码下载功能。代码GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST,ENABLE);、GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);、GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);都可以关闭I/O代码下载功能。调用其中任何一个即可。
函数GPIO_PinRemapConfig定义在stm32f10x_gpio.c中的第549行,声明在stm32f10x_gpio.h中的第364行。变量GPIO_Remap_SWJ_NoJTRST定义在stm32f10x_gpio.h中的第196行。变量GPIO_Remap_SWJ_Disable定义在stm32f10x_gpio.h中的第198行。变量GPIO_Remap_SWJ_JTAGDisable定义在stm32f10x_gpio.h中的第197行。
函数GPIO_Configuration的代码为
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//Buzzer
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_Init(GPIOB, &GPIO_InitStructure);//更改所有JTAG引脚状态
}
是对GPIOA 、GPIOB所有引脚的设置。
蜂鸣器使用代码为
GPIO_ResetBits(GPIOB,GPIO_Pin_4);
Delay_Ms(200);
GPIO_SetBits(GPIOB,GPIO_Pin_4);
Delay_Ms(200);
通过周期性高低电平的变化使蜂鸣器发生。可以改变占空比,使蜂鸣器发出不同的声调。
蜂鸣器的注意事项。因为在使用蜂鸣器时关闭I/O口下载代码的功能,所以在蜂鸣器代码下载成功后需要再次烧写代码的话,需要按住复位按键,然后点击下载按钮,点击后立即松开复位按键便可成功下载代码。