前言
在完成基本的传感器采集,串口通讯移植修改后,其实作为一个单品传感器已经是正常的工作起来了,但是如果我们在使用产品的时候有特殊情况,比如需要发送特定的无线报文,或者设置不同的工作模式之类的操作,我们就可以通过按键操作进行一定的配置。
所以本文会移植一个按键驱动,能够支持按键 短按,固定时间的长按等操作,同时周期执行的程序改成使用定时器来控制。
本文是《RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread》完结篇
❤️
一个简单的应用:无线温湿度传感器
❤️
一个小内存的芯片:STM32L051C8T6
❤️
一个小而美丽的物联网操作系统:RT-Thread
❤️
本 RT-Thread 专栏记录的开发环境:
RT-Thread记录(一、RT-Thread 版本、RT-Thread Studio开发环境 及 配合CubeMX开发快速上手)
RT-Thread记录(二、RT-Thread内核启动流程 — 启动文件和源码分析)
❤️
RT-Thread 内核篇系列博文链接:
RT-Thread记录(三、RT-Thread 线程操作函数及线程管理与FreeRTOS的比较)
RT-Thread记录(四、RT-Thread 时钟节拍和软件定时器)
RT-Thread记录(五、RT-Thread 临界区保护)
RT-Thread记录(六、IPC机制之信号量、互斥量和事件集)
RT-Thread记录(七、IPC机制之邮箱、消息队列)
RT-Thread记录(八、理解 RT-Thread 内存管理)
RT-Thread记录(九、RT-Thread 中断处理与阶段小结)
❤️
在STM32L051C8 上使用 RT-Thread 应用篇系列博文连接:
RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread (一、无线温湿度传感器 之 新建项目)
RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread (二、无线温湿度传感器 之 CubeMX配置)
RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread (三、无线温湿度传感器 之 I2C通讯)
RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread (四、无线温湿度传感器 之 串口通讯)
一、按键操作
在初步的测试框架中,我当时使用的是简单的按键处理方式,这里也上一下源码做测试备份:
static void key_thread_entry(void *par){
while(1){
if(key1_read == 0){
rt_thread_mdelay(10); //去抖动
if(key1_read == 0){
//按键按下,do something
while(key1_read == 0){rt_thread_mdelay(10);}
}
}
if(key2_read == 0){
rt_thread_mdelay(10); //去抖动
if(key2_read == 0){
//按键按下,do something
while(key2_read == 0){rt_thread_mdelay(10);}
}
}
rt_thread_mdelay(1);
}
}
但是在实际中,如果要实现长按,组合按之类的方式,还是需要一个适用的按键驱动。
1.1 按键驱动移植
按键驱动 是用我自己一直使用的一个,在我博文以前上传过,.c.h文件都开源了:
几个实用的按键驱动(STM32、51都适用)
老样子,把文件放置我们自己的驱动文件夹下面,然后右击,同步 scons 配置至项目:
因为这个驱动程序源码都给了,移植替换也不麻烦,所以简单看看:
1.2 按键测试
使用方式我介绍按键的博文也说过,在这个应用上只使用了3中按键方式:
这里直接看下测试结果,按键正常:
按键移植成功,因为我们按键调用都使用的是开始已经创建好的看见线程,所以相对之前额外的内存占用是没有的,多的只是一个全局变量Timer21_count,如下图:
细节说明: unsigned int 几个字节在不同编译器或者平台可能是不一样的,我们只需简单的测试一下即可:
二、定时器操作
虽然按键也用到了定时器,但是那个定时器是专门给按键驱动用的,我们开始还初始化了一个定时时间1S的定时器,开始也测试过了。
在使用裸机的时候,需要一定时间周期性的进行某项工作,我们只能使用定时器,而用了操作系统,在单独的线程中直接使用操作系统的延时函数也可以达到效果。
在一般的应用,定时时间没有那么严格要求的时候,完全可以直接使用rt_thread_mdelay,比如原始的周期处理:
但是复杂一些的应用,都使用rt_thread_mdelay,线程多了管理起来就不方便了,如果使用定时器配合信号量(在裸机中就是全局变量)那就是比较规范的方式了。
2.1 定时器逻辑添加
我们需要给定时器创建一个计数的全局变量,然后到了一定的时间给需要执行任务的线程通知,这个通知我们新建信号量实现(虽然通知也可以使用全局变量),但是既然用了RT-Thread ,就把IPC机制用起来,这样保证良好的习惯也为以后做大的应用打下好的基础。
我们操作如下图所示:
所以我们原始的周期处理代码改成如下所示:
2.2 定时器测试
测试也没什么,串口通讯接收报文也正常,今天改的按键和定时器也正常。
最后测试所有的功能和结果都正常:
三、时刻关注占RAM大小
今天的工作做完,本应用篇也算完结了,最后还是要看一下占用RAM的大小:
最终的程序,运行时候需要占用 RAM的大小: 7456 字节,我们的芯片 RAM:8192字节。
最后大小说明
从一开始,因为我们是在小内存的芯片上使用 RT-Thread ,所以每一篇每改一次代码博主都会记录内存使用大小。
最终程序我们上面记录需要使用的 RAM 大小为 7456 字节,实际上本次应用内存占用还有一定的优化空间的,比如主线程2K还是可以减少一点,按键线程其实不需要512字节等等。。。
但是因为本次应用也确实简单,而且内存也没到溢出的地步,所以就没有遇到瓶颈也就没有特意的花精力去处理每一个线程合适的大小。
其实在文章中,我也经常说明一些影响内存的细节问题,希望看过我文章的小伙伴都有体会。