2022年avr单片机中使用MODBUS协议的方法 .pdf
-
资源ID:39719067
资源大小:43.08KB
全文页数:6页
- 资源格式: PDF
下载积分:4.3金币
快捷下载
![游客一键下载](/images/hot.gif)
会员登录下载
微信登录下载
三方登录下载:
微信扫一扫登录
友情提示
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
|
2022年avr单片机中使用MODBUS协议的方法 .pdf
Avr单片机中使用modbus协议的方法有幸做了个项目,其中使用到了单片机和上位机通讯的程序,上位机用组态实现功能,探索了些方法,写出来和大家分享一下,这些知识本不是什么秘密,本人参考了许多资料,自己整合了一下。每种程序都是算法多样,最终功能实现就行。大家做单片机串口通讯时是不是总想有一种以不变应万变的思想,就是在底层单片机硬件和软件不变的情况下,去适应任何上位机软件系统,当然可以实现,这就需要用到标准的通讯协议了,以下我就和大家分享一下我做的modbus协议(单片机端),如果上位机用组态软件的情况下,你直接使用通讯协议就行它会自动和单片机通讯。大家在设计单片机程序时首先要定义好数据结构,先构想一下需要哪些采集数据,上位机需要查询什么数据,数据的类型和全局与否,运算的精度等等。然后把上位机需要采集的数据用一个数组管理起来,便于modbus协议的实现。单片机里串口通讯程序尽量用查询发送,中断接收的方式,要定义发送缓冲区和接收缓冲区,以便提高系统效率。以下程序用gcc 实现,单片机用avr 单片机。ISR(USART0_RX_vect)/串口 0 接收中断服务程序 volatile unsigned char status,data;cli();/关中断 status=UCSR0A;/ucsr0a赋值状态标志 data=UDR0;/接收的数据放入data 变量 usart0_rx_complete=0;/接收完成标志赋值0,还没有完成 if(status&(FRAMING_ERROR0|PARITY_ERROR0|DATA_OVERRUN0)=0)/如果各标志位正确则,执行以下 usart0_rx_count+;/接收缓冲区指针加一 switch(usart0_rx_count)case 1:if(data=add/第一个字节是地址,读入内部本机地址进行比较 usart0_rx_buf0=data;TIMSK0=0 x01;/启动定时器0,进行超时控制 else 名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 6 页 -usart0_rx_count=0;break;case 2:if(data=0 x03)|(data=0 x01)|(data=0 x05)|(data=0 x10)=0)/如果第一位不等于读指令0 x03,01,功能码,则清接收缓冲区指针 usart0_rx_count=0;else/等于这几个功能码则进行,则将他放入接收数组,并预计接收数组长度,不是10 码时都是8 个字节 usart0_rx_buf1=data;if(data!=0 x10)rx0_buf_size=8;break;case 3:usart0_rx_buf2=data;break;case 4:usart0_rx_buf3=data;break;case 5:usart0_rx_buf4=data;break;case 6:usart0_rx_buf5=data;break;case 7:usart0_rx_buf6=data;/10码时接收的字节计数 if(usart0_rx_buf1=0 x10)rx0_buf_size=9+usart0_rx_buf6;break;名师资料总结-精品资料欢迎下载-名师精心整理-第 2 页,共 6 页 -case 8:usart0_rx_buf7=data;/1,用 10 功能码时有效的数据位,system_reg_data的数据,这里规定最多接收26 个字节(不带crc)break;case 9:usart0_rx_buf8=data;/2 break;case 10:usart0_rx_buf9=data;/3 break;case 11:usart0_rx_buf10=data;/4 break;case 12:usart0_rx_buf11=data;/5 break;case 13:usart0_rx_buf12=data;/6 break;case 14:usart0_rx_buf13=data;/7 break;case 15:usart0_rx_buf14=data;/8 break;case 16:usart0_rx_buf15=data;/9 break;case 17:usart0_rx_buf16=data;/10 break;case 18:usart0_rx_buf17=data;/11 break;case 19:usart0_rx_buf18=data;/12 break;case 20:usart0_rx_buf19=data;/13 break;case 21:usart0_rx_buf20=data;/14 break;case 22:名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 6 页 -usart0_rx_buf21=data;/15 break;case 23:usart0_rx_buf22=data;/16 break;case 24:usart0_rx_buf23=data;/17 break;case 25:usart0_rx_buf24=data;/18 break;case 26:usart0_rx_buf25=data;/19 break;case 27:usart0_rx_buf26=data;/20 break;case 28:usart0_rx_buf27=data;/21 break;case 29:usart0_rx_buf28=data;/22 break;case 30:usart0_rx_buf29=data;/23 break;case 31:usart0_rx_buf30=data;/24 break;case 32:usart0_rx_buf31=data;/25 break;case 33:usart0_rx_buf32=data;/26 break;case 34:usart0_rx_buf33=data;/27 break;case 35:usart0_rx_buf34=data;/28 break;if(usart0_rx_count=rx0_buf_size)/串口 0 接收到了指定个数的数组则名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 6 页 -usart0_rx_count=0;/接收缓冲区指针清零 usart0_rx_complete=1;/串口 0 接收完标志 time0_num=0;/串口 0 的中断次数清零。它是超时控制的依据 TIMSK0=0 x00;/收到数据后则停止定时器0 不进行超时控制 else usart0_rx_count=0;sei();/开中断 以上中断接收程序可以实现上位机发来的0 x03,01,功能码指令,并且可以自动判断上位机发来10 功能码的包长。大家首先要深入了解modbus通讯协议的内涵,仔细体会各行程序的含义。其中本人加入了对通讯的超时控制,实际应用中很有必要。前面已经将上位机发来的命令,用中断接收的方式存入了单片机的接收缓冲区,中断服务程序不能执行太长时间,所以要将对指令的解读放入了主程序里。把对 modbus指令的解读程序列出,如下,只给出框架,因为每种应用是不一样的,需自己加入。void run_modbus(void)switch(usart0_rx_buf1)/判断主机发来的modbus 功能码是什么 case 0 x01:/读继电器输出的当前状要加入回传数据 break;case 0 x03:/功能码 03 要加入回传数据 break;case 0 x05:/05功能码要加入回传数据名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 6 页 -break;case 0 x10:/10功能码要加入回传数据 break;以上程序完全依赖一个提供给上位机数据的数组,自己要仔细排列好数据顺序,定义好长度。这里的程序使用一年有余完全正确和稳定。以上是基于串口实现的,信息高速发达的今天串口已经力不从心了。关于通讯,建议大家面向未来,了解一下can 总线网络通信,嵌入式工业以太网网络通信、zigbee 无线网络通信、IrDA 无线遥控通信、wifi无线网络通信、gprs 通信等等,本人喜欢 zigbee,精力有限不能全学啊。有心得会继续分享。名师资料总结-精品资料欢迎下载-名师精心整理-第 6 页,共 6 页 -