(新手必看)自定义数据传输通信协议+STM32代码详解

前言


       本篇博客主要学习和了解一些单片机协议的格式,在对传输大数据或者要求准确性的时候,都需要通过协议来发送接收,下面通过了解协议的基本构成和代码来分析和实现协议的发送和接收。本篇博客大部分是自己收集和整理,如有侵权请联系我删除。

本次博客开发板使用的是正点原子精英版,芯片是STM32F103ZET6,需要资料可以@我拿取。

交流群:717237739

如果觉得有用点赞关注收藏三连,多谢支持

本博客内容原创,创作不易,转载请注明
————————————————

一 .什么是协议?

协议,是网络协议的简称,网络协议是通信计算机双方必须共同遵从的一组约定

如怎么建立连接,怎么样互相识别等,只有遵守这个约定,计算机之间才能相互通信交流。它的三要素是:语法,语义,时序。为了使数据在网络上从源到达目的,网络通信的参与方必须遵循相同的规则,这套规则为协议,最终体现为在网络上传输的数据包的格式。 

例如,串口的波特率,也是协议的一种表现格式。

参考知乎的资料了解七层协议:OSI 七层模型和TCP/IP模型及对应协议(详解)

OSI 七层模型和TCP/IP模型及对应协议(详解)

以上图片是为了让我们对协议有个充足的概念,具体的自己可以先行了解协议的含义和作用。

二 .协议的组成 

1.概念

这里说的数据协议是建立在物理层之上的通信数据包格式。所谓通信的物理层就是指我们通常所常用的RS232,RS485,红外,光纤,无线等通信方式

2.组成部分

比较可靠的通信协议包括:帧头,地址信息,数据类型,数据长度,数据块,校验位,帧尾

在日常自己定义的格式里,我们一般也是要遵循这些格式来定义一个数据包的发送和接收,以保证数据的完整性和准确性。

  • 帧头:一帧数据的开始,可以使用多个字节,具体内容自己定义。例如:0X55
  • 地址信息:主要用于多机通信中,通过地址信息的不同来识别不同的通信终端,确定和哪个设备进行通信(类似于IIC的芯片地址ID)。例如:0X01
  • 数据类型:可以标识后面紧接的是命令还是数据,例如0X01标识二进制,0x02标识十六进制等。
  • 数据长度:标识后面的要发送/接收的数据长度的个数。例如:0X02,表示后面跟两个数据。
  • 数据块:真正发送的数据内容,发送数据内容的长度和上面的数据长度对应。
  • 校验码:用来检验数据的完整性和准确性,一般常见的校验方式有(MODBUS_CRC16/CRC32,ADD8/16求和等等)
  • 帧尾:判断数据包的结束,可以为一个数据或者多个数据,自己定义,例如0XAA

根据以上的协议格式介绍,一般正常的数据包为:

0X55        0X01        0X01        0X02        0X13        0X88        CRC16H        CRC16L        0XAA

(帧头        地址        数据类型     长度        数据        数据        CRC检验H      CRC校验L      帧尾)

 

三. 类似的芯片手册协议格式讲解

这里参考一个芯片手册:SYN6658中文语音合成芯片 用户手册

 从这里分析可以得到:

帧头为:        0XFD        数据长度:2字节 0xXX 0xXX       命令字:参考手册一字节

命令参数:一字节     数据文本:最大4K字节

下面是手册的一些命令字和命令参数的参考:

完整的数据包格式:

 注意:在一些使用其他芯片的场景下,我们一般都需要遵守各个芯片的协议格式,然后根据手册和要求发送对应的数据包,这样协议对应才能驱动芯片。

四 . STM32代码实现自定义格式协议

我们在网上找到有对应的嵌入式协议测试题目,我们根据这个题目写出对应的协议发送和接收代码,代码内部做了注释,整体就不再讲解了,不懂的只能去补补C语言了,代码仅做参考。

测试题:

