avr单片机中使用MODBUS协议的方法_第1页
avr单片机中使用MODBUS协议的方法_第2页
avr单片机中使用MODBUS协议的方法_第3页
avr单片机中使用MODBUS协议的方法_第4页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Avr单片机中使用modbus协议的方法有幸做了个项目,其中使用到了单片机和上位机通讯的程序,上位机用组态实现功能, 探索了些方法,写出来和大家分享一下,这些知识本不是什么秘密,本人参考了许多资料, 自己整合了一下。每种程序都是算法多样,最终功能实现就行。大家做单片机串口通讯时是不是总想有一种以不变应万变的思想,就是在底层单片机硬件和软件不变的情况下,去适应任何上位机软件系统,当然可以实现,这就需要用到标准的通讯协议了,以下我就和大家分享一下我做的modbus协议(单片机端),如果上位机用组态软件的情况下,你直接使用通讯协议就行它会自动和单片机通讯。大家在设计单片机程序时首先要定义好数据结构,

2、先构想一下需要哪些采集数据,上位机需要查询什么数据,数据的类型和全局与否,运算的精度等等。然后把上位机需要采集 的数据用一个数组管理起来,便于modbus协议的实现。单片机里串口通讯程序尽量用查询发送,中断接收的方式,要定义发送缓冲区和接收缓冲区,以便提高系统效率。以下程序用 gcc实现,单片机用avr单片机。ISR(USART0_RX_vect)/串口 0接收中断服务程序(volatile unsigned char status,data;cli();/ 关中断status = UCSR0A;/ucsr0a 赋值状态标志data = UDR0;/接收的数据放入 data变量usart0_r

3、x_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=0x01;/ 启动定时器0,进行超时控制 else( usart0_rx_count=0;)break;case 2:if (dat

4、a=0x03)|(data=0x01)|(data=0x05)|(data=0x10)=0)/如果第位不等于读指令 0x03, 01, 0 5, 1。功能码,则清接收缓冲区指针(usart0_rx_count=0;)else/等于这几个功能码则进行,则将他放入接收数组,并预计接收数组长度,不是10码时都是8个字节(usart0_rx_buf1=data;if (data!=0x10)(rx0_buf_size=8;)break;case 3:usart0_rx_buf2=data;break;case 4:usart0_rx_buf3=data;break;case 5:usart0_rx_b

5、uf4=data;break;case 6:usart0_rx_buf5=data;break;case 7:usart0_rx_buf6=data;/10码时接收的字节计数if (usart0_rx_buf1=0x10)(rx0_buf_size=9+usart0_rx_buf6;)break;case 8:usart0_rx_buf7=data;/1,用 10 功能码时有效的数据位,system_reg_data的数据,这里规定最多接收26个字节(不带crc )break;case 9:usart0_rx_buf8=data;/2break;case 10:usart0_rx_buf9=d

6、ata;/3break;case 11:usart0_rx_buf10=data;/4break;case 12:usart0_rx_buf11=data;/5break;case 13:usart0_rx_buf12=data;/6break;case 14:usart0_rx_buf13=data;/7break;case 15:usart0_rx_buf14=data;/8break;case 16:usart0_rx_buf15=data;/9break;case 17:usart0_rx_buf16=data;/10break;case 18:usart0_rx_buf17=data

7、;/11break;case 19:usart0_rx_buf18=data;/12break;case 20:usart0_rx_buf19=data;/13break;case 21:usart0_rx_buf20=data;/14break;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

8、;/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_r

9、x_buf33=data;/27 break;case 35:usart0_rx_buf34=data;/28 break;if(usart0_rx_count>=rx0_buf_size)/串口 0接收到了指定个数的数组则(usart0_rx_count=0;/接收缓冲区指针清零usart0_rx_complete=1;/串口 0 接收完标志time0_num=0;/ 串口 0的中断次数清零。它是超时控制的依据TIMSK0=0x00;/收到数据后则停止定时器0不进行超时控制) else (usart0_rx_count=0;)sei(); / 开中断)以上中断接收程序可以实现上位机发来

10、的0x03, 01, 0 5, 1 0功能码指令,并且可以自动判断上位机发来 10功能码的包长。大家首先要深入了解modbus通讯协议的内涵,仔细体会各行程序的含义。其中本人加入了对通讯的超时控制,实际应用中很有必要。前面已经将上位机发来的命令,用中断接收的方式存入了单片机的接收缓冲区,中断服务程序不能执行太长时间,所以要将对指令的解读放入了主程序里。把对modbus指令的解读程序列出,如下,只给出框架,因为每种应用是不一样的,需自己 加入。void run_modbus(void) (switch (usart0_rx_buf1)(/判断主机发来的 modbus功能码是什么case 0x01:/读继电器输出的当前状要加入回传数据break;case 0x03:/ 功能码 03要加入回传数据break;case 0x05:/05 功能码要加入回传数据break;case 0x10:/10 功能码 要加入回传数据break; )以上程序完全依赖一个提供给上位机数据的数组,自己要仔细排列好数据顺序,定义好长度。这里

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论