avr单片机中使用MODBUS协议的方法.doc_第1页
avr单片机中使用MODBUS协议的方法.doc_第2页
avr单片机中使用MODBUS协议的方法.doc_第3页
avr单片机中使用MODBUS协议的方法.doc_第4页
avr单片机中使用MODBUS协议的方法.doc_第5页
已阅读5页,还剩1页未读 继续免费阅读

VIP免费下载

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

文档简介

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=0x01;/启动定时器0,进行超时控制 else usart0_rx_count=0; break; case 2: if (data=0x03)|(data=0x01)|(data=0x05)|(data=0x10)=0)/如果第一位不等于读指令0x03,01,功能码,则清接收缓冲区指针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_buf4=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;/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: 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接收到了指定个数的数组则 usart0_rx_count=0;/接收缓冲区指针清零 usart0_rx_complete=1;/串口0接收完标志 time0_num=0;/串口0的中断次数清零。它是超时控制的依据 TIMSK0=0x00;/收到数据后则停止定时器0不进行超时控制 else usart0_rx_count=0; sei(); /开中断以上中断接收程序可以实现上位机发来的0x03,01,功能码指令,并且可以自动判断上位机发来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

提交评论