【FreeRTOS项目实例--构建一个简单的按键检测系统】

以下是一个基于FreeRTOS的小项目实例,构建一个简单的按键检测系统,它会在按下按键时通过串口发送一个确认消息,并且使用信号量进行任务间的通信和同步。

**项目描述:**

该项目有两个任务:
1. 键盘监听任务(KeyMonitorTask):持续监测指定GPIO引脚上的按键状态变化,当按键被按下时,释放一个信号量。
2. 串口打印任务(SerialPrintTask):定期检查信号量,如果有按键按下事件发生,则通过串口发送一条确认消息。

**具体实例:**


#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "stm32f4xx_hal.h"

#define KEY_GPIO_PORT    GPIOA
#define KEY_GPIO_PIN     GPIO_PIN_0
#define SERIAL_PRINT_PERIOD pdMS_TO_TICKS(100) // 100毫秒
#define SEMAPHORE_TIMEOUT pdMS_TO_TICKS(1000) // 1秒钟超时

SemaphoreHandle_t xKeyPressSemaphore;

void vKeyMonitorTask(void *pvParameters) {
    GPIO_InitTypeDef GPIO_InitStructure;
    // 初始化KEY_GPIO_PORT和KEY_GPIO_PIN为上拉输入
    // ...

    for (;;) {
        // 检查按键状态
        if (HAL_GPIO_ReadPin(KEY_GPIO_PORT, KEY_GPIO_PIN) == GPIO_PIN_RESET) {
            // 按键被按下,释放信号量
            xSemaphoreGive(xKeyPressSemaphore);
        }

        // 为了避免过于频繁的轮询,可以加入适当的延时
        vTaskDelay(pdMS_TO_TICKS(10));
    }
}

void vSerialPrintTask(void *pvParameters) {
    UART_HandleTypeDef huart; // 假设已经初始化好串口句柄
    static const char szKeyPressDetected[] = "Button press detected!\r\n";

    for (;;) {
        // 试图获取信号量,如果没有按键按下,等待一段时间
        if (xSemaphoreTake(xKeyPressSemaphore, SEMAPHORE_TIMEOUT) == pdTRUE) {
            // 发送按键按下消息
            HAL_UART_Transmit(&huart, (uint8_t*)szKeyPressDetected, strlen(szKeyPressDetected), HAL_MAX_DELAY);
        } else {
            // 如果超时没有按键按下,继续检查
        }

        // 按照预定频率执行任务
        vTaskDelay(SERIAL_PRINT_PERIOD);
    }
}

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_UART_Init(); // 初始化串口
    xKeyPressSemaphore = xSemaphoreCreateBinary(); // 创建信号量

    xTaskCreate(vKeyMonitorTask, "KeyMonitor", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
    xTaskCreate(vSerialPrintTask, "SerialPrint", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);

    vTaskStartScheduler();

    // 如果一切顺利,调度器不应该返回
    for (;;) {}
}

在这个项目中,`vKeyMonitorTask`不断检测按键状态,并在检测到按键按下时通过`xSemaphoreGive`函数释放信号量。同时,`vSerialPrintTask`定期检查信号量,如果在设定时间内(SEMAPHORE_TIMEOUT)成功获取到信号量,则通过串口发送一条按键按下已被检测的消息。通过这种方式,两个任务实现了协同工作,按键事件被正确捕获并反馈。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeRTOS一个开源的实时操作系统内核,被广泛应用于嵌入式系统中。ESP32是一款具有双核处理器和Wi-Fi功能的芯片,通过使用ESP-IDF开发框架可以进行软件开发。在ESP32-IDF开发中,使用FreeRTOS的消息队列可以实现不同任务之间的通信。 在ESP32开发中,可以通过中断服务程序(Interrupt Service Routine,ISR)来发送消息到消息队列,并在任务中通过接收方法响应。 首先,我们需要创建一个全局的消息队列句柄,可以使用xQueueCreate函数来创建一个消息队列。例如,可以使用以下代码创建一个大小为10的消息队列: xQueueHandle messageQueue = xQueueCreate(10, sizeof(int)); 然后,在中断服务程序中,可以使用xQueueSendFromISR方法将消息发送到消息队列中。例如,可以使用以下代码将一个整数值发送到消息队列中: int value = 100; xQueueSendFromISR(messageQueue, &value, NULL); 在任务中,可以使用xQueueReceive方法从消息队列中接收消息并进行响应。例如,可以使用以下代码从消息队列中接收一个整数值并打印出来: int receivedValue; xQueueReceive(messageQueue, &receivedValue, portMAX_DELAY); printf("Received value: %d\n", receivedValue); 需要注意的是,在接收消息时,可以通过指定第三个参数来设置等待时间。例如,使用portMAX_DELAY表示无限等待,即直到接收到消息为止。 通过以上步骤,我们可以实现在ESP32开发中使用FreeRTOS消息队列进行中断服务消息发送与响应。这种方式可以实现不同任务之间的通信和同步,提高系统的并发性和实时性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值