完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
相关推荐
1个回答
|
|
在学习过程中,遇到了要使用很多个按键的情况,(没有同时按下的处理,没有用矩阵键盘)。一增加一个新按键,需要改动的地方太多,在网上看了一篇博客 https://blog.csdn.net/jiejiemcu/article/details/83097992 觉得它使用的方法不错,就进行学习研究,移植到stm32单片机上。这种编程思想值得学习,做个小总结。 typedef struct button { /* 下面是一个函数指针,指向判断按键手否按下的函数 */ uint8_t (*Read_Button_Level)(void); /* 读取按键电平函数,需要用户实现 */ char Name[BTN_NAME_MAX]; uint8_t Button_State : 4; /* 按键当前状态(按下还是弹起) */ uint8_t Button_Last_State : 4; /* 上一次的按键状态,用于判断双击 */ uint8_t Button_Trigger_Level: 2; /* 按键触发电平 */ uint8_t Button_Last_Level: 2; /* 按键当前电平 */ uint8_t Button_Trigger_Event; /* 按键触发事件,单击,双击,长按等 */ Button_CallBack CallBack_Function[number_of_event]; uint8_t Button_Cycle; /* 连续按键周期 */ uint8_t Timer_Count; /* 计时 */ uint8_t Debounce_Time; /* 消抖时间 */ uint8_t Long_Time_Record; /* 有长按记录 */ uint8_t Long_Time; /* 按键按下持续时间 */ struct button *Next; }Button_t uint8_t (*Read_Button_Level)(void); /* 读取按键电平函数,需要用户实现 */ 这段代码是一个函数指针形式,指向函数的指针,可以用来塞用户的函数 函数指针的定义:如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。而且函数名表示的就是这个地址。既然是地址我们就可以定义一个指针变量来存放,这个指针变量就叫作函数指针变量,简称函数指针。 关于函数指针的详解: https://blog.csdn.net/luoyayun361/article/details/80428882 Button_CallBack CallBack_Function[number_of_event]; 这是一个回调函数的数组, #define TRIGGER_CB(event) if(btn->CallBack_Function[event]) btn->CallBack_Function[event]((Button_t*)btn) 这个是关于回调的解析: https://blog.csdn.net/booirror/article/details/20007009 通过jlink_rttview 进行打印,按键的信息 按键1按下,短按,双击,长按,长按释放 这里是20ms轮询一下相应的按键状态查询函数 按键的创建程序,相应的回调函数,事件和stm32的低层函数进行连接 /************************************************************ * @brief 按键创建 * @param name : 按键名称 * @param btn : 按键结构体 * @param read_btn_level : 按键电平读取函数,需要用户自己实现返回uint8_t类型的电平 * @param btn_trigger_level : 按键触发电平 * @note NULL ***********************************************************/ void Button_Create(const char *name, Button_t *btn, uint8_t(*read_btn_level)(void), uint8_t btn_trigger_level) { if(btn == NULL) { SEGGER_RTT_WriteString(0, RTT_CTRL_TEXT_BRIGHT_RED"struct button is null!"RTT_CTRL_RESET"n"); } memset(btn,0,sizeof(*btn)); StrnCopy(btn->Name,name,BTN_NAME_MAX); btn->Button_State = NONE_TRIGGER; btn->Button_Last_State = NONE_TRIGGER; btn->Button_Trigger_Event = NONE_TRIGGER; btn->Read_Button_Level = read_btn_level; btn->Button_Trigger_Level = btn_trigger_level; btn->Button_Last_Level = btn->Read_Button_Level(); btn->Debounce_Time = 0; btn->Long_Time_Record = 0; SEGGER_RTT_printf(0,"button create success n"); Add_Button(btn); Print_Btn_Info(btn); } 相应的回调函数,用户可以将要处理的事件放在这段函数里 /************************************************************ * @brief 相应的回调事件 * @param btn:处理的按键 * @return NULL * @note 用户可在这里添加自己的事件处理函数 ***********************************************************/ void Btn1_Down_CallBack(void *btn) { SEGGER_RTT_printf(0,"Btn1_Down_CallBackn"); } void Btn1_Double_CallBack(void *btn) { SEGGER_RTT_printf(0,"Btn1_Double_CallBackn"); } void Btn1_Long_CallBack(void *btn) { SEGGER_RTT_printf(0,"Btn1_Long_CallBackn"); } void Btn1_LongFree_CallBack(void *btn) { SEGGER_RTT_printf(0,"Btn1_LongFree_CallBackn"); } 这是修改后,并应用的工程,希望从网络中学习到更多的东西 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1537 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1490 浏览 1 评论
910 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
654 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1538 浏览 2 评论
1845浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
596浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
499浏览 3评论
499浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
483浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-5 14:26 , Processed in 0.908080 second(s), Total 47, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号