感知节点@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:
  //
}

串口打印:

image

 

posted @ 2025-10-25 13:42  辛河  阅读(4)  评论(0)    收藏  举报