串口通信全解(三)


title : “串口通信全解(三)”
date : 2021-05-25
tags :
- 设备通信

串口通信全解(三)

介绍完了串口通信的基础和通信时序,已经可以实现数据的传输。本文要介绍的通信协议是通信双方对传输数据格式的一种规则和约定,相当于机器和机器之间交流的语言。有了通信协议,不仅可以增加通信的可靠性,还可以实现更多的功能。接下来将使用MODBUS-RTU工控协议作例子进行讲解。

MODBUS-RTU简介

Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气 Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。**Modbus已经成为工业领域通信协议的业界标准(Defacto),并且现在是工业电子设备之间常用的连接方式。**如果要开发工控设备,学习和能够使用MODBUS协议十分重要。

Modbus协议目前存在用于串口以太网以及其他支持互联网协议的网络的版本。串口的Modbus协议包括Modbus RTU和Modbus ASCII。以太网的Modbus协议主要是Modbus-TCP。

本人目前使用的是MODBUS-RTU协议。

MODBUS-RTU结构

MODBUS-RTU的协议结构由**“设备地址 + 功能码 + 数据码 + 校验码”**组成。

  • 设备地址: 长度为一个字节。范围是0-255(其中有效范围是1-247,其他有特殊用途,比如255是广播地址),意义在于选择应答此次指令的从设备,相当于先点名来指派任务。

  • 功能码: 长度为一个字节。不同功能码对应不同功能,发送了功能码,就相当于告诉了从设备将要执行的任务类型。常用功能码有03和06,03功能为读取设备寄存器数据,06功能为将数据写入寄存器。

  • **数据码:**一般占用四个字节。根据功能码不同,有不同结构,将会在后续的实例中进行说明。

  • **校验码:**占用两个字节。为了保证指令没有发生错误,需要把前面的数据进行计算看数据是否一致,如果一致,就说明这帧数据是正确的,再进行回复。如果不一样,说明这帧数据在传输的时候出了问题,不需要进行操作。MODBUS-RTU的校验码为CRC校验。

下面使用两种常用的功能码进行举例说明MODBUS-RTU的数据包结构。

(1)03功能(读寄存器操作)

数据包格式:

设备地址功能码起始地址(高位)起始地址(低位)寄存器个数(高位)寄存器个数(低位)CRC校验码(高位)CRC校验码(低位)
0x010x030x000x020x000x030xA40x0B

此数据包功能表示为从0x01编号从设备的第0x0002个寄存器地址开始,往后读取0x0003个寄存器的值,CRC 码用于校验

返回数据形式为设备地址+功能码(03)+读取的字节长度(为寄存器个数的2倍)+读取到的寄存器值+CRC校验码

本例返回值为:

0x01 0x03 0x06 0xXX 0xXX 0xXX 0xXX 0xXX 0xXX CRC(H) CRC(L)

(2)06功能(写寄存器操作)

数据包格式:

设备地址功能码目标地址(高位)目标地址(低位)写入数据(高位)写入数据(低位)CRC校验码(高位)CRC校验码(低位)
0x010x060x000x3C0x010x900x480x3A

此数据包功能表示为在0x01编号的从设备地址为0x003C寄存器中写入数据0x0190,CRC码用于校验

从设备响应的返回数据和接收到的数据包相同。

本例返回值为:

0x01 0x06 0x00 0x3C 0x01 0x90 0x48 CRC(H) CRC(L)

CRC码

CRC码全称为循环冗余校验码,因为数据包的每一位数据都将参与CRC码计算,对结果产生很大影响,所以CRC码可以检测出多位错误。

现给出一种Verilog书写的CRC码计算方法。

初始化CRC校验码为‘0xFFFF’,每有一个字节接收过来后,与当前CRC校验码的低位进行异或运算,进行八次右移。如果移除的位是‘1’,再使用‘0xA001’进行异或;如果移除的位是‘0’,不进行操作。

//对缓存器中所有的数据进行计算得到CRC码

module CRC_generator(en,num,data_in,CLK,CRC_out,cnt,over,N,start);

input CLK,en;
input [7:0] data_in;
input [7:0] num;
output reg [15:0] CRC_out;
output reg [3:0]cnt;
output reg over,start;
output reg [7:0] N;
reg enbuf,enrise,enfall,error;

