#include <Arduino_FreeRTOS.h> // 引入FreeRTOS库,用于实现多任务并行处理
#include <queue.h> // 引入FreeRTOS中的队列库,用于任务之间传递数据
#define LED1_PIN 9 // 定义LED1连接的引脚为9
#define LED2_PIN 10
#define LED3_PIN 11
#define ANALOG_PIN A2 // 定义可变电阻(旋钮)的模拟引脚为A2
QueueHandle_t integerQueue; // 定义一个队列句柄,用于存储从模拟引脚读取的整数值
// 任务函数的前置声明
void TaskBlink(void *pvParameters); // LED闪烁任务
void TaskAnalogRead(void *pvParameters); // 模拟引脚读取任务
void TaskIdentitas(void *pvParameters); // 信息发送任务(目前代码中未使用此任务)
// 旋钮控制可变电阻(线性电位器)
// 可变电阻的初始值
int analogValue = 0;
void setup() {
// 初始化串口监视器,波特率为9600
Serial.begin(9600);
// 设置LED引脚为输出模式
pinMode(LED1_PIN, OUTPUT);
pinMode(LED2_PIN, OUTPUT); // 其他LED引脚未使用,注释掉
pinMode(LED3_PIN, OUTPUT);
pinMode(ANALOG_PIN, INPUT);
// 创建一个队列,用于存储10个整数值,每个队列项的大小为int(即4字节)
integerQueue = xQueueCreate(
10, // 队列长度为10
sizeof(int) // 队列中每个项目的大小为int类型
);
// 创建第一个任务:LED闪烁
xTaskCreate(
TaskBlink, // 任务函数
"Task Blink", // 任务名称
64, // 堆栈大小,64字节
NULL, // 传递给任务的参数,这里为NULL
2, // 任务优先级为2
NULL // 任务句柄(不需要的话可以为NULL)
);
// 创建第二个任务:读取模拟引脚
xTaskCreate(
TaskAnalogRead, // 任务函数
"Task Analog Read", // 任务名称
64, // 堆栈大小
NULL, // 任务参数
1, // 任务优先级为1
NULL // 任务句柄
);
// 创建第三个任务:发送信息
xTaskCreate(
TaskSendInfo, // 任务函数
"Task Send Info", // 任务名称
64, // 堆栈大小
NULL, // 任务参数
3, // 任务优先级为3
NULL // 任务句柄
);
}
void loop() {
// 主循环留空,因为任务已经交由FreeRTOS的调度器管理
}
// Task 1 - LED Blink
// Task 1 - LED闪烁任务
void TaskBlink(void *pvParameters) {
TickType_t xLastWakeTime = xTaskGetTickCount(); // 获取当前系统的节拍计数(用于定时)
// 定义任务延迟的周期时间,2000ms(2秒)
const TickType_t xFrequency = 2000 / portTICK_PERIOD_MS;
for(;;) { // 无限循环,任务不会退出
digitalWrite(LED1_PIN, HIGH); // 打开LED
Serial.println("LED1 ON"); // 在串口监视器输出LED状态
// 使用绝对延时:等待下一个周期到来
vTaskDelayUntil(&xLastWakeTime, xFrequency);
digitalWrite(LED1_PIN, LOW); // 关闭LED
Serial.println("LED1 OFF"); // 输出LED关闭状态
// 再次等待下一个周期到来
vTaskDelayUntil(&xLastWakeTime, xFrequency);
}
}
// Task 2 -
// Task 2 - 读取模拟引脚任务
void TaskAnalogRead(void *pvParameters) {
TickType_t xLastWakeTime = xTaskGetTickCount(); // 获取当前系统的节拍计数
// 定义任务延迟的周期时间,500ms(0.5秒)
const TickType_t xFrequency = 500 / portTICK_PERIOD_MS;
for(;;) { // 无限循环
analogValue = analogRead(ANALOG_PIN); // 从模拟引脚A2读取电压值(0-1023)
xQueueSend(integerQueue, &analogValue, portMAX_DELAY); // 将读取的值发送到队列中
Serial.print("可变电阻值为 : "); // 输出读取到的电阻值
Serial.println(analogValue);
// 控制 LED2 每500ms 闪烁一次
digitalWrite(LED2_PIN, HIGH); // 打开LED2
vTaskDelay(250 / portTICK_PERIOD_MS); // LED亮250ms
digitalWrite(LED2_PIN, LOW); // 关闭LED2
//vTaskDelay(250 / portTICK_PERIOD_MS); // LED灭250ms
vTaskDelayUntil(&xLastWakeTime, xFrequency); // 延迟500ms,等待下一个周期
}
}
// Task 3 - Serial Monitor
// Task 3 - 发送信息任务
void TaskSendInfo(void *pvParameters) {
int receivedADCValue; // 存储从队列中接收的值
TickType_t xLastWakeTime = xTaskGetTickCount(); // 获取当前系统的节拍计数
// 定义任务延迟的周期时间,5000ms(5秒)
const TickType_t xFrequency = 5000 / portTICK_PERIOD_MS;
for(;;) { // 无限循环
//Serial.print("SendInfo-传输数据:"); // 输出提示信息
if (xQueueReceive(integerQueue, &receivedADCValue, portMAX_DELAY)==pdTRUE) { // 从队列中接收数据
Serial.print("SendInfo-传输数据:");
Serial.println(receivedADCValue); // 打印接收到的数据
}else{
Serial.println("队列接收失败");
}
// 控制 LED2 每5s 闪烁一次
digitalWrite(LED3_PIN, HIGH); // 打开LED2
vTaskDelay(500 / portTICK_PERIOD_MS); // LED亮500ms
digitalWrite(LED3_PIN, LOW); // 关闭LED2
vTaskDelayUntil(&xLastWakeTime, xFrequency); // 每5秒执行一次
}
}