感知节点@9@ ESP32+arduino+FreeRTOS 第七个程序 读取射频卡卡号
设计为 一个任务读取射频卡卡号,一个任务串口通信,两个任务间消息队列实现通信。
1、基于FreeRTOS,设计一个程序框架
/* 程序: FREERTOS - 两(多个)个任务+消息队列 */ // 定义结构体类型 typedef struct { char msgName[10]; // 字符串:存储消息名称(使用固定长度char数组) int state; // 整数:0=关闭,1=开启 char infor[20]; // 消息 } qMsg; // 定义 队列 QueueHandle_t queueMsg = xQueueCreate(8, sizeof(qMsg)); // 定义任务1的函数 void task1(void *pt) { //++++++++++++ 初始化+++++++++++++++++++ qMsg q_msg = { "msg", // 字符串初始化 0, // 初始状态:开启 "nop" }; TickType_t timeOut = portMAX_DELAY; //++++++++++++ 超级循环+++++++++++++++++++ while (1) { // 正确字符串赋值方式(使用strncpy防止溢出) strncpy(q_msg.msgName, "task1msg", sizeof(q_msg.msgName)-1); q_msg.msgName[sizeof(q_msg.msgName)-1] = '\0'; // 确保终止符 q_msg.state = 1; xQueueSend(queueMsg, &q_msg, timeOut); vTaskDelay(1000);//等待,同时放弃CPU使用1000ticks } } // 定义任务2的函数 void task2(void *pt) { //++++++++++++ 初始化+++++++++++++++++++ qMsg q_msg = { "msg", // 字符串初始化 0, // 初始状态:开启 "nop" }; //++++++++++++ 超级循环+++++++++++++++++++ while (1) { TickType_t timeOut = 10; if (xQueueReceive(queueMsg,&q_msg, timeOut) == pdPASS) { Serial.print("Name: "); Serial.println(q_msg.msgName); Serial.print("State: "); Serial.println(q_msg.state); Serial.print("Infor: "); Serial.println(q_msg.infor); } } } void setup() { // put your setup code here, to run once: Serial.begin(115200); //创建和启动任务1 if (xTaskCreate(task1, "task1", 5120,// 足够大,防止堆栈溢出 NULL, 1, NULL) == pdPASS) Serial.println("Task1 Created."); //创建和启动任务2 if (xTaskCreate(task2, "Task2", 5120, // 足够大,防止堆栈溢出 NULL, 1, NULL) == pdPASS) Serial.println("Task2 Created."); } void loop() { // put your main code here, to run repeatedly: // 空 }
2、将调试通过的 读取射频卡卡号程序 整合至 FreeRTOS程序框架
举例任务1函数编写如下图,同样方法编写任务2函数。
感知节点@8@ ESP32+arduino+ 第六个程序 读取射频卡卡号 https://www.cnblogs.com/excellentHellen/p/19164365 的网页内最后的代码。
3、多次修改和调试,得到的基于freeRTOS完整程序
/* 程序: FREERTOS - 两(多个)个任务+消息队列 */ #include <SPI.h> #include <MFRC522.h> #define RST_PIN 4 // 复位引脚 #define SS_PIN 15 // 片选引脚 MFRC522 mfrc522(SS_PIN, RST_PIN); // 定义结构体类型 typedef struct { char msgName[10]; // 字符串:存储消息名称(使用固定长度char数组) int state; // 整数:0=关闭,1=开启 char infor[20]; // 消息 } qMsg; // 定义 队列 QueueHandle_t queueMsg = xQueueCreate(8, sizeof(qMsg)); // 定义任务1的函数 // 初始化 void task1(void *pt) { //++++++++++++ 初始化+++++++++++++++++++ qMsg q_msg = { "msg", // 字符串初始化 0, // 初始状态:开启 "nop" }; TickType_t timeOut = portMAX_DELAY; //++++++++++++ 超级循环+++++++++++++++++++ while (1) { // 检测新卡 if (!mfrc522.PICC_IsNewCardPresent()) { Serial.println("No Card"); vTaskDelay(100); continue; }; // 读取卡序列号 if (!mfrc522.PICC_ReadCardSerial()) { Serial.println("No Card ID"); vTaskDelay(100); continue; }; // 打印卡号(十六进制)长度是4个bytes //Serial.print("CardID(HEX): "); for (byte i = 0; i < mfrc522.uid.size; i++) { // Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "); // Serial.print(mfrc522.uid.uidByte[i], HEX); q_msg.infor[i] = mfrc522.uid.uidByte[i]; } // 停止操作 mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); // 正确字符串赋值方式(使用strncpy防止溢出) strncpy(q_msg.msgName, "task1msg", sizeof(q_msg.msgName)-1); q_msg.msgName[sizeof(q_msg.msgName)-1] = '\0'; // 确保终止符 q_msg.state = 1; xQueueSend(queueMsg, &q_msg, timeOut); vTaskDelay(1000);//等待,同时放弃CPU使用1000ticks } } // 定义任务2的函数 void task2(void *pt) { //++++++++++++ 初始化+++++++++++++++++++ qMsg q_msg = { "msg", // 字符串初始化 0, // 初始状态:开启 "nop" }; //++++++++++++ 超级循环+++++++++++++++++++ while (1) { TickType_t timeOut = 10; if (xQueueReceive(queueMsg,&q_msg, timeOut) == pdPASS) { Serial.print("Name: "); Serial.println(q_msg.msgName); Serial.print("State: "); Serial.println(q_msg.state); Serial.print("Infor: "); //Serial.println(q_msg.infor); for (byte i = 0; i < 4; i++) { Serial.print(q_msg.infor[i] < 0x10 ? " 0" : " "); Serial.print(q_msg.infor[i], HEX); } Serial.println(); } } } void setup() { // put your setup code here, to run once: Serial.begin(115200); SPI.begin(); mfrc522.PCD_Init(); //创建和启动任务1 if (xTaskCreate(task1, "task1", 2048, NULL, 1, NULL) == pdPASS) Serial.println("Task1 Created."); //创建和启动任务2 if (xTaskCreate(task2, "Task2", 2048, NULL, 1, NULL) == pdPASS) Serial.println("Task2 Created."); } void loop() { // put your main code here, to run repeatedly: // 空 }
串口打印:


浙公网安备 33010602011771号