基于STM32微控制器和FreeRTOS实时操作系统的按键检测与处理程序
代码功能描述
keyrelease.c 是一个基于STM32微控制器和FreeRTOS实时操作系统的按键检测与处理程序。其主要功能是检测多个按键的按下和松开事件,并通过消息队列将按键事件传递给主任务进行处理。以下是代码的详细功能描述:
1. 按键检测 :
- 检测四个按键的状态: START 、 UP 、 DOWN 和 BTWASH 。
- 使用GPIO输入模式检测按键的按下和松开事件。
- 通过状态机机制确保只有在按键松开时才触发事件。
2. 消息队列 :
- 使用FreeRTOS的消息队列( xButtonQueue )在任务间传递按键事件。
- 按键检测任务( ButtonTask )将检测到的按键事件发送到队列。
- 主任务( MainTask )从队列中接收按键事件并进行处理。
3. 多任务管理 :
- 使用FreeRTOS创建两个任务: ButtonTask 和 MainTask 。
- ButtonTask 负责按键检测,优先级较高(2)。
- MainTask 负责处理按键事件,优先级较低(1)。
4. 硬件初始化 :
- 初始化STM32的GPIO引脚,配置为上拉输入模式。
- 开启GPIOA和GPIOB的时钟。
5. 实时性 :
- 按键检测任务每10ms运行一次,确保实时检测按键状态。
- 使用FreeRTOS的延时函数( vTaskDelay )实现定时检测。
使用方法
1. 硬件连接
- START按键 :连接到GPIOA的Pin 15。
- UP按键 :连接到GPIOB的Pin 5。
- DOWN按键 :连接到GPIOB的Pin 6。
- BTWASH按键 :连接到GPIOB的Pin 8。
- 所有按键的另一端接地,使用上拉输入模式。
2. 代码配置
- FreeRTOS配置 :
- 确保FreeRTOS的配置文件( FreeRTOSConfig.h )正确设置,包括任务堆栈大小、队列长度等。
- GPIO配置 :
- 如果需要更改按键引脚,修改 START_PIN 、 UP_PIN 、 DOWN_PIN 和 BTWASH_PIN 的定义。
3. 编译与烧录
- 使用STM32开发环境(如Keil、STM32CubeIDE)编译代码。
- 将编译生成的二进制文件烧录到STM32微控制器中。
4. 运行与调试
- 启动程序后,FreeRTOS调度器会自动运行 ButtonTask 和 MainTask 。
- 按下任意按键, ButtonTask 会检测到松开事件并将其发送到消息队列。
- MainTask 从队列中接收按键事件,并根据按键类型执行相应的处理逻辑。
5. 扩展与修改
- 添加新按键 :
1. 在 ButtonType 枚举中添加新按键类型。
2. 在 ButtonTask 中添加新按键的检测逻辑。
3. 在 MainTask 的 switch 语句中添加新按键的处理逻辑。
- 修改按键处理逻辑 :
- 在 MainTask 的 switch 语句中修改对应按键的处理代码。
keyrelease.c
├── 宏定义
│ ├── START_PIN, UP_PIN, DOWN_PIN, BTWASH_PIN
├── 全局变量
│ ├── xButtonQueue (消息队列)
├── 枚举类型
│ ├── ButtonType (按键类型)
├── 任务函数
│ ├── ButtonTask (按键检测任务)
│ ├── MainTask (主任务)
├── 硬件初始化函数
│ ├── Hardware_Init (GPIO初始化)
├── 主函数
│ ├── main (初始化硬件、创建队列和任务、启动调度器)
#include "stm32f10x.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
// 定义按键引脚
#define START_PIN GPIO_Pin_15
#define UP_PIN GPIO_Pin_5
#define DOWN_PIN GPIO_Pin_6
#define BTWASH_PIN GPIO_Pin_8
// 按键队列
QueueHandle_t xButtonQueue;
// 按键枚举
typedef enum {
BUTTON_START,
BUTTON_UP,
BUTTON_DOWN,
BUTTON_BTWASH,
BUTTON_NONE
} ButtonType;
// 按键检测任务
void ButtonTask(void *pvParameters) {
ButtonType button;
uint8_t start_state = 1, up_state = 1, down_state = 1, btwash_state = 1;
while(1) {
// 检测按键状态
uint8_t current_start = GPIO_ReadInputDataBit(GPIOA, START_PIN);
uint8_t current_up = GPIO_ReadInputDataBit(GPIOB, UP_PIN);
uint8_t current_down = GPIO_ReadInputDataBit(GPIOB, DOWN_PIN);
uint8_t current_btwash = GPIO_ReadInputDataBit(GPIOB, BTWASH_PIN);
// 检测START按键按下并松开
if(start_state && !current_start) { // 按下
start_state = 0;
} else if(!start_state && current_start) { // 松开
start_state = 1;
button = BUTTON_START;
xQueueSend(xButtonQueue, &button, 0);
}
// 检测UP按键按下并松开
if(up_state && !current_up) {
up_state = 0;
} else if(!up_state && current_up) {
up_state = 1;
button = BUTTON_UP;
xQueueSend(xButtonQueue, &button, 0);
}
// 检测DOWN按键按下并松开
if(down_state && !current_down) {
down_state = 0;
} else if(!down_state && current_down) {
down_state = 1;
button = BUTTON_DOWN;
xQueueSend(xButtonQueue, &button, 0);
}
// 检测BTWASH按键按下并松开
if(btwash_state && !current_btwash) {
btwash_state = 0;
} else if(!btwash_state && current_btwash) {
btwash_state = 1;
button = BUTTON_BTWASH;
xQueueSend(xButtonQueue, &button, 0);
}
vTaskDelay(10 / portTICK_PERIOD_MS); // 10ms延时
}
}
// 主任务
void MainTask(void *pvParameters) {
ButtonType receivedButton;
while(1) {
if(xQueueReceive(xButtonQueue, &receivedButton, portMAX_DELAY) == pdPASS) {
switch(receivedButton) {
case BUTTON_START:
// 处理START按键
break;
case BUTTON_UP:
// 处理UP按键
break;
case BUTTON_DOWN:
// 处理DOWN按键
break;
case BUTTON_BTWASH:
// 处理BTWASH按键
break;
default:
break;
}
}
}
}
// 硬件初始化
void Hardware_Init(void) {
GPIO_InitTypeDef GPIO_InitStructure;
// 开启GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
// 配置START按键(PA15)
GPIO_InitStructure.GPIO_Pin = START_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置UP(PB5)、DOWN(PB6)、BTWASH(PB8)按键
GPIO_InitStructure.GPIO_Pin = UP_PIN | DOWN_PIN | BTWASH_PIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
int main(void) {
// 硬件初始化
Hardware_Init();
// 创建按键队列
xButtonQueue = xQueueCreate(10, sizeof(ButtonType));
// 创建任务
xTaskCreate(ButtonTask, "ButtonTask", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
xTaskCreate(MainTask, "MainTask", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
// 启动调度器
vTaskStartScheduler();
while(1);
}
「智能机器人开发者大赛」官方平台,致力于为开发者和参赛选手提供赛事技术指导、行业标准解读及团队实战案例解析;聚焦智能机器人开发全栈技术闭环,助力开发者攻克技术瓶颈,促进软硬件集成、场景应用及商业化落地的深度研讨。 加入智能机器人开发者社区iRobot Developer,与全球极客并肩突破技术边界,定义机器人开发的未来范式!
更多推荐



所有评论(0)