微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 手把手教你学51单片机之十八 RS485通信与Modbus协议

手把手教你学51单片机之十八 RS485通信与Modbus协议

时间:11-19 来源:互联网 点击:

flagFrame=1;//设置帧接收完成标志

}

}

}

}

else

{

cntbkp=0;

}

}

/*串口驱动函数,监测数据帧的接收,调度功能函数,需在主循环中调用*/

voidUartDriver()

{

unsignedcharlen;

unsignedcharpdatabuf[40];

if(flagFrame)//有命令到达时,读取处理该命令

{

flagFrame=0;

len=UartRead(buf,sizeof(buf)-2);//将接收到的命令读取到缓冲区中

UartAction(buf,len);//传递数据帧,调用动作执行函数

}

}

/*串口中断服务函数*/

voidInterruptUART()interrupt4

{

if(RI)//接收到新字节

{

RI=0;//清零接收中断标志位

if(cntRxd

{//保存接收字节,并递增计数器

bufRxd[cntRxd++]=SBUF;

}

}

if(TI)//字节发送完毕

{

TI=0;//清零发送中断标志位

flagTxd=1;//设置字节发送完成标志

}

}

/*main.c文件程序源代码/

#include

unsignedcharT0RH=0;//T0重载值的高字节

unsignedcharT0RL=0;//T0重载值的低字节

voidConfigTimer0(unsignedintms);

externvoidUartDriver();

externvoidConfigUART(unsignedintbaud);

externvoidUartRxMonitor(unsignedcharms);

externvoidUartWrite(unsignedchar*buf,unsignedcharlen);

voidmain()

{

EA=1;//开总中断

ConfigTimer0(1);//配置T0定时1ms

ConfigUART(9600);//配置波特率为9600

while(1)

{

UartDriver();//调用串口驱动

}

}

/*串口动作函数,根据接收到的命令帧执行响应的动作

buf-接收到的命令帧指针,len-命令帧长度*/

voidUartAction(unsignedchar*buf,unsignedcharlen)

{

//在接收到的数据帧后添加换车换行符后发回

buf[len++]=r;

buf[len++]=n;

UartWrite(buf,len);

}

/*配置并启动T0,ms-T0定时时间*/

voidConfigTimer0(unsignedintms)

{

unsignedlongtmp;//临时变量

tmp=11059200/12;//定时器计数频率

tmp=(tmp*ms)/1000;//计算所需的计数值

tmp=65536-tmp;//计算定时器重载值

tmp=tmp+33;//补偿中断响应延时造成的误差

T0RH=(unsignedchar)(tmp>>8);//定时器重载值拆分为高低字节

T0RL=(unsignedchar)tmp;

TMOD&=0xF0;//清零T0的控制位

TMOD|=0x01;//配置T0为模式1

TH0=T0RH;//加载T0重载值

TL0=T0RL;

ET0=1;//使能T0中断

TR0=1;//启动T0

}

/*T0中断服务函数,执行串口接收监控*/

voidInterruptTimer0()interrupt1

{

TH0=T0RH;//重新加载重载值

TL0=T0RL;

UartRxMonitor(1);//串口接收监控

}

现在看这种串口程序,是不是感觉很简单了呢?串口通信程序我们反反复复的使用,加上随着学习的模块越来越多,实践的越来越多,原先感觉很复杂的东西,现在就会感到简单了。从设备管理器里可以查看所有的COM口号,我们下载程序用的是COM4,而USB转RS485虚拟的是COM5,通信的时候我们用的是COM5口,如图18-3所示。


图18-3RS485通信试验设置和结果

1.2Modbus通信协议介绍

我们前边学习UART、I2C、SPI这些通信协议,都是最底层的协议,是“位”级别的协议。而我们在学习13章做实用串口通信程序的时候,我们通过串口发给单片机三条指令,让单片机做了三件不同的事情,分别是“buzzon”、“buzzoff”和“showstr”。随着系统复杂性的增加,我们希望可以实现更多的指令。而指令越来越多,带来的后果就是非常杂乱无章,尤其是这个人喜欢写成“buzzon”、“buzzoff”,而另外一个人喜欢写成“onbuzz”、“offbuzz”。导致不同开发人员写出来的程序代码不兼容,不同厂家的产品不能挂到一条总线上通信。

随着这种矛盾的日益严重,就会有聪明人提出更合理的解决方案,提出一些标准来,今后我们的编程必须按照这个标准来,这种标准也是一种通信协议,但是和UART、I2C、SPI通信协议不同的是,这种通信协议是字节级别的,叫做应用层通信协议。在1979年由Modicon(现为施耐德电气公司的一个品牌)提出了全球第一个真正用于工业现场总线的协议,就是Modbus协议。

1.2.1Modbus协议特点

Modbus协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其他设备之间可以通信,已经成为一种工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。这种协议定义了一种控制器能够认识使用的数据结构,而不管它们是经过何种网络进行通信的。它描述了控制器请求访问其它设备的过程,如何回应来自其它设备的请求,以及怎样侦测错误记录,它制定了通信数据的格局和内容的公共格式。

在进行多机通信的时候,Modbus协议规定每个控制器必须要知道它们的设备地址,识别按照地址发送过来的数据,决定是否要产生动作,产生何

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top