本文最后修改时间:2022年09月15日 11:02
一、本节简介
本节介绍如何编写一个可以自己选择引脚的短按、双击、长按三种方式的按键驱动。
二、实验平台
1、硬件平台
1)树莓派pico开发板
①树莓派pico开发板*2
②micro usb数据线*2
2)电脑
2、软件平台
1)VS CODE
三、版权声明
1)作者:甜甜的大香瓜
2)声明:喝水不忘挖井人,转载请注明出处。
3)纠错/业务合作:897503845@qq.com
4)香瓜嵌入式之树莓派群:512598061
5)本文出处:原创连载资料《简单粗暴学树莓派》
6)完整开源资料下载地址(电脑端打开):
opengua.taobao.com
四、实验前提
1、在进行本文步骤前,请先阅读以下章节:
1)《简单粗暴学树莓派》的“第一章至第二章”章节。
2、在进行本文步骤前,请先实现以下章节:
1)《简单粗暴学树莓派》的《香瓜树莓派pico之新建工程》章节。
五、硬件原理图
也就是:。
引脚号 | 功能 | 状态变化 |
17 | 按键 | 按键按下之前是高电平,按下之后是低电平 |
六、实验步骤
1、在VS CODE工程的GUA_CODE文件夹下,添加驱动GUA_Key.c
//********************************************************************** //name: GUA_Key.c //author: opengua //changetime: 2022.09.06 //********************************************************************** #include "pico/stdlib.h" #include "GUA_Key.h" /*********************macro definition************************/ //trigger level #define GUA_KEY_TRIGGER 0 //removing jitter #define GUA_KEY_DISAPPEARS_SHAKES_SHORT_COUNT (40000) //10ms #define GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT (40000*250) //2.5s #define GUA_KEY_SHORT_INTERVAL (10000000) //1s #define GUA_KEY_GET_VALUE gpio_get(GUA_KEY_PIN) /*********************Internal variables************************/ static uint32_t sGUA_Key_DisappearsShakes_TriggerCount = 0; //count value //********************************************************************** //name: GUA_Key_Scan //parameter: none //return: GUA_KEY_STATUS_IDLE or // GUA_KEY_STATUS_TRIGGER_SHORT or // GUA_KEY_STATUS_TRIGGER_LONG or // GUA_KEY_STATUS_NO_LOOSEN //author: opengua //changetime: 2022.09.06 //********************************************************************** uint8_t GUA_Key_Scan(void) { uint32_t nGUA_TimeOut = 0;
//TRIGGER if(GUA_KEY_GET_VALUE == GUA_KEY_TRIGGER) { //If the last key was a long key end, the release must be detected before the next count can begin if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT) { return GUA_KEY_STATUS_NO_LOOSEN; } //count sGUA_Key_DisappearsShakes_TriggerCount++;
//Determine if the count is sufficient while(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_SHORT_COUNT) { //When a release or timeout is detected, it is processed if((GUA_KEY_GET_VALUE != GUA_KEY_TRIGGER) || (sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)) { //long press 2.5S if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT) { return GUA_KEY_STATUS_TRIGGER_LONG; } //short press else { //The timeout count is cleared to zero nGUA_TimeOut = 0;
//Check whether there is a connection while((GUA_KEY_GET_VALUE != GUA_KEY_TRIGGER)) { //If the button is not pressed and times out, it indicates that there is only one button if(nGUA_TimeOut++ > GUA_KEY_SHORT_INTERVAL) { //The count is cleared to zero sGUA_Key_DisappearsShakes_TriggerCount = 0;
return GUA_KEY_STATUS_TRIGGER_SHORT; } }
//Determine if the count is sufficient while(GUA_KEY_GET_VALUE == GUA_KEY_TRIGGER) { //Start counting sGUA_Key_DisappearsShakes_TriggerCount++; //When a release or timeout is detected, it is processed if((GUA_KEY_GET_VALUE != GUA_KEY_TRIGGER) || (sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)) { //when long press 2.5S if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT) { //Clear up counter sGUA_Key_DisappearsShakes_TriggerCount = 0; return GUA_KEY_STATUS_TRIGGER_LONG; } //when short press else { //Clear up counter sGUA_Key_DisappearsShakes_TriggerCount = 0;
return GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT; } } }
//Clear up counter sGUA_Key_DisappearsShakes_TriggerCount = 0;
return GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT; } }
//Continue counting to determine the length of the button sGUA_Key_DisappearsShakes_TriggerCount++; } } //no press else { sGUA_Key_DisappearsShakes_TriggerCount = 0; }
return GUA_KEY_STATUS_IDLE; } //********************************************************************** //name: GUA_Key_Init //parameter: none //return: none //author: opengua //changetime: 2022.09.06 //********************************************************************** void GUA_Key_Init(void) { gpio_init(GUA_KEY_PIN); gpio_set_dir(GUA_KEY_PIN, GPIO_IN); gpio_pull_up(GUA_KEY_PIN); } |
2、在VS CODE工程的GUA_CODE文件夹下,添加驱动头文件GUA_Key.h
//********************************************************************** //name: GUA_Key.h //author: opengua //changetime: 2022.09.06 //********************************************************************** #ifndef _GUA_KEY_H_ #define _GUA_KEY_H_ /*********************macro definition************************/ #define GUA_KEY_PIN 17 //key pin //trigger transitions #define GUA_KEY_STATUS_IDLE 0 //no press #define GUA_KEY_STATUS_TRIGGER_SHORT 1 //short press #define GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT 2 //double press #define GUA_KEY_STATUS_TRIGGER_LONG 3 //long press 2.5S #define GUA_KEY_STATUS_NO_LOOSEN 4 //no loosen /*********************external function************************/ uint8_t GUA_Key_Scan(void); void GUA_Key_Init(void); #endif |
3、将新写的驱动文件新添加到可执行
4、修改main.c
//********************************************************************** //name: main.c //author: opengua //changetime: 2022.09.06 //********************************************************************** #include "pico/stdlib.h" #include "GUA_Led.h" #include "GUA_Key.h" /*********************Internal variables************************/ /*********************Internal function************************/ static void GUA_Init(void); //********************************************************************** //name: GUA_Init //parameter: none //return: none //author: opengua //changetime: 2022.09.06 //********************************************************************** static void GUA_Init(void) { //LED GUA_Led_Init(); GUA_Led_Set(GUA_LED_SET_LOW); //KEY GUA_Key_Init(); } //********************************************************************** //name: main //parameter: none //return: none //author: opengua //changetime: 2022.09.06 //********************************************************************** void main(void) { uint8_t nGUA_Ret; GUA_Init(); while(1) { //key scan nGUA_Ret = GUA_Key_Scan();
//If a button is pressed, deal with it if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_SHORT) { GUA_Led_Set(GUA_LED_SET_HIGH); sleep_ms(100); GUA_Led_Set(GUA_LED_SET_LOW); sleep_ms(100); } else if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT) { GUA_Led_Set(GUA_LED_SET_HIGH); sleep_ms(100); GUA_Led_Set(GUA_LED_SET_LOW); sleep_ms(100); GUA_Led_Set(GUA_LED_SET_HIGH); sleep_ms(100); GUA_Led_Set(GUA_LED_SET_LOW); sleep_ms(100); } else if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_LONG) { GUA_Led_Set(GUA_LED_SET_HIGH); sleep_ms(100); GUA_Led_Set(GUA_LED_SET_LOW); sleep_ms(100); GUA_Led_Set(GUA_LED_SET_HIGH); sleep_ms(100); GUA_Led_Set(GUA_LED_SET_LOW); sleep_ms(100); GUA_Led_Set(GUA_LED_SET_HIGH); sleep_ms(100); GUA_Led_Set(GUA_LED_SET_LOW); sleep_ms(100); } } } |
七、实验结果
编译并仿真,设置断点分别在按键的三种情况(短按、双击、长按),
1、当短按0~3秒内1次,会被识别为短按。
2、当短按后在1秒内再次短按,则会被识别为双击。
3、当长按3秒以上(即使不松开)也会被识别为长按。
因此,实验成功。