1. 代码
//sem.c
#include <rtthread.h> #include <rtdevice.h> #include "drv_gpio.h" #define THREAD_PRIORITY 25 #define THREAD_TIMESLICE 5 #define LED3_PIN GET_PIN(B, 3) ALIGN(RT_ALIGN_SIZE) static char thread3_stack[1024]; static struct rt_thread thread3; static struct rt_semaphore keyPress1_sem; void KeyScanCallBack(void) { rt_sem_release(&keyPress1_sem); } static void rt_thread3_entry(void *parameter) { static rt_err_t result; // static int cnt = 0; while(1) { /* 永 久 方 式 等 待 信 号 量, 获 取 到 信 号 量, 则 执 行 number 自 加 的 操 作 */ result = rt_sem_take(&keyPress1_sem, RT_WAITING_FOREVER); if (result != RT_EOK) { rt_kprintf("t3 take a static semaphore, failed. "); return; } else { rt_kprintf("t3 take a static semaphore"); rt_pin_write(LED3_PIN, PIN_HIGH); rt_thread_mdelay(1000); rt_pin_write(LED3_PIN, PIN_LOW); // if(++cnt >= 5) // { // rt_sem_detach(&keyPress1_sem); // return; // } } } } void Key1PressTaskInit(void) { /* 初 始 化 3 个 信 号 量 */ rt_sem_init(&keyPress1_sem, "keyPress1_sem", 0, RT_IPC_FLAG_FIFO); rt_pin_mode(LED3_PIN, PIN_MODE_OUTPUT); rt_thread_init(&thread3, "thread3", rt_thread3_entry, RT_NULL, &thread3_stack[0], sizeof(thread3_stack), THREAD_PRIORITY-1, THREAD_TIMESLICE); rt_thread_startup(&thread3); }
//usrtimer.c
#include <rtthread.h> #include <rtdevice.h> #include "drv_gpio.h" /* 定时器的控制块 */ static struct rt_timer timer3; static int cnt = 0; #define KEY1_PIN GET_PIN(C, 5) static uint8_t keyVal = 0; void KeyScanCallBack(void); static void keyscan(void* parameter) { static uint8_t i = 0; uint8_t val; val = rt_pin_read(KEY1_PIN); if(val == 0) { if(i < 200) { i ++; } } else { if(i >= 2) { keyVal = 1; rt_kprintf("key press val is %d ",keyVal); KeyScanCallBack(); keyVal = 0; } i = 0; } } void keyscan_init(void) { rt_pin_mode(KEY1_PIN, PIN_MODE_INPUT); rt_timer_init(&timer3, "timerKeyscan", /* 定时器名字是 timer2 */ keyscan, /* 超时时回调的处理函数 */ RT_NULL, /* 超时函数的入口参数 */ 5, /* 定时长度为 5 个 OS Tick */ RT_TIMER_FLAG_PERIODIC); /* 单次定时器 */ rt_timer_start(&timer3); }
//main.c
#include <rthw.h> #include <stdio.h> #include <rtthread.h> #include <rtdevice.h> #include "drv_gpio.h" #include "gd32f3x0.h" /* defined the LED2 pin: PC6 */ #define LED1_PIN GET_PIN(B, 1) #define LED2_PIN GET_PIN(B, 2) #define delay_ms(x) rt_thread_mdelay(x) #define RT_USR1_THREAD_PRIO 6 #define USR1_THREAD_NAME "usr1" static struct rt_thread usr1_thread; static rt_uint8_t usr1_thread_stack[500]; void rt_thread_usr1_entry(void *parameter) { /* set LED2 pin mode to output */ rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT); while (1) { rt_pin_write(LED2_PIN, PIN_HIGH); rt_thread_mdelay(2000); rt_pin_write(LED2_PIN, PIN_LOW); rt_thread_mdelay(3000); } } void keyscan_init(void); void Key1PressTaskInit(void); int main(void) { keyscan_init(); Key1PressTaskInit(); rt_thread_init(&usr1_thread, USR1_THREAD_NAME, rt_thread_usr1_entry, RT_NULL, &usr1_thread_stack[0], sizeof(usr1_thread_stack), RT_USR1_THREAD_PRIO, 20); rt_thread_startup(&usr1_thread); /* set LED1 pin mode to output */ rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT); while (1) { rt_pin_write(LED1_PIN, PIN_HIGH); rt_thread_mdelay(500); rt_pin_write(LED1_PIN, PIN_LOW); rt_thread_mdelay(600); } }
2.测试
按键一次,rt_sem_release(&keyPress1_sem);执行一次信号量值value加1。按键可以很快,但rt_thread3_entry()执行以下需要1s多。
rt_kprintf("t3 take a static semaphore"); rt_pin_write(LED3_PIN, PIN_HIGH); rt_thread_mdelay(1000); rt_pin_write(LED3_PIN, PIN_LOW);
即生产过快,消耗过慢。