题目分析:

  • 1.数据包格式,建议直接做成结构体的模式,然后传入地址,一个个调用就很方便了
  • 2.已知的信息,直接宏定义调用,例如帧头帧尾
  • 3.提前写好串口数据包的发送和接收函数,类似数组遍历那种,然后了解清楚占用的字节大小
  • 4.题目要求最大65536,但是我们在STM32F103上实现,就最大256算了,不然超范围了
  • 串口发送和接收函数讲解和应用:基于STM32 + UART串口通信新手详解

 代码.C.H部分和main部分

#include "rs485.h"
#include <stdio.h>
#include <string.h>
u8 sendbuf[Send_Buf_Size];  //发送数据缓冲区
u8 recbuf[Rec_Buf_Size];		//接收数据缓冲区
RS485 rs485def={sendbuf,recbuf,0,0}; //rs485相关信息结构体//中断服务函数接收数据
void USART3_IRQHandler(void)
{u8 data;u32 head,tail;u8 len;if(USART3->SR & 1<<5){data= USART3->DR;
//		printf("%x\t",data);rs485def.recbuf[rs485def.reclen]=data ;//存放收到的数据rs485def.reclen++;if(rs485def.reclen >=8) //收到了包头和数据域长度{head = *(u32*)rs485def.recbuf;//获取包头
//			printf("head:0x%x\r\n",head);if(head == PACK_START)//收到包头{len = *(u32*)&rs485def.recbuf[4];//获取数据域长度
//				printf("reclen:%d,len:%d\r\n",rs485def.reclen,len);if(rs485def.reclen >= len+12) //一帧数据接收完成{tail = *(u32*)&rs485def.recbuf[len+4+4];//获取包尾 4包头所占4字节,4数据域长度所占4个字节
//					printf("tail:0x%x\r\n",tail);if(tail == PACK_TAIL )//包尾正确{rs485def.recflag = 1; //接收完成标志}else{rs485def.reclen = 0 ;}}}else{rs485def.reclen = 0 ;}}}
}//数据包接收函数
//函数功能:得到数据包的相关内容
//出口参数 :
//返回值 : 0 接收到数据 1 ,没收到数据
u8 RecPacket(Packet* pdata)
{u8* ptemp = rs485def.recbuf;u8 len;u8 buf[Rec_Buf_Size-20];pdata->pInform = (char *)buf;if(rs485def.recflag == 1){rs485def.recflag = 0 ;		//跳过包头ptemp += 4;//获取数据域长度len = *(u32*)ptemp;//获取验证码ptemp += 4;pdata->identify = *(u16*)ptemp;//获取源地址ptemp += 2;pdata->SrcAddr = *(u16*)ptemp;//获取目的地址ptemp += 2;pdata->DesAddr = *(u16*)ptemp;//获取命令码ptemp += 2;pdata->CmdNum = *(u16*)ptemp;ptemp += 2;  //指向信息内容//获取信息长度pdata->InformLlen = len - 8;	//获取信息内容memcpy(pdata->pInform,ptemp,pdata->InformLlen);//清除
//		memset(&rs485def,0,sizeof(RS485));rs485def.reclen = 0 ;return 0 ;}return 1;
}//数据包发送函数
//入口参数:发送的数据包
void SendPacket(Packet* pdata)
{u8* ptemp = rs485def.sendbuf;u8 sendlen;
//	u8 i;//把需要发送的数据赋给sendbuf//包头*(u32*)ptemp=PACK_START;
//	printf("0x%x\r\n",*ptemp);//数据域长度ptemp += 4;*(u32*)ptemp = pdata->InformLlen+8;//验证码ptemp += 4;*(u16*)ptemp = pdata->identify;//源地址ptemp += 2;*(u16*)ptemp = pdata->SrcAddr;//目的地址ptemp += 2;*(u16*)ptemp = pdata->DesAddr;//命令码ptemp += 2;*(u16*)ptemp = pdata->CmdNum;//信息内容ptemp += 2;//strcpy strncpy memcpy memset-->这几个函数的区别memcpy(ptemp,pdata->pInform,pdata->InformLlen);
//RS485_Send(ptemp,pdata->InformLlen);//包尾ptemp+=pdata->InformLlen;*(u32*)ptemp=0x88CC55AA;//发送数据ptemp += 4;sendlen = ptemp - rs485def.sendbuf;//发送数据长度	
//	printf("send:");
//	for(i=0;i<sendlen;i++)
//		printf("%x\t",rs485def.sendbuf[i]);RS485_Send(rs485def.sendbuf,sendlen); //发送数据
}
#ifndef _RS485_H_
#define _RS485_H_
#include "stm32f10x.h"
#include "io_bit.h"#define Send_Buf_Size 256
#define Rec_Buf_Size 	Send_Buf_Sizetypedef struct
{u8 *sendbuf;		 //发送数据缓冲区u8 *recbuf;			//接收数据缓冲区u8 reclen;			//接收数据总长度u8 recflag;			//接收完成事件标志位
}RS485;
extern RS485 rs485def;//数据包
#define PACK_START 0xAA55CC88	//帧头
#define PACK_TAIL  0x88CC55AA //帧尾
typedef struct
{u16 identify;  //验证码 --字节u16 SrcAddr;   //源地址u16 DesAddr;   //目的地址u16 CmdNum;    //命令码char* pInform; //信息内容u8 InformLlen; //信息长度
}Packet;u8 RecPacket(Packet* pdata);
void SendPacket(Packet* pdata);#endif

 main


int main()
{	Packet SendPack;Packet RecPack;char sendbuf[6]= "12345";LED_Init();KEY_Init();SCB->AIRCR= 0X05FA0500 ; //设置为分组2USART1_Init(115200);delay_init(72);OLED_Init();W25QXX_Init();DHT11_Init();RS485_Init();while(1){if(Key_Scanf(0))  //发送{	 
//			printf("key\r\n");//填充数据包   ---  学习 433模块 CC1101SendPack.identify = 0x1234;		//验证码SendPack.SrcAddr  = 0x5678;		//源地址SendPack.DesAddr  = 0x90ab;		//目的地址SendPack.CmdNum   = 0xcdef;	  //命令码SendPack.pInform  = sendbuf;	//信息内容SendPack.InformLlen=strlen(sendbuf);//信息长度SendPacket(&SendPack);}if(!RecPacket(&RecPack))//收到数据{//打印收到的数据printf("identify:0x%x\r\n",RecPack.identify);  //验证码printf("SrcAddr:0x%x\r\n",RecPack.SrcAddr);		 //源地址printf("DesAddr:0x%x\r\n",RecPack.DesAddr);		 //目的地址printf("CmdNum:0x%x\r\n",RecPack.CmdNum);			 //命令码printf("pInform:%s\r\n",RecPack.pInform);			 //信息内容printf("InformLlen:%d\r\n",RecPack.InformLlen);//信息长度}}	
}

总结:


      协议在一些公司的项目一般都会用到,最常见的就是485-modbus,不过基本的格式都差不多,这部分内容在项目了算是比较重要的,IAP升级的常用YModem协议也是异曲同工,类似的芯片DHT11和模块也会有协议格式要求。大家如果对我的博客有疑问或者错误,可以@我修改,大家相互交流。

交流群:717237739

如果觉得有用点赞关注收藏三连,多谢支持

本博客内容原创,创作不易,转载请注明

  点赞收藏关注博主,不定期分享单片机知识,互相学习交流。
————————————————
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/268055.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatisPlus简介

1 简介 MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 2、特性 无侵入 只做增强不做改变&#xff0c;引入它不会对现有工程产生影响&#xff0c;如丝般顺滑…

淡化了技术指标 还能做现货黄金交易?

技术指标是分析和预测现货黄金走势的其中一种方法&#xff0c;普通投资者多数依赖技术指标为自己的交易做判断。然而&#xff0c;近几年有一种观点认为&#xff0c;我们应该淡化技术指标&#xff0c;少使用或者不用技术分析来服务我们的交易。这个观点引起了不少投资者的思考&a…

Adobe的3D建模工具Substance 3D Painter 9.1.1 版本下载与安装

目录 前言一、Substance 3D Painter 9.1.1安装二、使用配置总结 前言 Adobe的Substance 3D Painter是一款强大的3D建模和纹理创建工具&#xff0c;专为数字艺术家设计&#xff0c;尤其是3D画家、游戏设计师和视觉特效艺术家。注&#xff1a;文末附有下载链接&#xff01; 这款…

关于Android studio新版本和NEW UI显示返回按钮的设置

1.新版Android studio问题 因为在新版本的Android Studio中&#xff0c;默认情况下是没有直接的选项来显示返回上一步按钮在状态栏上的&#xff0c;可以通过以下方法来实现返回上一步的功能&#xff1a; 在Android Studio的顶部菜单栏中&#xff0c;选择"View"。在…

剑指offer(C++)-JZ49:丑数(算法-其他)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 题目描述&#xff1a; 把只包含质因子2、3和5的数称作丑数&#xff08;Ugly Number&#xff09;。例如6、8都是丑数&#xff0c;…

Shell函数数组练习

1、编写函数&#xff0c;实现打印绿色OK和红色FAILED&#xff0c;判断是否有参数&#xff0c;存在为Ok&#xff0c;不存在为FAILED [rootshell ~]# vim ok.sh #!/bin/bash read -p "请输入一个参数:" i function ok…

DNF 单机联网 搭建教程(附视频)

更多游戏搭建&pvf修改教程请见: DNF教程 注意&#xff1a;请不要将游戏进行商业化&#xff0c;一切后果概不负责。仅供单机&#xff0c;好友之间进行娱乐&#xff01;&#xff01; 注意&#xff1a;请不要将游戏进行商业化&#xff0c;一切后果概不负责。仅供单机&#…

SiteGround如何设置WordPress网站自动更新

SiteGround Autoupdate功能会自动帮我们更新在他们这里托管的所有WordPress网站&#xff0c;这样做是为了保证网站安全&#xff0c;并且让它们一直保持最新状态。他们会根据我们选择的设置自动更新不同版本的WordPress&#xff0c;包括主要版本和次要版本。在每次自动更新之前&…

计算机循环神经网络(RNN)

计算机循环神经网络&#xff08;RNN&#xff09; 一、引言 循环神经网络&#xff08;RNN&#xff09;是一种常见的深度学习模型&#xff0c;适用于处理序列数据&#xff0c;如文本、语音、时间序列等。RNN通过捕捉序列数据中的时间依赖关系和上下文信息&#xff0c;能够解决很…

EasyRecovery2024国内免费的电脑数据恢复软件(一键备份还原)

EasyRecovery2024是coco玛奇朵Ontrack 的技术杰作。它是一个硬盘数据恢复工具&#xff0c;能够帮你恢复丢失的数据以及重建文件系统。其 Professioanl &#xff08;专业&#xff09; 版更是囊括了磁盘诊断、数据恢复、文件修复、E-mail 修复等全部 4 大类目19 个项目的各种数据…

npm,yarn,pnpm包管理器的介绍

npm&#xff0c;yarn和pnpm都是我们通常使用的包管理器&#xff0c;具体有什么区别呢&#xff1f;别的也不细说&#xff0c;就是快&#xff01;更节省磁盘空间。yarn比npm好&#xff0c;pnpm比yarn好&#xff01;

智慧机房与3D机房动环监控系统的应用

智慧机房是什么&#xff1f; 智慧机房是集采集信息、实时监控、数据分析、统一管理、故障告警等功能于一体的全方位、立体化的智能环境监控系统&#xff0c;构建物联网、大数据和云计算背景下现代企业的“数据心脏”。它能为机房管理者呈现细致入微的关键性数据&#xff0c;优…