ESP32在Arduino环境下的串口数据帧接收
测试平台
ESP32-WROOM
测试语言
Arduino @ PlatformIO
注意事项
需要添加Queue的库函数 作者: SMFSW
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
monitor_speed = 115200
upload_speed = 921600
lib_deps = smfsw/Queue@^1.11
代码实现
- CPP主文件
#include <Arduino.h>
#include <Ticker.h>
#include <cppQueue.h>
#include "CRC16.h"
#define MAX_LENGTH 200
#define FRAME_LENGTH 50
#define HEADER_FRAME_LEN_LENGTH 3
#define FRAME_HEADER 0XAA
const uint8_t frame_Header[2] = {0XAA, 0XAA};
uint8_t frame_Recv_Dat[FRAME_LENGTH];
cppQueue Serialqueue(sizeof(uint8_t), MAX_LENGTH, FIFO, true);
void SerialRecvEvent();
void SerialRecvFrameEvent(cppQueue& uint8queue);
void LED_Blink();
void DetectFrame();
Ticker LEDTask;
Ticker SerialFrameDetection;
void setup() {
Serial.begin(115200);
Serial.setRxTimeout(1);
Serial.onReceive(SerialRecvEvent);
delay(5);
pinMode(2, OUTPUT);
digitalWrite(2, HIGH);
LEDTask.attach(1, LED_Blink);
SerialFrameDetection.attach_ms(2, DetectFrame);
}
void loop() {
delay(5);
}
void LED_Blink(){
digitalWrite(2,!digitalRead(2));
}
void SerialRecvEvent(){
if(Serial.available() > 0){
uint8_t len = Serial.available();
for(uint8_t i = 0; i < len; i++){
uint8_t recvbyte = Serial.read();
Serialqueue.push(&recvbyte);
}
}
}
void DetectFrame(){
SerialRecvFrameEvent(Serialqueue);
}
void SerialRecvFrameEvent(cppQueue& uint8queue){
uint8_t qbyte;
uint8_t temp_Recv_Dat[FRAME_LENGTH];
uint8_t crc16modbussum[2];
if(uint8queue.getCount() >= HEADER_FRAME_LEN_LENGTH){
uint8_t header_chk_flag = false;
uint8_t CRC_16_chk_flag = false;
uint8queue.pop(&qbyte);
if(qbyte == FRAME_HEADER){
uint8_t header2;
uint8queue.peekIdx(&header2, 0);
if(header2 == FRAME_HEADER){
header_chk_flag = true;
uint8queue.pop(&header2);
temp_Recv_Dat[0] = qbyte;
temp_Recv_Dat[1] = header2;
uint8queue.pop((temp_Recv_Dat + 2));
#ifdef DEBUG
Serial.println("frame len is: " + String(temp_Recv_Dat[2]));
#endif
uint8_t waitingcount = 0;
if((uint8queue.getCount() < (temp_Recv_Dat[2] - HEADER_FRAME_LEN_LENGTH))||(waitingcount < 5)){
delayMicroseconds(10);
waitingcount++;
#ifdef DEBUG
Serial.println("queue count left is: " + String(uint8queue.getCount()));
#endif
}
else{
header_chk_flag = false;
}
for(uint8_t i = HEADER_FRAME_LEN_LENGTH; i < temp_Recv_Dat[2]; i++){
uint8queue.pop((temp_Recv_Dat + i));
}
CRC_16_chk_flag = update_crc(crc16modbussum, temp_Recv_Dat, temp_Recv_Dat[2]);
#ifdef DEBUG
Serial.println("CRC_16_chk_flag: " + String(CRC_16_chk_flag));
Serial.print("0X" + String(crc16modbussum[0],HEX) + ",");
Serial.println("0X" + String(crc16modbussum[1],HEX));
for(uint8_t i = 0; i < temp_Recv_Dat[2]; i++){
Serial.print("0X" + String(temp_Recv_Dat[i], HEX) + ", ");
}
Serial.println();
#endif
}
else{
header_chk_flag = false;
}
}
else{
header_chk_flag = false;
}
if(CRC_16_chk_flag == true && header_chk_flag == true){
memcpy(frame_Recv_Dat, temp_Recv_Dat, temp_Recv_Dat[2]);
Serial.println("received data frame: ");
for(uint8_t i = 0; i < frame_Recv_Dat[2]; i++){
Serial.print("0X" + String(frame_Recv_Dat[i], HEX) + ", ");
}
Serial.println();
}
}
}
- CRC16 校验CPP文件
#include "CRC16.h"
uint8_t update_crc(uint8_t* crc_sum, uint8_t *data_blk_ptr, uint8_t data_blk_size)
{
unsigned int i;
unsigned short crc = 0xFFFF;
unsigned short crcl;
uint8_t oriCRC16[2];
oriCRC16[0] = data_blk_ptr[data_blk_size - 2];
oriCRC16[1] = data_blk_ptr[data_blk_size - 1];
data_blk_size = data_blk_size - 2;
while(data_blk_size--){
crc ^= *data_blk_ptr++;
for (i = 0; i < 8; ++i){
if (crc & 1)
crc = (crc >> 1) ^ 0xA001;
else
crc = (crc >> 1);
}
}
crcl = crc;
crc_sum[1] = (unsigned char)(crc>>8);
crc_sum[0] = (unsigned char)(crcl);
if((oriCRC16[0] == crc_sum[0]) &&((oriCRC16[1] == crc_sum[1])))
return true;
else
return false;
}
- CRC16 校验头文件
#ifndef _CRC_16_H_
#define _CRC_16_H_
#include <arduino.h>
uint8_t update_crc(uint8_t* crc_sum, uint8_t *data_blk_ptr, uint8_t data_blk_size);
#endif
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构