这是一个基于 FreeRTOS 的 STM32 示例程序,它展示了如何使用两个任务分别进行数字输入和模拟输入的读取。下面是对代码的详细注释:
包含头文件和定义
#include <STM32FreeRTOS.h> // 包含 STM32 的 FreeRTOS 库
#ifndef USER_BTN
#define USER_BTN 2 // 如果没有默认定义用户按钮的引脚,则将其定义为引脚 2
#endif
SemaphoreHandle_t xSerialSemaphore; // 声明一个互斥信号量句柄,用于管理串口的访问
声明任务函数
void TaskDigitalRead(void *pvParameters); // 声明数字读取任务函数
void TaskAnalogRead(void *pvParameters); // 声明模拟读取任务函数
setup() 函数
void setup() {
Serial.begin(9600); // 初始化串口通信,波特率为 9600
while (!Serial) {
; // 等待串口连接。对于原生 USB 板,如 Leonardo、Micro、Yun 等,这是必要的。
}
// 创建并初始化互斥信号量,用于管理串口的访问
if (xSerialSemaphore == NULL) {
xSerialSemaphore = xSemaphoreCreateMutex();
if (xSerialSemaphore != NULL)
xSemaphoreGive(xSerialSemaphore);
}
// 创建两个任务,一个用于数字读取,一个用于模拟读取
xTaskCreate(TaskDigitalRead, "DigitalRead", 128, NULL, 2, NULL);
xTaskCreate(TaskAnalogRead, "AnalogRead", 128, NULL, 1, NULL);
// 启动调度器
vTaskStartScheduler();
// 如果 RAM 不足,输出错误信息并进入死循环
Serial.println("Insufficient RAM");
while (1);
}
loop() 函数
void loop() {
// 空函数体。任务在 TaskDigitalRead 和 TaskAnalogRead 中完成。
}
数字读取任务
void TaskDigitalRead(void *pvParameters) {
uint8_t pushButton = USER_BTN; // 将用户按钮的引脚号赋给 pushButton
pinMode(pushButton, INPUT); // 设置 pushButton 引脚为输入模式
for (;;) { // 任务永远不应该返回或退出
int buttonState = digitalRead(pushButton); // 读取按钮状态
if (xSemaphoreTake(xSerialSemaphore, (TickType_t)5) == pdTRUE) {
// 如果成功获取到信号量,则输出按钮状态
Serial.print("Button state: ");
Serial.println(buttonState);
xSemaphoreGive(xSerialSemaphore); // 释放信号量
}
vTaskDelay(1); // 在读取之间延迟 15ms 以保持稳定性
}
}
模拟读取任务
void TaskAnalogRead(void *pvParameters) {
for (;;) {
int sensorValue = analogRead(A0); // 读取模拟引脚 A0 的值
if (xSemaphoreTake(xSerialSemaphore, (TickType_t)5) == pdTRUE) {
// 如果成功获取到信号量,则输出传感器值
Serial.println(sensorValue);
xSemaphoreGive(xSerialSemaphore); // 释放信号量
}
vTaskDelay(1); // 在读取之间延迟 15ms 以保持稳定性
}
}
这个示例展示了如何使用 FreeRTOS 在 STM32 上创建并运行多个任务,以及如何使用信号量来同步对共享资源(如串口)的访问。
效果
1、按下按键
2、松开按键
|