[STM32F103]基于标准库的单按键控制LED闪烁频率 |
您所在的位置:网站首页 › 灯的闪烁频率是多少,人能分辨 › [STM32F103]基于标准库的单按键控制LED闪烁频率 |
用到:Keil5 mdk + stm32F103C8T6最小系统板 + 独立按键一个 + led灯一个 要使用单按键切换不同的LED闪烁频率,需要用到外部中断,才能实现按键按下一次切换LED闪烁频率。 按键对应的GPIO口模式设置成输入上拉模式,即默认高电平,按下时变成低电平,出现下降沿,选择下降沿作为外部中断的触发条件 主函数 #include "stm32f10x.h" // Device header #include "Delay.h" #include "LED.h" #include "KEY.h" extern uint8_t a; uint8_t Num; int main(void) { LED_Init(); KEY_Init(); while (1) { Num = Key_GetNum(); //接收独立按键返回的值 LED_Mode(a); //LED灯闪烁频率,由a决定 } }
首先配置LED LED.C #include "stm32f10x.h" // Device header #include "Delay.h" uint8_t a = 0; void LED_Init(void) //LED灯初始化 { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_SetBits(GPIOA,GPIO_Pin_1); } void LED_Set(int i,int j) //封装LED亮灭 { if( i == 1 && j == 0) GPIO_ResetBits(GPIOA,GPIO_Pin_1); //点亮LED if (i == 1 && j == 1) GPIO_SetBits(GPIOA,GPIO_Pin_1); //关闭LED } void LED_Mode(uint8_t a) //LED闪烁模式 { if(a == 0) { LED_Set(1,1); } if(a == 1) { LED_Set(1,0); Delay_ms(500); LED_Set(1,1); Delay_ms(500); } if(a == 2) { LED_Set(1,0); Delay_ms(200); LED_Set(1,1); Delay_ms(200); } }
LED.H #ifndef __LED_H #define __LED_H void LED_Init(void); void LED_Set(int i,int j); void LED_Mode(uint8_t a); #endif接下来配置独立按键 Key.c #include "stm32f10x.h" // Device header #include "Delay.h" #include "LED.h" extern int8_t a; extern uint8_t Num; uint8_t KeyNum; void KEY_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //输入模式一般都是上拉输入模式为主 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource11); //中断线配置,搭个线 EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line = EXTI_Line11; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //设置下降沿触发,按键按下,按键 // 处GPIO端口转低电平 EXTI_Init(&EXTI_InitStructure); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //4*4 中断优先级分组 NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStructure); } //这样下来整个外部中断的通道就搭建好了,重点就在于如何实现点按切换频率了 //按键按下瞬间进入中断,这样就可以开始判断了 void EXTI15_10_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line11) == SET) { if(Num == 1) { if(a == 0) a = 1; else if(a == 1) a = 2; else if(a == 2) a = 0; } Num = 0; EXTI_ClearITPendingBit(EXTI_Line11); } } uint8_t Key_GetNum(void) //改变LED闪烁频率的关键 { if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0) { Delay_ms(20); while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0); //经典的按键消抖 Delay_ms(20); KeyNum = 1; } return KeyNum; } void EXTI15_10_IRQHandler(void) //按键中断程序 { if(EXTI_GetITStatus(EXTI_Line11) == SET) //当中断标志位被置位 { if(Num == 1) { if(a == 0) //a控制LED闪烁频率,分别是灭,慢闪,快闪 a = 1; else if(a == 1) a = 2; else if(a == 2) a = 0; } Num = 0; //每次中断后必须要归零,否则LED灯会出现乱跳 EXTI_ClearITPendingBit(EXTI_Line11); } }Key.h #ifndef __KEY_H #define __KEY_H void KEY_Init(void); uint8_t Key_GetNum(void); #endif以上,就是全部代码。 其实就主要用到EXTI外部中断而已,不是很复杂,难点在如何使用单个按键控制LED闪烁(好像在说废话:}) 欢迎并感谢建议! |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |