▼点击下方名片,关注公众号,获取更多精彩内容▼
欢迎关注【玩转单片机与嵌入式】公众号,回复关键字获取更多免费视频和资料
回复【加群】,【单片机】、【STM32】、【硬件知识】、【硬件设计】、【经典电路】、【论文】、【毕业设计】、【3D封装库】、【PCB】、【电容】、【TVS】、【阻抗匹配】、【资料】、【终端电阻】、【Keil】、【485】、【CAN】、【振荡器】、[USBCAN]、【PCB】、【智能手环】、【智能家居】、【智能小车】、【555】、【I2C】、【华为】、【中兴】,等……
一:第一次命令输入
#include "stm32f4xx_hal.h"
#define PACKET_START_BYTE 0x7E
#define PACKET_END_BYTE 0x7E
#define MAX_PACKET_SIZE 20 // 最大数据包大小,根据实际情况调整
typedef struct {
uint8_t device_address;
uint8_t command;
uint8_t data_length;
uint8_t data[MAX_PACKET_SIZE];
uint8_t checksum;
uint8_t is_valid;
} SerialPacket;
SerialPacket received_packet;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
static uint8_t buffer[MAX_PACKET_SIZE];
static uint8_t buffer_index = 0;
static uint8_t is_inside_packet = 0;
if (huart == &huart2) {
if (!is_inside_packet) {
if (buffer_index == 0 && received_byte == PACKET_START_BYTE) {
is_inside_packet = 1;
buffer[buffer_index++] = received_byte;
}
} else {
buffer[buffer_index++] = received_byte;
if (buffer_index >= 4) {
uint8_t data_length = buffer[3] - 2; // 计算数据区长度(不包括校验和和包尾)
if (buffer_index == (data_length + 6)) { // 收到完整的数据包
received_packet.device_address = buffer[1];
received_packet.command = buffer[2];
received_packet.data_length = data_length;
for (int i = 0; i < data_length; i++) {
received_packet.data[i] = buffer[4 + i];
}
received_packet.checksum = buffer[data_length + 4];
received_packet.is_valid = 1;
// 处理接收到的数据包,例如执行相应的命令
// ...
// 复位接收缓冲区和状态
buffer_index = 0;
is_inside_packet = 0;
}
}
}
HAL_UART_Receive_IT(&huart2, &received_byte, 1); // 启动下一次接收中断
}
}
int main(void) {
// 初始化HAL库和串口2
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
// 启动接收中断
HAL_UART_Receive_IT(&huart2, &received_byte, 1);
while (1) {
// 在这里可以执行其他任务
// ...
}
}
二:第二次命令输入
UART_HandleTypeDef huart2;
typedef struct {
uint8_t device_address;
uint8_t command;
uint8_t data_length;
uint8_t data[MAX_PACKET_SIZE];
uint8_t checksum;
uint8_t is_valid;
} SerialPacket;
SerialPacket received_packet;
// 接收缓冲区
uint8_t rx_buffer[MAX_PACKET_SIZE];
uint8_t rx_buffer_index = 0;
uint8_t is_inside_packet = 0;
void process_received_data() {
// 在这里可以解析和处理接收到的数据包
// 访问 received_packet 中的数据进行解析
// 例如,你可以根据 received_packet.command 执行相应的操作
// ...
// 清除接收缓冲区,准备接收下一个数据包
memset(rx_buffer, 0, sizeof(rx_buffer));
rx_buffer_index = 0;
is_inside_packet = 0;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart == &huart2) {
if (!is_inside_packet) {
if (rx_buffer_index == 0 && rx_buffer[0] == PACKET_START_BYTE) {
is_inside_packet = 1;
}
} else {
rx_buffer[rx_buffer_index++] = received_byte;
if (rx_buffer_index >= 4) {
uint8_t data_length = rx_buffer[3] - 2; // 计算数据区长度(不包括校验和和包尾)
if (rx_buffer_index == (data_length + 6)) { // 收到完整的数据包
received_packet.device_address = rx_buffer[1];
received_packet.command = rx_buffer[2];
received_packet.data_length = data_length;
for (int i = 0; i < data_length; i++) {
received_packet.data[i] = rx_buffer[4 + i];
}
received_packet.checksum = rx_buffer[data_length + 4];
received_packet.is_valid = 1;
process_received_data(); // 处理接收到的数据包
// 启动下一次接收中断
HAL_UART_Receive_IT(&huart2, rx_buffer, 1);
}
}
}
}
}
int main(void) {
// 初始化HAL库和串口2
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
// 启动接收中断
HAL_UART_Receive_IT(&huart2, rx_buffer, 1);
while (1) {
// 在这里可以执行其他任务
// ...
}
}
三:总结及应对挑战
其中一条:持续学习和更新技能,在任何时代、任何领域都是保持自身竞争力的手段之一。比如:关注小编的公众号,一起学习、一起成长。比如加入小编的微信及技术交流群,与高手一起学习。
END
扫描上方二维码加群,回复【加群】或扫码加我好友,限时免费进入技术交流群。
推荐阅读
END
扫描上方二维码加群,回复【加群】或扫码加我好友,限时免费进入技术交流群。
感谢大家阅读,如果喜欢
请点赞和“在看”吧,或者分享到朋友圈。
点击跳转到原文,限时优惠加入我们的知识星球(加好友获取免费券)