赞
踩
放在while(1)循环里,系统不停识别按键状态来控制彩灯
#ifndef __KEY_H #define __KEY_H #include "stm32f10x.h" // 引脚定义:检测按键输入的GPIO端口、GPIO引脚号以及GPIO端口时钟封装起来;Key1:PA0;Key2:PC13(可查开发板规格书) #define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA #define KEY1_GPIO_PORT GPIOA #define KEY1_GPIO_PIN GPIO_Pin_0 #define KEY2_GPIO_CLK RCC_APB2Periph_GPIOC #define KEY2_GPIO_PORT GPIOC #define KEY2_GPIO_PIN GPIO_Pin_13 /** 按键按下标置宏 * 按键按下为高电平,设置 KEY_ON=1, KEY_OFF=0 * 若按键按下为低电平,把宏设置成KEY_ON=0 ,KEY_OFF=1 即可 */ #define KEY_ON 1 #define KEY_OFF 0 void Key_GPIO_Config(void);//按键初始化函数 uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin); #endif /* __KEY_H */
/** ****************************************************************************** * @file bsp_key.c * @author fire * @version V1.0 * @date 2013-xx-xx * @brief 按键应用bsp(扫描模式) ****************************************************************************** * @attention * * 实验平台:野火 F103-指南者 STM32 开发板 * 论坛 :http://www.firebbs.cn * 淘宝 :https://fire-stm32.taobao.com * ****************************************************************************** */ #include "./Key/bsp_key.h" /** * @brief 配置按键用到的I/O口 * @param 无 * @retval 无 */ void Key_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; /*开启按键端口的时钟*/ RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE); //选择按键的引脚 GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN; // 设置按键的引脚为浮空输入 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 由于引脚的默认电平受按键电路影响,所以设置成浮空输入。 //使用结构体初始化按键 GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure); //选择按键的引脚 GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN; //设置按键的引脚为浮空输入 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //使用结构体初始化按键 GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure); } /* * 函数名:Key_Scan * 描述 :检测是否有按键按下 * 输入 :GPIOx:x 可以是 A,B,C,D或者 E * GPIO_Pin:待读取的端口位 * 输出 :KEY_OFF(没按下按键)、KEY_ON(按下按键) */ uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin) { /*检测是否有按键按下 */ if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON ) { /*等待按键释放 */ while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON); //一次↓↑输出一次KEY_ON,否则当只有↓没有↑的时候一直在循环不输出 return KEY_ON; } else return KEY_OFF; } /*********************************************END OF FILE**********************/
/** ****************************************************************************** * @file main.c * @author fire * @version V1.0 * @date 2013-xx-xx * @brief 测试led ****************************************************************************** * @attention * * 实验平台:野火 F103-指南者 STM32 开发板 * 论坛 :http://www.firebbs.cn * 淘宝 :https://fire-stm32.taobao.com * ****************************************************************************** */ #include "stm32f10x.h" #include "./Led/bsp_led.h" #include "./Key/bsp_key.h" //#define SOFT_DELAY Delay(0x0FFFFF); //void Delay(__IO u32 nCount); /** * @brief 主函数 * @param 无 * @retval 无 */ int main(void) { /* LED 端口初始化 */ LED_GPIO_Config(); /*初始化按键*/ Key_GPIO_Config(); // while (1) // { // LED1_ON; // 亮 // SOFT_DELAY; // LED1_OFF; // 灭 // LED2_ON; // 亮 // SOFT_DELAY; // LED2_OFF; // 灭 // LED3_ON; // 亮 // SOFT_DELAY; // LED3_OFF; // 灭 // /*轮流显示 红绿蓝黄紫青白 颜色*/ // LED_RED; // SOFT_DELAY; // // LED_GREEN; // SOFT_DELAY; // // LED_BLUE; // SOFT_DELAY; // // LED_YELLOW; // SOFT_DELAY; // // LED_PURPLE; // SOFT_DELAY; // // LED_CYAN; // SOFT_DELAY; // // LED_WHITE; // SOFT_DELAY; // // LED_RGBOFF; // SOFT_DELAY; // } /* 轮询按键状态,若按键按下则反转LED */ while(1) { if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON ) { /*LED1反转*/ LED1_TOGGLE; } if( Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON ) { /*LED2反转*/ LED2_TOGGLE; } } } //void Delay(__IO uint32_t nCount) //简单的延时函数 //{ // for(; nCount != 0; nCount--); //} /*********************************************END OF FILE**********************/
烧进去就OK啦!
参考:https://blog.csdn.net/p467616/article/details/115669632
中断是啥
中断可以这样比喻:你在做一件事情,然后电话打进来,你去做电话里要求你做的是,然后做完了又回来做刚才没做完的事情
NVIC
嵌套向量中断控制器,属于内核外设,管理着包括内核和片上所有外设的中断相关的功能。
EXTI
外部 中断/事件 控制器
EXTI 有20个中断/事件线,每个GPIO都可以被设置为输入线,占用 EXTI0至EXTI15。
中断分组、主优先级、子优先级
一般来说先选定优先级分组,选好之后就不要改了,因为改分组可能会使程序错乱。然后配置主优先级和子优先级。
编号越小,优先级越高:如果同一分组里,主优先级相同,子优先级越低,越先发生。如果是主优先级不同,那么主优先级越低,也越先发生。等一个发生完了,再接下一个发生…当然,如果一个优先级高的先发生了,这是来了个低的,是不会打断这个正在发生的。
利用EXTI中断,按下按键(上升沿或下降沿)会触发中断,从而将灯开关的控制作为中断事件。
#ifndef __EXTI_H #define __EXTI_H #include "stm32f10x.h" //dym1:引脚定义 //配置key1的GPIO引脚 #define KEY1_INT_GPIO_PORT GPIOA #define KEY1_INT_GPIO_CLK (RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO)//除了开GPIO的端口时钟外,我们还打开了AFIO的时钟, 这是因为等下配置EXTI信号源的时候需要用到AFIO的外部中断控制寄存器AFIO_EXTICRx //故:使用 GPIO 之前必须开启 GPIO 端口的时钟;用到 EXTI 必须开启 AFIO 时钟。 #define KEY1_INT_GPIO_PIN GPIO_Pin_0 //配置key1的中断 #define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOA #define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource0 #define KEY1_INT_EXTI_LINE EXTI_Line0 //EXTI中断/事件线选择,可选EXTI0至EXTI19 #define KEY1_INT_EXTI_IRQ EXTI0_IRQn //配置向量控制器NVIC的中断向量 //注意:Line0-4为EXTIX_IRQn,Line5-9都为EXTI9_5_IRQn,Line10-15都为EXTI15_10_IRQn #define KEY1_IRQHandler EXTI0_IRQHandler //配置key2的GPIO引脚 #define KEY2_INT_GPIO_PORT GPIOC #define KEY2_INT_GPIO_CLK (RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO) #define KEY2_INT_GPIO_PIN GPIO_Pin_13 #define KEY2_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOC #define KEY2_INT_EXTI_PINSOURCE GPIO_PinSource13 #define KEY2_INT_EXTI_LINE EXTI_Line13 #define KEY2_INT_EXTI_IRQ EXTI15_10_IRQn #define KEY2_IRQHandler EXTI15_10_IRQHandler //dym3:配置 IO为EXTI中断口,并设置中断优先级 void EXTI_Key_Config(void); #endif /* __EXTI_H */
/** ****************************************************************************** * @file bsp_exti.c * @author fire * @version V1.0 * @date 2013-xx-xx * @brief I/O线中断应用bsp ****************************************************************************** * @attention * * 实验平台:野火 F103-指南者 STM32 开发板 * 论坛 :http://www.firebbs.cn * 淘宝 :https://fire-stm32.taobao.com * ****************************************************************************** */ #include "bsp_exti.h" /** * @brief dym2:配置嵌套向量中断控制器NVIC * @param 无 * @retval 无 */ static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* 配置NVIC为优先级组1 */ /* 提示 NVIC_PriorityGroupConfig() 在整个工程只需要调用一次来配置优先级分组!!!*/ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); /* 配置中断源:按键1 */ NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ; /* 配置主优先级 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 配置子优先级 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* 使能中断通道 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* 配置中断源:按键2,其他使用上面相关配置 */ NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ; NVIC_Init(&NVIC_InitStructure); } /** * @brief dym3:配置 IO为EXTI中断口,并设置中断优先级 * @param 无 * @retval 无 */ void EXTI_Key_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; /*开启按键GPIO口的时钟*/ RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE); RCC_APB2PeriphClockCmd(KEY2_INT_GPIO_CLK,ENABLE); /* 配置 NVIC 中断*/ NVIC_Configuration(); /*--------------------------KEY1配置-----------------------------*/ /* 选择按键用到的GPIO */ GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN; /* 配置为浮空输入 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure); /* 选择EXTI的信号源 */ GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE); EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE; /* EXTI为中断模式 */ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; /* 上升沿中断 */ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; /* 使能中断 */ EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); /*--------------------------KEY2配置-----------------------------*/ /* 选择按键用到的GPIO */ GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN; /* 配置为浮空输入 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure); /* 选择EXTI的信号源 */ GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE); EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE; /* EXTI为中断模式 */ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; /* 下降沿中断 */ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; /* 使能中断 */ EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); } /*********************************************END OF FILE**********************/
/** ****************************************************************************** * @file Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c * @author MCD Application Team * @version V3.5.0 * @date 08-April-2011 * @brief Main Interrupt Service Routines. * This file provides template for all exceptions handler and * peripherals interrupt service routine. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2> ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_it.h" #include "./Led/bsp_led.h" #include "./Key/bsp_exti.h" /** @addtogroup STM32F10x_StdPeriph_Template * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /******************************************************************************/ /* Cortex-M3 Processor Exceptions Handlers */ /******************************************************************************/ /** * @brief This function handles NMI exception. * @param None * @retval None */ void NMI_Handler(void) { } /** * @brief This function handles Hard Fault exception. * @param None * @retval None */ void HardFault_Handler(void) { /* Go to infinite loop when Hard Fault exception occurs */ while (1) { } } /** * @brief This function handles Memory Manage exception. * @param None * @retval None */ void MemManage_Handler(void) { /* Go to infinite loop when Memory Manage exception occurs */ while (1) { } } /** * @brief This function handles Bus Fault exception. * @param None * @retval None */ void BusFault_Handler(void) { /* Go to infinite loop when Bus Fault exception occurs */ while (1) { } } /** * @brief This function handles Usage Fault exception. * @param None * @retval None */ void UsageFault_Handler(void) { /* Go to infinite loop when Usage Fault exception occurs */ while (1) { } } /** * @brief This function handles SVCall exception. * @param None * @retval None */ void SVC_Handler(void) { } /** * @brief This function handles Debug Monitor exception. * @param None * @retval None */ void DebugMon_Handler(void) { } /** * @brief This function handles PendSVC exception. * @param None * @retval None */ void PendSV_Handler(void) { } /** * @brief This function handles SysTick Handler. * @param None * @retval None */ void SysTick_Handler(void) { } //dym4:配置中断函数!!!!! void KEY1_IRQHandler(void) { //确保是否产生了EXTI Line中断 if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) { // LED1 取反 LED1_TOGGLE; //清除中断标志位 EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE); } } void KEY2_IRQHandler(void) { //确保是否产生了EXTI Line中断 if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) { // LED2 取反 LED2_TOGGLE; //清除中断标志位 EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE); } } /******************************************************************************/ /* STM32F10x Peripherals Interrupt Handlers */ /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ /* available peripheral interrupt handler's name please refer to the startup */ /* file (startup_stm32f10x_xx.s). */ /******************************************************************************/ /** * @brief This function handles PPP interrupt request. * @param None * @retval None */ /*void PPP_IRQHandler(void) { }*/ /** * @} */ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
/** ****************************************************************************** * @file main.c * @author fire * @version V1.0 * @date 2013-xx-xx * @brief 按键测试(中断模式/EXTI模式) ****************************************************************************** * @attention * * 实验平台:野火 F103-指南者 STM32 开发板 * 论坛 :http://www.firebbs.cn * 淘宝 :https://fire-stm32.taobao.com * ****************************************************************************** */ #include "stm32f10x.h" #include "./Led/bsp_led.h" #include "./Key/bsp_key.h" #include "./Key/bsp_exti.h" /** * @brief 主函数 * @param 无 * @retval 无 */ int main(void) { /* LED 端口初始化 */ LED_GPIO_Config(); /* 初始化EXTI中断,按下按键会触发中断, * 触发中断会进入stm32f4xx_it.c文件中的函数 * KEY1_IRQHandler和KEY2_IRQHandler,处理中断,反转LED灯。 */ EXTI_Key_Config(); /* 等待中断,由于使用中断方式,CPU不用轮询按键 */ while(1) { } } /*********************************************END OF FILE**********************/
烧进去就OK啦!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。