initial
begin
enbuf = 0;
enrise = 0;
over = 0;
N = 8'b00000000;
cnt = 4'b0000;
CRC_out = 16'b1111111111111111;
error = 0;
start = 0;
end

//en(数据传输完毕指示信号)的下降沿检测, 下降沿出现表示开始了下一次通信
always @(posedge CLK)   
begin
  enbuf <= en;
  enfall <= (~en) & enbuf;
end

always @(posedge CLK)
begin

//新字节和低八位异或
if((en ==1)&&(N < num-2)&&(start == 0)&&(over == 0)&&(num != 0))//num-2表示最后两位不参与运算
begin
	CRC_out[7:0] = CRC_out[7:0] ^ data_in;
	start = 1;//移位操作准备开始
end

///八次移位操作开始
else if(start == 1)
begin

	if(cnt < 4'b1000)
	begin
	
		if(CRC_out[0] == 1)//移除的位是1
		begin
		   CRC_out = CRC_out >> 1;
			CRC_out = CRC_out ^ 16'b1010000000000001;//和0xA001异或
			cnt = cnt + 4'b0001;
		end
		
		else begin
			CRC_out = CRC_out >> 1;
			cnt = cnt + 4'b0001;
			end
	end
	
	else begin//一个字节完成,准备计算一个字节
		cnt = 4'b0000;
		N = N+1;		
		start = 0;
		end
end
//八次移位操作结束,准备下一个数据

//发送的数据全部计算完毕,发出指示信号,等待下一次通讯发送数据
else if((en == 1)&&(over == 0))
begin
		CRC_out[15:8] <= CRC_out[7:0];
		CRC_out[7:0] <= CRC_out[15:8];//高低字节交换
		over = 1;							//CRC码计算完毕指令
		cnt = 4'b0000;
end
//下一次通信开始,将所有值复位准备重新进行计算
else if(enfall == 1)
begin
		over = 0;
		N = 0;
		cnt = 4'b0000;
		CRC_out = 16'b1111111111111111;
end

else error <= 1;

end
endmodule

总结

数据的通信协议是人为定义的,是为了实现某一特定任务设置的。相应的,想要实现通信协议,就要编写相应的协议发送、协议接收和协议校验代码,对发送的每一个字节数据赋予意义。MODBUS-RTU协议只是众多通信协议的一种,但是它们的本质是相同的。希望这篇文章能帮助你进一步理解通信协议。

Stkcd [股票代] ShortName [股票简称] Accper [统计截止日期] Typrep [报表类型编] Indcd [行业代] Indnme [行业名称] Source [公告来源] F060101B [净利润现金净含量] F060101C [净利润现金净含量TTM] F060201B [营业收入现金含量] F060201C [营业收入现金含量TTM] F060301B [营业收入现金净含量] F060301C [营业收入现金净含量TTM] F060401B [营业利润现金净含量] F060401C [营业利润现金净含量TTM] F060901B [筹资活动债权人现金净流量] F060901C [筹资活动债权人现金净流量TTM] F061001B [筹资活动股东现金净流量] F061001C [筹资活动股东现金净流量TTM] F061201B [折旧摊销] F061201C [折旧摊销TTM] F061301B [公司现金流1] F061302B [公司现金流2] F061301C [公司现金流TTM1] F061302C [公司现金流TTM2] F061401B [股权现金流1] F061402B [股权现金流2] F061401C [股权现金流TTM1] F061402C [股权现金流TTM2] F061501B [公司自由现金流(原有)] F061601B [股权自由现金流(原有)] F061701B [全部现金回收率] F061801B [营运指数] F061901B [资本支出与折旧摊销比] F062001B [现金适合比率] F062101B [现金再投资比率] F062201B [现金满足投资比率] F062301B [股权自由现金流] F062401B [企业自由现金流] Indcd1 [行业代1] Indnme1 [行业名称1] 季度数据,所有沪深北上市公司的 分别包含excel、dta数据文件格式及其说明,便于不同软件工具对数据的分析应用 数据来源:基于上市公司年报及公告数据整理,或相关证券交易所、各部委、省、市数据 数据范围:基于沪深北证上市公司 A股(主板、中小企业板、创业板、科创板等)数据整理计算
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值