分享个自己写的自定义串口协议
最近在写一个通过手控器控制设备动作的程序,手控器按键较多,所以通过串口来和外设设备进行通信,由于命令较多,所以做了个小协议以后也能用到,可做主机可做从机,适合近距离单机通讯,第二位功能码可做地址组成多机通讯,但最好加上校验位。新手入门,大佬请多多指教附上代码
[*]//自定义串口发送协议 例:68 01 00 03 FF ,除去包头包尾,中间为 功能码,数据1,数据2
[*]// 发送数据包函数功能码,第一位数据,第二位数据
[*]void SendDataPacket(uint8_t function, uint8_t data1, uint8_t data2) {
[*] // 发送包头
[*] USART1_SendData(PACKET_HEADER);
[*]
[*] // 发送功能码
[*] USART1_SendData(function);
[*]
[*] // 发送数据1和数据2
[*] USART1_SendData(data1);
[*] USART1_SendData(data2);
[*]
[*] // 发送包尾
[*] USART1_SendData(PACKET_TAILER);
[*]}
[*]
[*]
[*]void Anlsy_Data(uint8_t function, uint8_t data1, uint8_t data2)//所有按键接收解析在这里写
[*]{
[*] if(function == KEY_STAUS)
[*] {
[*] SysChenyuan.mark = QX_MARK;
[*] switch(data2)
[*] {
[*] case KEY1:
[*] SysChenyuan.Uart_Comd = QX1;
[*] printf("清洗1按键按下,data2 = %02d,function = %02d", data2, function);
[*] break;
[*] case KEY2:
[*] SysChenyuan.Uart_Comd = QX2;
[*] printf("清洗2按键按下,data2 = %02d,function = %02d", data2, function);
[*] break;
[*] case KEY3:
[*] SysChenyuan.Uart_Comd = QX3;
[*] printf("清洗3按键按下,data2 = %02d,function = %02d", data2, function);
[*] break;
[*] case KEY_STOP:
[*] SysChenyuan.all_stopped = YES;//停止标志
[*] printf("停止按键按下,data2 = %02d,function = %02d", data2, function);
[*] break;
[*] case KEY_CHONGSHUI:
[*] SysChenyuan.QiTa = CHONGSHUI;//冲水标志
[*] printf("冲水按键按下,data2 = %02d,function = %02d", data2, function);
[*] break;
[*] case KEY_HONGGAN:
[*] SysChenyuan.QiTa = HONGGAN;//烘干标志
[*] printf("烘干按键按下,data2 = %02d,function = %02d", data2, function);
[*] break;
[*] default:
[*] // 处理未知按键情况
[*] break;
[*] }
[*] }
[*]}
[*]extern uint8_t Serial_Rx3Flag,time_out3,time_out3_flag;
[*]// 解析数据包的函数
[*]int ParseDataPacket(void) {
[*] static uint8_t expectingHeader = 1; // 标记是否正在等待包头
[*] static uint8_t packetIndex = 0, i = 0; // 当前数据包内的索引
[*] uint8_t function, data1, data2;
[*]
[*] if(Serial_Rx3Flag == 1)
[*] {
[*] time_out3 = 0;
[*] time_out3_flag = 0;
[*] // 遍历缓冲区中的所有数据(在实际情况中,你可能只处理新接收到的数据)
[*] for ( i = 0; i < rxIndex; ++i) {
[*] if (expectingHeader) {
[*] if (rxBuffer == PACKET_HEADER) {
[*] expectingHeader = 0; // 找到了包头,开始解析数据包
[*] packetIndex = 0; // 重置数据包索引
[*] }
[*] // 如果不是包头,则忽略该字节或进行错误处理
[*] } else {
[*] switch (packetIndex) {
[*] case 0: // 功能码
[*] function = rxBuffer;
[*] break;
[*] case 1: // 数据1
[*] data1 = rxBuffer;
[*] break;
[*] case 2: // 数据2
[*] data2 = rxBuffer;
[*]
[*] // 检查包尾
[*] if (rxBuffer == PACKET_TAILER) {
[*] // 完整的数据包已接收,可以处理数据
[*] Anlsy_Data(function, data1, data2);
[*] // processPacket(function, data1, data2);
[*]
[*] // 重置状态以接收下一个数据包
[*] expectingHeader = 1;
[*] packetIndex = 0;
[*] rxIndex = 0; // 清除缓冲区(或者只清除已处理的部分)
[*] } else {
[*] // 没有找到包尾,可能是数据损坏或丢失,进行错误处理
[*] // TODO: 错误处理代码
[*] expectingHeader = 1; // 重置状态以接收下一个数据包
[*] packetIndex = 0;
[*] }
[*] break;
[*] default:
[*] // 无效的数据包索引,进行错误处理
[*] expectingHeader = 1; // 重置状态以接收下一个数据包
[*] packetIndex = 0;
[*] break;
[*] }
[*] if (packetIndex < 3) { // 还未到达包尾,递增索引
[*] packetIndex++;
[*] }
[*] }
[*] }
[*] rxIndex = 0;// 清除已处理的数据(如果rxIndex不是自动管理的)
[*] Serial_Rx3Flag = 0;
[*] }
[*] return 0; // 返回值可以根据需要来定义,例如表示是否成功解析了一个数据包
[*]}
[*]
[*]
[*]//下面是串口超时代码,我放在了10ms定时器里,看需要。
[*]// 定时器回调函数 10ms
[*]void vTimerCallback( TimerHandle_t xTimer )
[*]{
[*] if(time_out3 < 10 && time_out3_flag == 1) {
[*] time_out3++;
[*] }
[*]
[*] // 检查是否超时
[*] if(time_out3 >= 10) {
[*] time_out3 = 0;
[*] time_out3_flag = 0;
[*] // 执行超时处理,例如发送确认信息或者进行数据处理
[*] Serial_Rx3Flag = 1;
[*] }
[*]
[*]}
[*]
[*]//串口中断
[*]
[*]void USART1_IRQHandler(void)
[*]{
[*] if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET) //RXNE 标志位为1 表示可以接收数据
[*] {
[*] uint8_t ucReceivedChar;
[*] // 读取接收到的字符
[*] ucReceivedChar = USART_ReceiveData(USART1);
[*] if (rxIndex < RX_BUFFER_SIZE) {
[*] rxBuffer = ucReceivedChar;
[*] time_out3 = 0;
[*] time_out3_flag = 1;
[*] }
[*]// if(Serial_Rx3Flag == 1)
[*]// {
[*]// rxIndex= 0;
[*]// }
[*] USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除RXNE标志位
[*] }
[*]}
帮忙再加上 DMA 的演示,可参考下面的程序
4组串口UART使用DMA收发 @STC32G,易用,高效,稳定 !精品实战代码 - DMA: 支持4组串口,3组SPI,I2C,TFT-i8080/M6800,ADC 国芯技术交流网站 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)
深圳国芯人工智能有限公司-产品_STC32系列 (stcai.com)
页:
[1]