用PIC18F4520与发电机上的电表实现MUDBUS通信

2019-11-11来源: 51hei关键字:PIC18F4520  发电机  电表  MUDBUS通信

本软件可分为以下五个部分,第一部分是状态设定和位置监测模块,其中发电车的行车和发电状态的设定是由一个船型开关决定的,当开关闭合时,为发电状态,反之为行车状态,步进电机控制油门的开合,但考虑到异常情况,用一个常开型开关实时监测步进电机是否转动到了极限位置;第二部分为LCD液晶显示,主要将串口通信得到的发电机输出电的频率fre、发电机输出电的电流current以及控制步进电机转动快慢的方波频率mtfre这三个参数实时显示在LCD液晶上。第三部分为单片机与发电机上的仪表之间的Modbus-RTU串口通信,通过软件的实时发送和接收可以得到发电机输出电的频率和电流等参数;第四部分为利用定时中断实现频率可调的方波输出,根据发电机的频率与额定频率50HZ的比较来决定输出方波的频率,而方波的频率之所以可以实时变化的原因是通过改变定时器的初值来实现的,改变了定时器的初值,则改变了定时时间的大小,在每一次溢出中断产生时,置反某一个I/O口的电平,从而实现了频率可调的方波输出;第五部分是步进电机的控制模块,这里需要了解步进电机的工作原理以及驱动原理,这个系统采用专用驱动器驱动步进电机进行转动,驱动器上的输入信号包括脉冲信号、方向信号和使能信号,只要将这三种信号按照要求进行输入,驱动器就可以控制步进电机进行正常转动;


  整体的软件功能是在几个模块函数的相互联系相互调用的情况下实现的,每一个模块有自己的专用函数,在编写程序时,用特殊的专用的函数名来对各个模块的函数进行命名,这样方便查找和修改。


  我觉得大家感兴趣的应该是MODBUS通信,因为用到这种通信的一般是工业仪器仪表,所以我想给大家介绍一下,我在编写这一块时的问题和解决办法。

  

1. Modbus-RTU串口通信模块

通信协议:该模块是整个软件的重点部分,实现发电车上的电力仪表与单片机之间的实时通信,得到系统所要提取的发电机的频率和电流。Modbus协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络和其它设备之间可以通信。发电机上的电力仪表本身规定用的通信协议为RS485接口Modbus-RTU通信协议。当在Modbus网络上通信时,此协议决定了每个控制器必须要知道它们的设备地址,识别按地址发来的消息,决定要产生何种行为。如果需要回应,控制器将生成反馈信息并通过Modbus协议发送。


在Modbus协议中,典型的主设备可以为:主机和可编程仪表。典型的从设备主要为:可编程控制器。在系统中,单片机为主设备,发电机上的电力仪表为从设备。主设备可单独和从设备通信,也能以广播方式和所有从设备通信,如果单独通信,从设备返回一消息作为回应,如果是以广播方式查询的,则从设备们不作任何回应。Modbus协议建立了主设备查询的格式:设备(或广播)地址、功能代码、所有要发送的数据、一错误检测域。从设备回应消息也由Modbus协议构成,包括要确认行动的域、任何要返回的数据、和一错误检测域。如果在消息接收过程中发生一错误,或从设备不能执行其命令,从设备将建立一错误消息并把它作为回应发送出去。


(1)查询  查询消息中的功能代码告之被选中的从设备要执行何种功能。数据段包含了从设备要执行功能的任何附加信息。例如功能代码03是要求从设备读保持寄存器并返回它们的内容。数据段必须包含要告之从设备的信息:从何寄存器开始读及要读的寄存器数量。错误检测域为从设备提供了一种验证消息内容是否正确的方法。

查询数据包结构如下:

从机

地址

功能码

起始寄存器地址高字节

起始寄存器地址低字节

数据字节长度高字节

数据字节长度低字节

CRC校验低字节

CRC检验高字节

(2)回应  如果从设备产生一正常的回应,在回应消息中的功能代码是在查询消息中的功能代码的回应。数据段包括了从设备收集的数据:像寄存器值或状态。如果有错误发生,功能代码将被修改以用于指出回应消息是错误的,同时数据段包含了描述此错误信息的代码。错误检测域允许主设备确认消息内容是否可用。

