手把手教你学51单片机之十八 RS485通信与Modbus协议
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协议。 Modbus协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其他设备之间可以通信,已经成为一种工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。这种协议定义了一种控制器能够认识使用的数据结构,而不管它们是经过何种网络进行通信的。它描述了控制器请求访问其它设备的过程,如何回应来自其它设备的请求,以及怎样侦测错误记录,它制定了通信数据的格局和内容的公共格式。 在进行多机通信的时候,Modbus协议规定每个控制器必须要知道它们的设备地址,识别按照地址发送过来的数据,决定是否要产生动作,产生何1.2.1Modbus协议特点
51单片机RS485通信Modbus协 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)