在这里分享一个我写到基于 FreeRTOS 的按键程序,只是自己的一个思路,欢迎讨论。
数据结构定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
#ifndef __XTP_DEFINES_H #define __XTP_DEFINES_H
#include "at32f413.h" #include <stdbool.h> #include <stdio.h>
#define USE_FREERTOS (1) #define AT32 #define LED
#if USE_FREERTOS #include "FreeRTOS.h" #include "task.h" #endif
#ifdef LED #include "led.h" #endif
#define KEY_PCS 2
struct key_buffer_t { uint16_t buffer; bool previous_state; uint32_t down_count; };
struct key_gpiox_t { gpio_type *gpiox; uint16_t pin; };
struct xtp_system_t { int32_t global_num_1; int32_t key_count; struct key_buffer_t key_buffer[KEY_PCS]; struct key_gpiox_t key_gpiox[KEY_PCS]; };
extern struct xtp_system_t xtp_system;
#endif
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
#include "xtp_defines.h" #include "xtp_gpio.h" #include <stdbool.h> int global_num_1 = 0;
struct xtp_system_t xtp_system = { .global_num_1 = 0, .key_count = 0, .key_buffer = { { .buffer = 0xffff, .previous_state = false, .down_count = 0, }, { .buffer = 0xffff, .previous_state = false, .down_count = 0 } }, .key_gpiox = { { .gpiox = OK_KEY_GPIOX, .pin = OK_KEY_PIN }, { .gpiox = LEFT_KEY_GPIOX, .pin = LEFT_KEY_PIN } } };
|
主逻辑代码
主逻辑在Tick钩子函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| void vApplicationTickHook(void) { BaseType_t YieldRequired;
for (int i = 0; i < KEY_PCS; i++) { xtp_system.key_buffer[i].buffer = (xtp_system.key_buffer[i].buffer << 1) | (!io_get_level(xtp_system.key_gpiox[i].gpiox, xtp_system.key_gpiox[i].pin));
if (xtp_system.key_buffer[i].buffer == (uint16_t)0x0000) { xtp_system.key_buffer[i].previous_state = true; } else if (xtp_system.key_buffer[i].buffer == (uint16_t)0xffff && xtp_system.key_buffer[i].previous_state == true) { xtp_system.key_buffer[i].previous_state = false;
switch (i) { case 0: xTaskNotifyGive(xTaskGetHandle("led_task")); break; case 1: YieldRequired = xTaskResumeFromISR(xTaskGetHandle("test_task")); if (YieldRequired == pdTRUE) {
portYIELD_FROM_ISR(YieldRequired); } break;
default: break; }
} else { } } }
|