回应数据包结构:

从机地址

功能码

数据字长

数据段

CRC校验

低字节

CRC检验

高字节

(3)两种传输方式

控制器能设置为两种传输模式:ASCII或RTU中的任何一种在标准的Modbus网络通信。用户选择想要的模式,包括串口通信参数(波特率、校验方式等),在配置每个控制器的时候,在一个Modbus网络上的所有设备都必须选择相同的传输模式和串口参数。相对来说,RTU模式传输效率更高,因此,在当前普遍的生产环境中RTU模式获得了广泛应用,而ASCII模式只作为特殊情况下的可选项。


ASCII模式

当控制器设为在Modbus网络上以ASCII(美国标准信息交换代码)模式通信,一个信息中的每8个比特作为2个ASCII字符传输,如数值63H用ASCII方式时,需发送两个字节,即ASCII“6"(0110110)和ASCII”3“(0110011),ASCII字符占用的位数有7位和8位,国际通用7位为多。这种方式的主要优点是字符发送的时间间隔可达到1秒而不产生错误。


代码系统

· 十六进制,ASCII字符0...9,A...F

· 消息中的每个ASCII字符都是一个十六进制字符组成

每个字节的位

· 1个起始位

· 7个数据位,最小的有效位先发送

· 1个奇偶校验位,无校验则无

1个停止位(有校验时),2个Bit(无校验时)

错误检测域

· LRC(纵向冗长检测)

RTU模式

当控制器设为在Modbus网络上以RTU模式通信,在消息中的每个8Bit字节按照原值传送,不做处理,如63H,RTU将直接发送01100011。这种方式的主要优点是:数据帧传送之间没有间隔,相同波特率下传输数据的密度要比ASCII高,传输速度更快。


代码系统

8位二进制,十六进制数0...9,A...F

消息中的每个8位域都是一或两个十六进制字符组成

每个字节的位

1个起始位

8个数据位,最小的有效位先发送

1个奇偶校验位,无校验则无

1个停止位(有校验时),2个Bit(无校验时)

(4)数据校验方式

CRC校验

CRC域是两个字节,包含一16位的二进制值。它由传输设备计算后加入到消息中。接收设备重新计算收到消息的CRC,并与接收到的CRC域中的值比较,如果两值不同,则有误。


CRC是先调入一值是全“1”的16位寄存器,然后调用一过程将消息中连续的8位字节和当前寄存器中的值进行处理。仅每个字符中的8Bit数据对CRC有效,起始位和停止位以及奇偶校验位均无效。


CRC产生过程中,每个8位字符都单独和寄存器内容相异或(XOR),结果向最低有效位方向移动,最高有效位以0填充。LSB被提取出来检测,如果LSB为1,寄存器单独和预置的值或一下,如果LSB为0,则不进行。整个过程要重复8次。在最后一位(第8位)完成后,下一个8位字节又单独和寄存器的当前值相异或(XOR)。最终寄存器中的值,是消息中所有的字节都执行之后的CRC值。


CRC添加到消息中时,低字节先加入,然后高字节。

CRC-16错误校验程序如下:报文(此处只涉及数据位,不指起始位、停止位和任选的奇偶校验位)被看作是一个连续的二进制,其最高有效位(MSB)首选发送。报文先与X↑16相乘(左移16位),然后看X↑16+X↑15+X↑2+1除,X↑16+X↑15+X↑2+1可以表示为二进制数11000,0000,0000,0101。整数商位忽略不记,16位余数加入该报文(MSB先发送),成为2个CRC校验字节。余数中的1全部初始化,以免所有的零成为一条报文被接收。经上述处理而含有CRC字节的报文,若无错误,到接收设备后再被同一多项式(X↑16+X↑15+X↑2+1)除,会得到一个零余数(接收设备核验这个CRC字节,并将其与被传送的CRC比较)。全部运算以2为模(无进位)。


习惯于成串发送数据的设备会首选送出字符的最右位(LSB-最低有效位)。而在生成CRC情况下,发送首位应是被除数的最高有效位MSB。由于在运算中不用进位,为便于操作起见,计算CRC时设MSB在最右位。生成多项式的位序也必须反过来,以保持一致。多项式的MSB略去不记,因其只对商有影响而不影响余数。


