【RP2350】香瓜树莓派RP2350之按键
本文最后修改时间:2025年05月11日 01:57
一、本节简介
本节以树莓派pico2开发板为例,举例如何写一个按键驱动。
二、实验平台
1、硬件平台
1)树莓派pico2开发板
①树莓派pico2开发板(作为仿真器)
②micro usb数据线
2)电脑
3)香瓜RP2350目标板
2、软件平台
1)VS CODE
三、版权声明
1)作者:甜甜的大香瓜
2)声明:喝水不忘挖井人,转载请注明出处。
3)纠错/业务合作:897503845@qq.com
4)香瓜嵌入式之树莓派群:512598061
5)本文出处:原创连载资料《简单粗暴学树莓派》
6)完整开源资料下载地址(电脑端打开):
opengua.taobao.com
四、实验前提
1、在进行本文步骤前,请先阅读以下章节:
1)《简单粗暴学树莓派》的“第一章至第二章”章节。
2、在进行本文步骤前,请先实现以下章节:
1)《简单粗暴学树莓派》的《香瓜树莓派RP2350之搭建开发环境(windows)》
2)《简单粗暴学树莓派》的《香瓜树莓派RP2350之新建工程》
3)《简单粗暴学树莓派》的《香瓜树莓派RP2350之LED》
五、硬件原理
1、硬件连接
实际只接了4根线,VCC、GND、CLK、DIO
2、原理图
GPIO4作为按键引脚,松开时高电平、按下时低电平
这是GPIO4同时作为进入下载模式的引脚。
下载模式简介:上电前按着按键、用usb线连接设备与电脑,给设备上电,这时电脑会识别到设备(像识别到u盘一样),此时可以松开按键。将工程的uf2文件复制进识别到的盘里,会自动退出,就代表更新好固件了。
六、实验步骤
1、在VS CODE工程文件夹下,添加驱动GUA_Key.c(VS CODE会自动加载)
//********************************************************************** //name: GUA_Key.c //introduce: 按键驱动 //author: opengua //email: 897503845@qq.com //QQ group: 香瓜嵌入式之树莓派群(512598061) //shop: opengua.taobao.com //changetime: 2025.02.18 //********************************************************************** #include "GUA_Key.h" #include "pico/stdlib.h" /*********************macro definition************************/ //trigger level #define GUA_KEY_TRIGGER false //removing jitter #define GUA_KEY_DISAPPEARS_SHAKES_SHORT_COUNT (10000) //10ms #define GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT (10000000*3) //3s #define GUA_KEY_SHORT_INTERVAL (10000000) //1s #define GUA_KEY_GET_VALUE gpio_get(GUA_KEY_PIN) /*********************Internal variables************************/ static volatile uint32_t sGUA_Key_DisappearsShakes_TriggerCount = 0; //count value //********************************************************************** //name: GUA_Key_Scan //introduce: 按键检测触发状态 //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 //email: 897503845@qq.com //QQ group: 香瓜嵌入式之树莓派群(512598061) //shop: opengua.taobao.com //changetime: 2025.02.18 //********************************************************************** 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 //introduce: 按键初始化 //parameter: none //return: none //author: opengua //email: 897503845@qq.com //QQ group: 香瓜嵌入式之树莓派群(512598061) //shop: opengua.taobao.com //changetime: 2025.02.18 //********************************************************************** void GUA_Key_Init(void) { //输入上拉 gpio_set_dir(GUA_KEY_PIN, GPIO_IN); gpio_set_function(GUA_KEY_PIN, GPIO_FUNC_SIO); gpio_pull_up(GUA_KEY_PIN); } |
2、在VS CODE工程文件夹下,添加驱动GUA_Led.h(VS CODE会自动加载)
//********************************************************************** //name: GUA_Key.h //introduce: 按键驱动的头文件 //author: opengua //email: 897503845@qq.com //QQ group: 香瓜嵌入式之树莓派群(512598061) //shop: opengua.taobao.com //changetime: 2025.02.18 //********************************************************************** #ifndef _GUA_KEY_H_ #define _GUA_KEY_H_ /*********************头文件************************/ #include <stdint.h> /*********************宏定义************************/ //GPIO PIN #define GUA_KEY_PIN 4 //按键的触发状态 #define GUA_KEY_STATUS_IDLE 0 //按键没触发 #define GUA_KEY_STATUS_TRIGGER_SHORT 1 //短按键触发 #define GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT 2 //双击触发 #define GUA_KEY_STATUS_TRIGGER_LONG 3 //长按键3S触发 #define GUA_KEY_STATUS_NO_LOOSEN 4 //按键没松开 /*********************外部函数声明************************/ void GUA_Key_Init(void); uint8_t GUA_Key_Scan(void); #endif |
3、添加对应驱动文件名称
4、在应用层中调用
1)添加驱动头文件(main.c中)
#include "GUA_Key.h" |
2)添加驱动初始化代码(main.c的main函数中)
//按键初始化 GUA_Key_Init(); |
3)添加测试代码(main.c的main函数中)
uint8_t nGUA_Ret;
//检测按键当前状态 nGUA_Ret = GUA_Key_Scan(); //短按键触发 if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_SHORT) { LED1_BAT0_OUT_H; sleep_ms(100); LED1_BAT0_OUT_L; sleep_ms(100); } else if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT) { LED1_BAT0_OUT_H; sleep_ms(100); LED1_BAT0_OUT_L; sleep_ms(100);
LED1_BAT0_OUT_H; sleep_ms(100); LED1_BAT0_OUT_L; sleep_ms(100); } else if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_LONG) { LED1_BAT0_OUT_H; sleep_ms(100); LED1_BAT0_OUT_L; sleep_ms(100);
LED1_BAT0_OUT_H; sleep_ms(100); LED1_BAT0_OUT_L; sleep_ms(100);
LED1_BAT0_OUT_H; sleep_ms(100); LED1_BAT0_OUT_L; sleep_ms(100); } |
七、实验结果
编译并仿真,全速运行
1、短按:led1会亮灭一次
2、连按:led1会亮灭两次
3、长按(超过3秒):led1会亮灭三次
因此实验成功。