本期我们将讲解,如何在之前创建的Hello World项目中添加按键检测功能。
一、创建一个新的线程用于按键检测
1、使用动态线程创建方法创建一个线程
首先,定义一个动态线程句柄结构体指针:
1/* 定义一个按键检测线程句柄结构体指针 */ 2static rt_thread_t key_thread = RT_NULL;
然后使用动态线程创建函数创建一个线程,其中线程优先级的范围根据系统配置情况不同, 可以在rtconfig.h中查看RT_THREAD_PRIORITY_MAX 宏定义
1/* 创建按键检测线程*/ 2key_thread = rt_thread_create( "key thread", /* 线程的名称 */ 3 key_thread_entry, /* 线程入口函数 */ 4 RT_NULL, /* 线程入口函数的参数 */ 5 256, /* 线程栈大小,单位是字节 */ 6 5, /* 线程的优先级,数值越小优先级越高*/ 7 10); /* 线程的时间片大小 */
线程创建成功后会返回该创建成功的线程句柄,如果线程创建失败,则返回RT_NULL,当线程创建成功后,我们启动该线程,让该线程进入就绪态
1/* 如果获得线程控制块,启动这个线程 */ 2if (key_thread != RT_NULL) 3 rt_err = rt_thread_startup(key_thread); 4else 5 rt_kprintf("key thread create failure !!! "); 6 7/* 判断线程是否启动成功 */ 8if( rt_err == RT_EOK) 9 rt_kprintf("key thread startup ok. "); 10else 11 rt_kprintf("key thread startup err. ");
2、使用静态线程创建方法创建一个线程
静态线程创建需要提供线程栈和句柄:
1/*定义一个按键检测静态线程栈*/ 2static char key_thread_stack[256]; 3/*定义一个按键检测静态线程句柄*/ 4static struct rt_thread key_thread;
然后使用静态线程初始化函数初始化静态线程对象
1 /* 初始化按键检测线程,名称是thread2,入口是thread2_entry */ 2 rt_err = rt_thread_init(&key_thread, /* 线程句柄 */ 3 "key thread", /* 线程的名称 */ 4 key_thread_entry, /* 线程入口函数 */ 5 RT_NULL, /* 线程入口函数的参数 */ 6 &key_thread_stack[0], /* 线程栈起始地址*/ 7 sizeof(key_thread_stack), /* 线程栈大小,单位是字节*/ 8 5, /* 线程的优先级,数值越小优先级越高*/ 9 10); /* 线程的时间片大小 */
线程创建成功后返回值为RT_EOK,创建失败则返回-RT_ERROR,当线程创建成功后,我们启动该线程,让该线程进入就绪态
1 /* 如果线程创建成功,启动这个线程 */ 2 if (rt_err == RT_EOK) 3 rt_err = rt_thread_startup(&key_thread); 4 else 5 rt_kprintf("key thread init failure !!! "); 6 7 /* 判断线程是否启动成功 */ 8 if( rt_err == RT_EOK) 9 rt_kprintf("key thread startup ok. "); 10 else 11 rt_kprintf("key thread startup err. ");
二、编写线程入口函数
首先,我们需要获取按键对应的引脚编号,使用 GET_PIN 宏定义,查看原理图,获取按键对应的引脚
1/* 获取相应的引脚编号 */ 2#define PIN_WK_UP GET_PIN(C, 13) 3#define PIN_KEY0 GET_PIN(D, 10) 4#define PIN_KEY1 GET_PIN(D, 9) 5#define PIN_KEY2 GET_PIN(D, 8)
接下来,我们编写一下按键检测线程入口函数,因为硬件上已经有上下拉了,所以就不配置内部上下拉了
1/* 按键检测线程入口函数*/ 2static void key_thread_entry(void *parameter) 3{ 4 static rt_uint8_t key_up = 1; /* 按键松开标志 */ 5 /* 初始化按键 */ 6 rt_pin_mode(PIN_WK_UP, PIN_MODE_INPUT); 7 rt_pin_mode(PIN_KEY0, PIN_MODE_INPUT); 8 rt_pin_mode(PIN_KEY1, PIN_MODE_INPUT); 9 rt_pin_mode(PIN_KEY2, PIN_MODE_INPUT); 10 11 while (1) 12 { 13 /* 检测按键是否按下 */ 14 if (key_up && ((rt_pin_read(PIN_WK_UP) == PIN_HIGH) || 15 (rt_pin_read(PIN_KEY0) == PIN_LOW) || 16 (rt_pin_read(PIN_KEY1) == PIN_LOW) || 17 (rt_pin_read(PIN_KEY2) == PIN_LOW) ) ) 18 { 19 rt_thread_mdelay(50); /* 延时消抖*/ 20 key_up = 0; 21 if (rt_pin_read(PIN_WK_UP) == PIN_HIGH) 22 { 23 /* 按键WK_UP按下,按键按下处理*/ 24 rt_kprintf("WK_UP pressed! "); 25 } 26 else if (rt_pin_read(PIN_KEY0) == PIN_LOW) 27 { 28 /* 按键KEY0按下,按键按下处理*/ 29 rt_kprintf("KEY0 pressed! "); 30 } 31 else if (rt_pin_read(PIN_KEY1) == PIN_LOW) 32 { 33 /* 按键KEY0按下,按键按下处理*/ 34 rt_kprintf("KEY1 pressed! "); 35 } 36 else if (rt_pin_read(PIN_KEY2) == PIN_LOW) 37 { 38 /* 按键KEY0按下,按键按下处理*/ 39 rt_kprintf("KEY2 pressed! "); 40 } 41 } 42 else if((rt_pin_read(PIN_WK_UP) == PIN_LOW) && 43 (rt_pin_read(PIN_KEY0) == PIN_HIGH) && 44 (rt_pin_read(PIN_KEY1) == PIN_HIGH) && 45 (rt_pin_read(PIN_KEY2) == PIN_HIGH) ) 46 { 47 key_up = 1; /* 按键已松开 */ 48 } 49 rt_thread_mdelay(100); 50 } 51 52}
三、实现效果
构建并下载程序,查看串口终端输出:
可以看到,按键检测线程启动成功,按键功能也实现了
四、代码优化
上面我们的代码都写在了mian.c里,我们可以将其放在一个单独的app_key.c文件中右键选中【applications】,选择新建源文件
输入 app_key.c文件名,点击确定:
将之前编写的代码都迁移到该文件中来,并提供一个app_key_init()函数供main()函数调用
1#include
在mian()函数中调用app_key_init()
实现效果一样:
全部0条评论
快来发表一下你的评论吧 !