LRC检验

LRC错误校验用于ASCII模式。这个错误校验是一个8位二进制数,可作为2个ASCII十六进制字节传送。把十六进制字符转换成二进制,加上无循环进位的二进制字符和二进制补码结果生成LRC错误校验(参见图)。这个LRC在接收设备进行核验,并与被传送的LRC进行比较,冒号(:)、回车符号(CR)、换行字符(LF)和置入的其他任何非ASCII十六进制字符在运算时忽略不计。


(5)Modbus协议中功能码定义

Modbus功能码在查询数据包和回应数据包里都只占用一个字节,取值范围是1~127。之所以127以上不能使用,是因为Modbus规定当通信出现异常时,功能码+0X80(十进制128)代表异常状态,因此129~255的取值代表异常码。

Modbus相关公共功能码:

代码

名称

操作数量

01

读线圈状态

单个或多个线圈

02

读离散输入状态

单个或多个

03

读保持

[1] [2]
关键字:PIC18F4520  发电机  电表  MUDBUS通信 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic479585.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:PIC16F877A单片机PPM调制的激光通信Proteus仿真及源程序
下一篇:电池容量测试仪电路与源码(PIC16F1938单片机+AD623实现)

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

PIC16F877A单片机PPM调制的激光通信Proteus仿真及源程序
软件:MPLAB X IDE v4.15编译    proteus 8.6仿真.1、仿真电路图;2、发送和接收源程序加注释。请看注释。原理:1)ADC读取并用led显示ADC读数,并通过usart进行输出。2)通过PPM原理进行通讯传输到另外一个单片机,LED显示接收的值。具体请看附件希望大家顶一下。仿真原理图如下(proteus仿真工程文件可到本帖附件中下载) 1、发送模块:读取ADC数值,LED显示10位ADC值。并通过PPM发送。2、接收模块:PPM接收到的数据。LED显示接收的ADC值(10bits)基于PIC单片机的PPM调制激光通信收发器PPM (pulse position
发表于 2019-11-09
PIC16F877A单片机PPM调制的激光通信Proteus仿真及源程序
PIC 16f877a PORTB State Change Interrupt仿真与源码
PORT Change Interrupt PIC 16f877A单片机源程序如下:#define      LED_1     PORTd.b0#define      LED_2     PORTd.b1void interrupt(){if(INTCON.RBIF)  {  INTCON.RBIF = 0;  if(!PORTB.B4)   {    LED_1 = 0;    LED_2 = 1;   } 
发表于 2019-11-09
PIC 16f877a PORTB State Change Interrupt仿真与源码
基于pic16f877a的电压输出并显示
 程序源码如下#include <pic.h>//引脚定义#define din RC7           //显示串行数据输入端#define load RC6          //显示数据锁存端#define clk RC5           //显示时钟输入端#define DecodeMode 0x09     //译码模式#define Intensity 0x0a      //亮度
发表于 2019-11-09
基于pic16f877a的电压输出并显示
用PIC10F202单片机制作两路开关源程序
;*****************************************//************************************  以下为代码区,请勿改动!  *****************************************//=============================================硬件连接示意===============================================////    ___短 _      长   _______ //       |_| |_________|    PIC10F200/202
发表于 2019-11-08
PIC16F877的外围功能模块例程
第5章 PIC16F877的外围功能模块5.1.2 简单应用实例该例用于令与PORTD口相连的8个发光二极管前4个点亮,后4个熄灭。在调试程序前,应使与PORTD口相连的8位拔码开关拔向相应的位置。例5.1 PORTD输出#include        <pic.h>main(){        TRISD=0X00;                        /*TRISD寄存器被赋值,PORTD每一位都为输出
发表于 2019-11-08
TM1640与PIC12F629单片机的结合
TM1640是驱动数码管的专用集成电路,可以直接驱动16位共阴数码管,手册请下载附件。/********************************本程序直接驱动16位共阴数码管,各数码管分别驱动0、1、2、……E、F。*/#include <pic.h>  //PIC12F629__CONFIG(0x3F84); #define clk GPIO0  //时钟信号#define dio GPIO1   //数据/地址数据#define uchar unsigned char#define uint unsigned int       
发表于 2019-11-08
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved