- 附上我的keil工程和cubemx工程
- 链接:https://pan.baidu.com/s/1iEmh_VOZfRK-eUi_VVicgA?pwd=gnjx
提取码:gnjx
- 链接:https://pan.baidu.com/s/1iEmh_VOZfRK-eUi_VVicgA?pwd=gnjx
- 基本的略讲了
- stm32cubemx的时钟树
- 定时器我们使用TIM6,因为我们的时钟频率为80x10的6次方,则我们需要每10ms进入定时器进行判断,则我们的psc设置为800-1,arr设置为1000-1,80000000/800/1000=100hz,因次同时打开TIM6的NVIC中断
- 按键处理部分(参考了
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:蓝桥杯嵌入式G431(hal库)——定时器实现按键长按、短按、双击_hal库单击,双击和长按控制灯状态的报告-CSDN博客
)在此基础上修改了一点。- 首先,重新定义定时器的回调函数,因为在官方中的回调函数是弱定义,因此可以重新定义。回调函数是这个
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
-
主函数while(1)外面用的代码
HAL_TIM_Base_Start_IT(&htim6); LCD_Init(); LCD_Clear(Black); LCD_SetBackColor(Black); LCD_SetTextColor(White);
while(1)里面的代码
while (1) { if (key[0].key_short == 1) { key[0].key_short = 0; i++; } if (key[0].key_long == 1) { key[0].key_long = 0; i--; sprintf(textbuf,"i:%d",i); LCD_DisplayStringLine(Line2,(uint8_t *)textbuf); } if (key[0].key_double == 1) { key[0].key_double = 0; i+=10; sprintf(textbuf,"i:%d",i); LCD_DisplayStringLine(Line2,(uint8_t *)textbuf); } sprintf(textbuf,"i:%d",i); LCD_DisplayStringLine(Line2,(uint8_t *)textbuf); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }
这里的key是定义在main.h中的结构体定义的结构体变量
-
看代码,代码里有注释,与引用的代码不同的地方是将第四个状态里冗余的代码删除了一些。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if (htim->Instance == TIM6) { key[0].cur_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0); key[1].cur_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1); key[2].cur_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2); key[3].cur_sta = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0); //这里是读取GPIO的状态 for(int i=0;i<4;i++){ //遍历四个按键 switch(key[i].key_choose) { // 根据状态处理每个状态需要处理的情况 case 0: //开始,就是检查是否按下,是按下的,因此我们跳转到2状态,消抖判断 if (key[i].cur_sta == 0) key[i].key_choose = 1; break; case 1: //消抖 if (key[i].cur_sta == 0) key[i].key_choose = 2; else key[i].key_choose = 0; break; case 2: if (key[i].cur_sta == 0) //这里如果按键还是按下的状态,则长按键的时间加一次 key[i].key_time_long++; else //松手后进入双击和单击判断状态 key[i].key_choose = 3;// break; case 3: if (key[i].cur_sta == 1) { //如果是松手的状态,则短按的时间++,到达一定阈值,且未到达长按键的阈值,则短按成立,否则长按成立,然后将状态置为0,时间同时清0 key[i].key_time_short++; if (key[i].key_time_short>10) { if (key[i].key_time_long<70) key[i].key_short = 1; else key[i].key_long = 1; key[i].key_choose = 0; key[i].key_time_long = 0; key[i].key_time_short = 0; } } else //如果按下的状态,跳转4 key[i].key_choose = 4; break; case 4: if (key[i].cur_sta == 0) key[i].key_choose = 5; //如果按下,双击消抖 else { //否则,跳回0,时间清0 key[i].key_choose=0; key[i].key_time_long = 0; key[i].key_time_short = 0; } break; case 5: if(key[i].cur_sta == 1) { // 松手了,则双击成立 key[i].key_double = 1; key[i].key_choose = 0; key[i].key_time_long = 0; key[i].key_time_short = 0; } break; } } } }
- 首先,重新定义定时器的回调函数,因为在官方中的回调函数是弱定义,因此可以重新定义。回调函数是这个
【蓝桥杯嵌入式】stm32三种按键(短按,长按,双击)一起实现
于 2024-02-26 22:39:57 首次发布
本文介绍了如何在STM32嵌入式开发中使用Cubemx配置TIM6定时器,以10ms周期检测按键状态,并处理按键的长按、短按和双击事件。通过HAL库实现了按键事件的处理逻辑。
摘要由CSDN通过智能技术生成