详解RS485通讯程序代码及技术介绍

合集下载

安可信RS485通讯协议(V1.2)

安可信RS485通讯协议(V1.2)

HTX48501操作手册该产品的功能是负责把控制器的信号转换为标准的modbus协议信号。

一、硬件接口该产品使用RS485接口与modbus协议的主站进行通信。

RS485接口采用3线进行通信,分别为A,B,PGND。

二、软件接口使用modbus标准协议对可燃气体报警系统的信号进行解析。

使用到modbus协议的功能代码为1,2,3,4,5。

三、Modbus协议说明1.传输协议modbus传输模式:RTU波特率:9,600bps传输字节特性:起始位:1位数据位(最小位优先):8位奇偶校验:奇校验停止位:1位错误校验:CRC校验2.协议解析该协议支持两种数据访问模式,分别为位地址和寄存器地址(16位)。

a.地址表示该从modbus设备的通信地址(该地址的范围为1~247),该地址由控制器进行设置。

b.c.数据访问地址数据访问地址:就是访问的寄存器起始地址。

各种类型数据的具体起始访问地址(十进制表示)如下:x000:探测器的浓度x064:探测器的状态x128:模块的开关状态x168:控制器状态控制器中最多允许接入128个探测器,64个外部模块,4个内部模块。

地址以十进制数进行表示,千位为X,表示x的值可以为1~9。

其它位数的值固定。

数据访问地址的增量为2,比如:x000表示1号探测器,x001也表示1号探测器,x002和x003表示2号探测器。

(即访问地址除以2然后加1就是具体设备的编号)。

d.数据数据:通信发送要处理的实际数据。

注意:应答数据不能够超过255个字节。

e.CRC校验Modbus协议采用16位的CRC校验。

3.设备状态说明探测器状态如下:0:探头短路1:探头断线2:探头老化3:其它故障4:未标定5:零点变化7:无响应9:探头自检a:正常d:预报警e:低限报警f:高限报警4.modbus消息例子a.读取模块的开关状态实例1:发送:表示1,2,3,4号模块都断开。

实例2:应答:表示模块2闭合,内部模块3断开,模块4~6闭合。

rs485通信协议介绍

rs485通信协议介绍

rs485通信协议介绍附录:RS485串⾏通讯协议1 主要性能本变频器通过内置的RS485标准接⼝,能与个⼈计算机、PLC 或同系列的变频器等连接,进⾏主从式、异步半双⼯串⾏通信。

其主要性能参见下表:项⽬规范适⽤机型 ALPHA3000系列变频器物理级EIA RS485 传输线屏蔽双绞线配线最长长度 500⽶连接台数主机⼀台,从机31台传输速度19200bps,9600bps,4800bps,2400bps,1200bps,600bps,300bps 数据交换⽅式异步串⾏、半双⼯传送协议点对点或⼴播字长 11位停⽌位长度 1位帧长 14字节固定奇偶校验奇校验出错检查⽅式异或校验2硬件连接 2.1硬件联接如下图:图 1 多台变频器⽤主机控制连接⽰意图图中的MASTER (主机)是ALPHA3000变频器、PC 机或可编程控制器(PLC ),图中的SLAVE (从机,在虚线框内)是变频器。

变频器做为主机,只要将从机的RS485端⼦和主机的RS485同名端⼦相联接即可;如果⽤PC 机或PLC 做为主机,则要在主机和总线之间增加⼀个RS485的转接器。

RS458串⾏总线接⼝最多可连接31台变频器做从机,每⼀个从机变频器都有⼀个唯⼀的号码(ID ),主机依靠ID 来识别每⼀台从机。

2.2 RS485转换器RS485转换器采⽤DB9/DB9外形,带孔的⼀端为RS232,带针的⼀端为RS485。

转换器外带接线转换头把RS485端的DB9接线转换为螺丝接线柱,便于通讯线缆的安装和拆卸。

接线转换头上“A+”为485收/发正端,“ B-”为485收/发负端,“GND”为485地线。

RS485接⼝组成半双⼯⽹络,⼀般只需⼆根连线,为获得良好的抗噪声⼲扰性和较长的传输距离,建议采⽤屏蔽双绞线传输。

3通讯协议3.1概述3.1.1通讯⽅式采⽤USS协议。

主机和从机之间⽤轮询的⽅式来进⾏通讯。

由主机启动每⼀次通信,主机向从机变频器发送任务报⽂,从机接到主机的任务命令后返回响应报⽂并执⾏相应动作。

RS485通信协议

RS485通信协议

RS485通信协议协议名称:RS485通信协议一、引言RS485通信协议是一种用于在多个设备之间进行数据传输和通信的标准协议。

本协议旨在规范RS485通信的数据格式、传输方式和通信协议,以确保设备之间的可靠通信和数据交换。

二、范围本协议适用于使用RS485通信接口的各种设备,包括但不限于工业自动化设备、仪器仪表、数据采集设备等。

三、术语定义1. RS485通信:使用差分信号进行数据传输的半双工通信方式。

2. 主设备:发起通信请求的设备。

3. 从设备:响应通信请求的设备。

4. 数据帧:包含数据信息的通信单元。

5. 起始位:数据帧的起始标识位。

6. 终止位:数据帧的结束标识位。

7. 奇偶校验:用于检测数据传输中的错误的校验机制。

8. 波特率:数据传输速率,以每秒传输的比特数表示。

四、通信协议1. 物理层RS485通信使用差分信号进行数据传输,其中A线和B线分别代表正向和反向信号线。

通信设备应符合RS485标准的物理层要求,包括信号电平、线路阻抗等。

2. 数据帧格式RS485通信使用数据帧进行数据传输。

数据帧格式如下:起始位 | 数据位 | 奇偶校验位 | 停止位起始位:一个字节的起始标识位,用于标识数据帧的开始。

数据位:包含要传输的数据信息,可以是一个或多个字节。

奇偶校验位:用于检测数据传输中的错误,可以选择奇校验、偶校验或无校验。

停止位:一个字节的停止标识位,用于标识数据帧的结束。

3. 通信流程RS485通信的通信流程如下:主设备发送请求帧 -> 从设备接收请求帧并解析 -> 从设备执行请求操作 -> 从设备发送响应帧 -> 主设备接收响应帧并解析4. 数据传输RS485通信使用半双工通信方式,即同一时间只能有一方发送数据。

通信设备应在发送数据前先检测总线是否空闲,以避免冲突。

5. 错误处理RS485通信中可能发生的错误包括数据传输错误、通信超时等。

通信设备应具备错误处理机制,能够检测和处理这些错误,例如重新发送数据、重置通信连接等。

详解RS485通讯程序代码及技术介绍

详解RS485通讯程序代码及技术介绍
void UART_Puts(unsigned char *Str) { if(*Str) //字符串结束 {
} } //主函数 void main() { DDRD|=BIT(PD2); //PORTD|=BIT(PD2); USART_Init(); //UART_Puts("\r\n 你发送的字符串是:");//发送字符串 PORTD&=~BIT(PD2); DDRD|=BIT(PD2); while(1) { if(RX_Flag)
{
PORTD|=BIT(PD2);
//UART_Puts();
USART_Send('1');
//USART_Send(RX_Buffer);
RX_Flag=0;
PORTD&=~BIT(PD2);
PORTD|=BIT(PD2);
//UART_Puts();
USART_Send('2');
//USART_Send(RX_Buffer);
HART 网络:HART 是由现在的艾默生提出一个过度性总线标准,他主要是在 4~20 毫安电流信号上面叠加数字信号,物理层采用 BELL202 频移键控技术,以 实现部分智能仪表的功能,但此协议不是一个真正意义上开放的标准,要加入他 的基金会才能拿到协议,加入基金会要一部分的费用。技术主要被国外几家大公 司垄断,近两年国内也有公司再做,但还没有达到国外公司的水平。现在有很大 一部分的智能仪表都带有 HART 圆卡,都具备 HART 通讯功能。但从国内来看还没 有真正利用其这部分功能,最多只是利用手操器对其进行参数设定,没有发挥出 HART 智能仪表应有的功能,没有联网进行设备监控。从长远来看由于 HART 通信 速率低组网困难等原因,HART 仪表的采购量会程下滑趋势,但由于 HART 仪表已 经有十多年的历史现在在装数量非常的大,对于一些系统集成商来说还有很大的 可利用空间。

RS485通信原理图及程序实例详解

RS485通信原理图及程序实例详解

RS485通信原理图及程序实例详解RS232 标准是诞⽣于 RS485 之前的,但是 RS232 有⼏处不⾜的地⽅:接⼝的信号电平值较⾼,达到⼗⼏ V,使⽤不当容易损坏接⼝芯⽚,电平标准也与TTL 电平不兼容。

传输速率有局限,不可以过⾼,⼀般到⼀两百千⽐特每秒(Kb/s)就到极限了。

接⼝使⽤信号线和 GND 与其它设备形成共地模式的通信,这种共地模式传输容易产⽣⼲扰,并且抗⼲扰性能也⽐较弱。

传输距离有限,最多只能通信⼏⼗⽶。

通信的时候只能两点之间进⾏通信,不能够实现多机联⽹通信。

针对 RS232 接⼝的不⾜,就不断出现了⼀些新的接⼝标准,RS485 就是其中之⼀,它具备以下的特点:采⽤差分信号。

我们在讲 A/D 的时候,讲过差分信号输⼊的概念,同时也介绍了差分输⼊的好处,最⼤的优势是可以抑制共模⼲扰。

尤其当⼯业现场环境⽐较复杂,⼲扰⽐较多时,采⽤差分⽅式可以有效的提⾼通信可靠性。

RS485 采⽤两根通信线,通常⽤ A 和 B 或者 D+和D-来表⽰。

逻辑“1”以两线之间的电压差为+(0.2~6)V 表⽰,逻辑“0”以两线间的电压差为-(0.2~6)V 来表⽰,是⼀种典型的差分通信。

RS485 通信速率快,最⼤传输速度可以达到 10Mb/s 以上。

RS485 内部的物理结构,采⽤的是平衡驱动器和差分接收器的组合,抗⼲扰能⼒也⼤⼤增加。

传输距离最远可以达到 1200 ⽶左右,但是它的传输速率和传输距离是成反⽐的,只有在 100Kb/s 以下的传输速度,才能达到最⼤的通信距离,如果需要传输更远距离可以使⽤中继。

可以在总线上进⾏联⽹实现多机通信,总线上允许挂多个收发器,从现有的 RS485芯⽚来看,有可以挂 32、64、128、256 等不同个设备的驱动器。

RS485 的接⼝⾮常简单,与 RS232 所使⽤的 MAX232 是类似的,只需要⼀个 RS485转换器,就可以直接与单⽚机的 UART 串⼝连接起来,并且使⽤完全相同的异步串⾏通信协议。

rs485通讯

rs485通讯

RS485通讯1. 引言RS485是一种串行通信协议,用于在多个设备之间进行双向数据传输。

它是一种高性能的通讯协议,常用于工业自动化、仪器仪表、门禁系统等领域。

本文将介绍RS485通讯的基本原理、使用方法以及常见的应用场景。

2. 基本原理RS485通讯使用差分信号传输,可以抵抗电磁干扰和噪声。

它采用两条相对独立的传输线(A线和B线),通过不同的电平表示逻辑1或逻辑0。

其中,逻辑1对应线A为高电平,线B为低电平;逻辑0对应线A为低电平,线B为高电平。

通过这种方式,数据可以在多个设备之间进行可靠的传输。

3. 硬件连接在使用RS485通讯时,需要将所有设备连接到一个共享的总线上。

每个设备都需要两条连接线(A线和B线)以及一个共享的地线。

通常,可以使用终端电阻来匹配总线阻抗并提高信号质量。

4. 传输方式RS485通讯可以采用两种传输方式:全双工和半双工。

4.1 全双工通讯在全双工通讯中,设备可以同时发送和接收数据。

发送数据的设备需要将数据发送到总线上,并通过差分信号传输给其他设备。

同时,接收数据的设备可以监听总线上的数据并将其解析。

4.2 半双工通讯在半双工通讯中,设备的发送和接收操作是交替进行的。

设备在发送数据时,需要先将总线设置为发送模式,并将数据发送到总线上。

其他设备在接收数据时,将总线设置为接收模式,并监听数据。

5. 通讯协议RS485通讯可以使用多种协议进行数据交换,常见的有MODBUS、DMX512等。

这些协议定义了数据的传输格式、通讯方式和功能码等。

5.1 MODBUS协议MODBUS是一种常用的通讯协议,适用于工业自动化领域。

它定义了数据的传输格式,并提供了读写寄存器等功能。

MODBUS协议支持点对点和多点通讯。

5.2 DMX512协议DMX512是一种用于舞台灯光控制的通讯协议。

它定义了数据的传输格式和通讯方式。

DMX512通讯一般采用全双工方式进行。

6. 应用场景RS485通讯在许多领域都有广泛的应用。

485端口使用说明

485端口使用说明

用RS485端口控制TVF2000使用说明:一、硬件连接:1.RS485/RS485:(1)终端设备:将J2用终端方式短接;(2)非终端设备:将J2用非终端方式短接;(3)A、B、AGND对接;(4)如果使用屏蔽线,SCR对接。

2.RS485/RS232(PC机):(1)用RS485/RS232转换器;(2)PC机串口与转换器RS232口连接;(3)TVF2000的CN1与转换器的RS485口的A、B、AGND连接。

二、用MODBUS与TVF2000通讯(RTU方式):1.TVF2000键盘设置:a)键盘菜单设置说明:i.1001=10:外端子1用通讯控制;ii.5005=2:标准MODBUS通讯方式;iii.5201=1-247:从机号(缺省=1);iv.5202=5:通讯速度为9600bps(缺省=5);v.5203=0:无效验(缺省=0);vi.其它=缺省值;b)通讯缺省设置:i.通讯从机号:1;ii.通讯速率:9600 BPS;iii.效验:无;iv.停止位:2;v.数据位:8;c)键盘具体操作:i.9952 = 1:参数初始化;ii.1001 = 10;iii.5005 = 2;这样设置后,就可以与TVF2000通讯了。

2.TVF2000使用的MODBUS命令:a)读存储寄存器:03命令;b)写单个寄存器:06命令;c)写多个寄存器:16命令;3.MODBUS单寄存器写入命令说明(其它说明见附录):a)主机发送:i.[地址]:从机地址1-247;ii.[命令]:06,单寄存器写入命令;iii.[寄存器地址_H]:寄存器地址高8位;iv.[寄存器地址_L]:寄存器地址低8位;v.[数据_H]:写入数据高8位;vi.[数据_L]:写入数据低8位;vii.[CRC_H]:CRC效验高8位;viii.[CRC_L]:CRC效验低8位;b)从机返回(正常):i.[地址]:从机地址1-247(相同地址);ii.[命令]:06,单寄存器写入命令;iii.[寄存器地址H]:寄存器地址高8位;iv.[寄存器地址L]:寄存器地址低8位;v.[数据_H]:写入数据高8位;vi.[数据_L]:写入数据低8位;vii.[CRC_H]:CRC效验高8位;viii.[CRC_L]:CRC效验低8位;c)通讯具体操作(菜单1102=7为例):i.主机发送:[01][06][04][4E][00][07][CRC_H][CRC_L];ii.从机返回(正常):[01][06][04][4E][00][07][CRC_H][CRC_L];4.用通讯命令设置菜单值(调速前必须设置):i.MODBUS规定:寄存器都以4开始(内置);ii.1102=7;外部1有效(也可用键盘设置);iii.1103=8;由串行通讯给定(也可用键盘设置);iv.0002=初始频率;如果不设置,为菜单1104的值;v.0001=0x06;命令寄存器:0001;vi.0001=0x0f;vii.0001=0x2f;启动;viii.0001=0x6f;到达设定频率;5.用通讯命令调速(给定寄存器1:0002):i.0002=0-20000;调速:0对应1104的值,20000对应1105的值;ii.通过03命令读取状态寄存器(0004)的值;iii.通过03命令读取保持寄存器(0005、0006)的值;iv.用通讯命令停车:0001 = 0x06;6如下:7. 给定寄存器1:0002(MODBUS 为40002)说明如下:i. 输出频率与给定值成正比例;ii. 输出频率=(0002的值)*(1105的值)/20000;8. 状态寄存器:0004(MODBUS 为40004)说明如下:9.保持寄存器:0005(MODBUS为40005):实际输出频率(单位:Hz);10.保持寄存器:0006(MODBUS为40006):实际输出电流(单位:0.1A);11.状态寄存器、保持寄存器均为只读;12.如果想保存通讯设置,必须用键盘设置菜单1607=1。

PLC资料:三菱PLC RS485通讯使用教程(带示例)

PLC资料:三菱PLC RS485通讯使用教程(带示例)

通信
一、联机方式
自动化生产线各工作站中PLC之间通过RS-485串行通信的方式实现互连,构成分布式的控制系统。

二、N:N网络功能
N:N网络功能,就是在最多8台FX可编程控制器之间,通过RS-485通信连接,进行软元件相互连接。

1)根据要链接的点数,有3种模式可以选择。

2)数据的链接是在最多8台FX可编程控制器之间自动更新。

3)总延长距离最大可达500m。

三、链接模式及链接点数
四、N:N网络接线图
五、N:N网络中使用的软元件如下:
1.N:N网络设定用的软元件
是用于设定N:N网络的软元件。

使用N:N网络时,必须设定下列的软元件。

2.判断N:N网络错误用的元件
用于判断N:N网络错误。

请将链接错误输出到外部,并在顺控程序的互锁等中使用。

3. 链接软元件
是用于发送接收各可编程控制器之间的信息的软元件。

根据在相应站号设定中设定的站号,以及在刷新范围设
定中设定的模式不同,使用的软元件编号及点数也有所不同。

1)模式0时
2) 模式1时
3) 模式2时
三菱PLC 485通讯示例(2个PLC)
题目:
按下SB1(0#PLC 的X0),灯L1(1#PLC 的Y0)亮。

按下SB2(1#PLC 的X1),灯L2(0#PLC 的Y1)亮。

通讯线连接方式:
主站程序:
从站程序:。

RS485通信示例程序

RS485通信示例程序

RS485通信示例程序看程序时请配合芯片资料一起看,公布源码不是为了抄袭,而是为了相互学习,如果有不对的地方还请指出来,谢谢!/*===================================================== ===程序说明:PC端通过RS232-RS485芯片转换后再经过一个RS485收发芯片MAX485连接单片机的RX和TX(RO-RX,DI-TX)的通信示例程序控制发送和接收的引脚为P2.7,使用时注意正确连接!作者:绘天地点:成都信息工程学院====================================================== ==*/#include <reg52.h>#include "com_communication.h"sbit SHRL=P2^7;/*高电平发送,低电平接收*/void main(){int c;UartInit();SHRL=0;/*保持为发送状态*/while(1){if ( RI ) //如果收到数据{RI = 0; //清除接收标志c = SBUF; //读取收到的数据SHRL=1;UartSendChar(c); //回送收到的数据SHRL=0;}}}所调用的头文件:#ifndef _com_H_#define _com_H_//定义波特率(取值1200、2400、4800、9600、19200等)#define BaudRate 19200L/*********************************************************************** ********函数:UartInit()功能:串行口初始化************************************************************************ *******/void UartInit(){SCON = 0x50; //串口方式1(8位UART),允许接收PCON |= 0x80; //波特率加倍TMOD &= 0x0F; //设置T1为8位自动重装定时器,用于产生波特率TMOD |= 0x20;TH1 = TL1 = 256 - (11059200L / 12) / (16 * BaudRate); //设置T1初值TR1 = 1; //启动T1}/*********************************************************************** ********函数:UartSendChar()功能:通过串行口发送单个字节参数:c是被发送的字节数据,取值0x00~0xFF************************************************************************ *******/void UartSendChar(char c){SBUF = c; //数据写入SBUF,同时启动硬件发送过程while ( !TI ); //等待发送完毕TI = 0; //清除发送标志}#endif。

RS485通讯

RS485通讯

精通RS485通讯系列教程一、通讯基础知识1.1什么是通讯要搞清楚RS485通讯我们要先搞明白什么是通讯,通讯就是两个设备之间0、1代码的传递,0-低电平1-高电平。

举例:A设备向B设备传递数据,首先A设备和B设备之间必须通过电缆连接(硬件连接)。

如果A设备要向B设备发送101010这样一串代码,那么A设备就要在他的通讯端口产生如下图所示的高低电平的组合,通过电缆这个介质B设备的通讯端口就会接收到A设备发出高低电平的组合,同时就会将接收到的高低电平组合翻译成101010,这就完成了A设备向B设备数据的传递,B 设备向A设备数据传递也是同样的道理。

与通讯有个的概念。

【全双工与半双工】全双工是通讯端口在发送数据的同时可以接收数据。

而半双工指的是同一时刻通讯端口要么只能发送数据,要么只能接收数据。

举例:全双工-打电话时双方都可以说。

半双工:对讲机-同一时刻只能一个人说另一个人听。

【通讯速率】通讯速率也叫通讯波特率是1S内通讯端口发送01代码(或者说是高低电平)的数量。

举例:我们说通讯速率是9.6kbps,就表示通讯端口每秒发送9600个bit的数据,也就是每秒可以产生9600个高低电平(注意:是高低电平总共加起来9600个)。

【主从通讯】是在一个通讯网络中一个站点是主站,其他站点作为从站。

主站和从站之间可以直接进行数据的传递,但是从站与从站之间不能直接进行数据的传递。

如果需要从站之间交换数据也必须要通过主站进行转发。

如下图所示1.2、485通讯定义明白了通讯的基本概念后再理解485通讯就相对容易了,下面我们从通讯介质、通讯方式、通讯类型、物理层四个方面来介绍485通讯。

通讯介质:屏蔽双绞线,也就是我们通常用的带有屏蔽层的两心电缆如下图所示。

通讯方式:半双工通讯类型:主从通讯物理层:9针接口,需要注意的是通常情况下485通讯的9针接口,只需要将两芯电缆接到3号脚和8号脚上,3是信号“﹢”,8是信号“-”。

485通讯协议程序怎么写(51单片机的485通信程序案例)

485通讯协议程序怎么写(51单片机的485通信程序案例)

485通讯协议程序怎么写(51单片机的485通信程序案例)
RS-485总线接口是一种常用的串口,具有网络连接方便、抗干扰性能好、传输距离远等优点。

RS-485收发器采用平衡发送和差分接收,因此具有抑制共模干扰的能力,加上收发器具有高的灵敏度,能检测到低达200mv的电压,可靠通信的传输距离可达数千米。

使用RS-485总线组网,只需一对双绞线就可实现多系统联网构成分布式系统、设备简单、价格低廉、通信距离长。

51单片机的485通信程序
#ifndef __485_C__ #define __485_C__
#include 《reg51.h》
#include 《string.h》
#define unsigned char uchar
#define unsigned int uint
/* 通信命令*/
#define __ACTIVE_ 0x01 // 主机询问从机是否存在
#define __GETDATA_ 0x02 // 主机发送读设备请求
#define __OK_ 0x03 // 从机应答
#define __STATUS_ 0x04 // 从机发送设备状态信息
#define __MAXSIZE 0x08 // 缓冲区长度
#define __ERRLEN 12 // 任何通信帧长度超过12则表示出错
uchar dbuf[__MAXSIZE]; // 该缓冲区用于保存设备状态信息
uchar dev; // 该字节用于保存本机设备号
sbit M_DE = P1。

485通信讲解(附案例)解析

485通信讲解(附案例)解析

数据帧格式示意图
起始字节 从机地址 (字节) (字节)
用户数据
异或校验 (字节)
76543210
单机地址或群组地址 =0:单机地址 =1:群组地址
RS485通讯协议
命令字(响应字)+功能码号(2个字节,16BIT)
数据含义:主机发送的命令或从机对命令的应答。
功能码组号范围0~16(BIT8~BIT11),功能码的范围0~99(BIT0~BIT7),参见 TD3000
响应字定义
控制字 (位) 值
bit5
1
含义
停机2状态
功能描述
变频器执行停机2命令,处于停机状态
0
非停机2状态
bit6
1
控制禁止状态
因停机1或停机2或变频器故障或异常命令使变
频器停机的状态,需控制字恢复到准备运行状态
0
控制允许状态
使其复位
bit9
1 上位机控制
0 本地控制方式
bit10
1
到达设定频率/
数据帧格式示意图
起始字节 (字节)
从机地址 (字节)
功能码操作 命令/响应 (字节)
功能码号 (字节)
功能码设 定/实际值
(字)
控制/状 态字
(字)
主设定/ 实际值
异或校验
(字) (字节)
1514 13 12 1110 9 8 7 6 5 4 3 2 1 0
功能码操作错误代码 功能码设定/实际值
RS485通讯协议
帧头 帧头:一个字节 帧头是主机发布命令或从机回应主机响应的第一个字节,不论是主机还是从 机,都在收到该字节后开始记录有效数据。 为确保能准确识别报文头,要求两个通信帧之间保持2个字节传输时间以上的 总线空闲时间。

stm32 rs485解析程序实例

stm32 rs485解析程序实例

stm32 rs485解析程序实例在STM32中实现RS485通信,你需要使用UART(通用异步收发器)硬件模块,并配置其RS485模式。

下面是一个简单的RS485解析程序实例,以STM32 HAL库为例。

首先,你需要配置UART并开启RS485模式。

以下是一个示例:```cvoid MX_RS485_UART_Init(void){= USART2;= 115200;= UART_WORDLENGTH_8B;= UART_STOPBITS_1;= UART_PARITY_NONE;= UART_MODE_TX_RX;= UART_HWCONTROL_NONE;= UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart2) != HAL_OK){Error_Handler();}// Enable RS485 mode__HAL_UART_ENABLE_IT(&huart2, UART_IT_REACK); __HAL_UART_DISABLE_IT(&huart2, UART_IT_TEACK); __HAL_UART_ENABLE_IT(&huart2, UART_IT_RWUID); __HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE); __HAL_UART_ENABLE(&huart2);}```然后,你可以在中断服务程序中处理接收到的数据:```cvoid USART2_IRQHandler(void){HAL_UART_IRQHandler(&huart2);}```在`HAL_UART_IRQHandler`函数中,你可以处理接收到的数据:```cvoid HAL_UART_IRQHandler(UART_HandleTypeDef huart){if(__HAL_UART_GET_FLAG(huart, UART_FLAG_REACK) != RESET) // RS485 Receiver Mode ACK reception{__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_REACK);// Handle received data here...}}```以上代码只是一个基本的示例,你可能需要根据你的实际需求进行修改。

一文秒懂 自动化485通讯

一文秒懂 自动化485通讯

一文秒懂自动化485通讯相信不少化工人,一听见通讯就闻风丧胆,一看到通讯的代码进制就一个头俩个大。

一听见别人聊通讯就会觉得很厉害,感觉他是大神。

但是小编要告诉你,其实通讯并没有什么难的。

那么怎么去理解这些呢,突然看到下面这些代码是不是感觉一脸懵逼下面先简单的讲个小故事:某一天,你决定去上门拜访丈母娘清楚了丈母娘家的地址是在XX省XXX镇上(主地址),然后有多种交通方式可以达到,最后选择了自己开车走高速(功能码,功能方式),到达镇上之后打了个电话问清楚了丈母娘家在哪个位置门牌号为XXX(寄存器地址),了解了她们家里有几口人,有几个亲戚(数据个数),然后到了之后再跟女朋友确认下免得认错人(CRC校验)。

当然丈母娘看到你的的一瞬间肯定会想:下面我们以pH控制器485通讯举例:发送TX:01 03 00 00 00 01 84 0A01:仪器的485通讯地址(地址)单独唯一的一个03:通讯过程中读数据的功能(功能码)唯一的一种读的方式00 00:存储PH值的一个地方(寄存器地址),不同的参数对应的地址也不一样哦00 01:需要读取PH的个数为一个(数据长度或者数据个数)不同数据对应的长度也不相同哦84 0A:确认数据的校验方式可利用工具计算(校验码)返回RX:01 03 02 02 DD 79 7D01,03不多说了,和上面发送TX是一样的02:返回来的读取到的pH数据字节为2个(分析的就是这个之后的字节哦)02 DD:所返回的pH值数据十六进制转换成十进制显示(自带两位小数点)79 7D:CRC校验码(自动返回)是不是跟仪器显示的一样呢?答案是一样的!PH=7.33当然基本参数都会提供只要你想到第一次拜访丈母娘的情景,就能明白通讯的基本格式。

STM32的RS485通信

STM32的RS485通信

STM32的RS485通信1.简介与CAN类似,RS-485是一种工业控制环境中常用的通讯块议,它具有抗干扰能力强、传输距离远的特点。

RS-485通讯协议由RS-232协议改进而来,协议层不变,只是改进了物理层,因而保留了串口通讯协议应用简单的特点。

用的是SP3485芯片:通信的时候,A端口连接另一个设备的A端口,B端口连接B端口,不是交叉相连。

最多能够连接128个设备,所以在某种情况下可以取代网络,RE引脚用来控制通讯数据的方向,要么进行接收,要么进行发送。

本质还是串口通信RS485_RE为高电平的时候,DE为高电平有效,允许发送数据RS485_RE为低电平的时候,RE为低电平有效,允许接收数据所以当你要发送数据的时候,需要将与RE连接的引脚置为高电平、2.编码所以我们大致可以得到一个程序模板:发送数据函数void rs485_send(uint8_t *pbuf,uint32_t len) { //设置RS458为发送模式,将所连引脚设置高电平输出PGout(2)=1; //调用串口2的库函数发送数据... //延时100us delay_us(100); //设置RS485为接收模式PGout(2)=0;} 接收函数,使用中断接收void USART2_IRQHandler(void) { uint8_t data=0; if(USART2_GetITStatus(USART2,USART_IT_RXNE)!=RESET) data = USART2_ReceiveData(USART2);}下面是演示代码,供参考#include "stm32f4xx.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_usart.h"//模式控制#define RS485_TX_ENPGout(8)//485模式控制.0,接收;1,发送. static GPIO_InitTypeDef GPIO_InitStructure; static USART_InitTypeDef USART_InitStructure; static NVIC_InitTypeDef NVIC_InitStructure;void USART1_Init(uint32_t baud) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟//串口1对应引脚复用映射GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);//GPIOA9复用为USART1 GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);//GPIOA10复用为USART1 //USART1端口配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉GPIO_Init(GPIOA, //初始化PA9,PA10//USART1 初始化设置USART_ART_BaudRate = baud;//波特率设置USART_ART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_ART_StopBits = USART_StopBits_1;//一个停止位USART_ART_Parity = USART_Parity_No;//无奇偶校验位USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_Init(USART1, //初始化串口 1 USART_Cmd(USART1, ENABLE); //使能串口 1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断//Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;//子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(//根据指定的参数初始化VIC寄存器}void USART1_WriteBytes(uint8_t *pbuf,uint32_t len) { uint32_t i =0; for(i=0; iDRUSART1_WriteBytes( } }。

rs485协议的编程方法

rs485协议的编程方法

rs485协议的编程方法1.什么是r s485协议?r s485协议是一种常用的串行通信协议,用于在多个设备之间进行数据传输。

它具有高速传输、长距离通信和多节点连接的特点,广泛应用于工业自动化领域。

本文将介绍如何使用rs485协议进行编程。

2.硬件准备在使用r s485协议进行编程之前,需要进行一些硬件准备工作。

主要包括:R S485转U A R T模块-:用于将r s485信号转换为与M CU或计算机通信的UA RT信号。

M C U或计算机-:用于与rs485转UA R T模块进行数据交互。

外设设备-:如传感器、执行器等,通过r s485协议与M CU或计算机进行通信。

3.软件编程3.1选择编程语言在进行r s485协议的编程时,可以选择多种编程语言,如C语言、P y th on等。

根据实际需求和项目环境选择合适的编程语言。

3.2使用串口库使用rs485协议进行通信时,需要通过串口与外设设备进行数据交互。

因此,需要在编程中使用相应的串口库来实现串口的打开、配置和读写操作。

3.3配置串口参数在使用r s485协议进行通信之前,需要对串口进行正确的配置。

主要包括波特率、数据位、停止位和校验位等参数的设置。

这些参数应与外设设备的参数相匹配,否则通信将无法正常进行。

3.4发送和接收数据使用rs485协议进行通信时,需要明确发送和接收数据的格式。

根据外设设备的通信协议,编写相应的数据发送和接收函数。

在发送数据时,需要将数据按照协议格式进行打包;在接收数据时,需要根据协议格式解析接收到的数据。

3.5错误处理在r s485通信中,可能会出现各种错误情况,如传输错误、超时等。

在编程过程中,需要预先考虑这些错误情况,并编写相应的错误处理代码,保证程序的稳定性和可靠性。

4.实例演示以下是一个使用C语言编写的简单示例,演示了如何使用r s485协议进行通信:#i nc lu de<s td io.h>#i nc lu de<s td in t.h>#i nc lu de<s td li b.h>#i nc lu de<u ni st d.h>#i nc lu de<f cn tl.h>#i nc lu de<t er mi os.h>#d ef in eR S485_D EVI C E"/d ev/t ty US B0"v o id in it_r s485(in t fd){s t ru ct te rm io st io;t c ge ta tt r(fd,&tio);t i o.c_cf la g|=C REA D|C LO CA L;t i o.c_cf la g&=~CSI Z E;t i o.c_cf la g|=C S8;t i o.c_cf la g&=~PAR E NB;t i o.c_cf la g&=~CST O PB;t i o.c_cc[V MI N]=0;t i o.c_cc[V TI ME]=10;t c se ta tt r(fd,T CSA N OW,&ti o);}i n tm ai n(){i n tf d=op en(R S485_D EV IC E,O_RD WR|O_N OC TT Y);i f(f d==-1){p e rr or("op en");e x it(1);}i n it_r s485(f d);u n si gn ed ch ar da ta[]={0x01,0x02,0x03};w r it e(fd,d at a,siz e of(d at a));u n si gn ed ch ar bu f[10];s s iz e_tn=r ea d(fd,b uf,s iz eo f(bu f));i f(n>0){//解析接收到的数据f o r(in ti=0;i<n;i++){p r in tf("%02x",buf[i]);}p r in tf("\n");}c l os e(fd);r e tu rn0;}5.总结本文介绍了使用r s485协议进行编程的方法。

485通信讲解(附案例)

485通信讲解(附案例)

帧头 帧头:一个字节 帧头是主机发布命令或从机回应主机响应的第一个字节,不论是主机还是从 机,都在收到该字节后开始记录有效数据。 为确保能准确识别报文头,要求两个通信帧之间保持2个字节传输时间以上的总 线空闲时间。
数据帧格式示意图
起始字节 (字节)
从机地址 (字节)
用户数据
异或校验 (字节)
76543210
速度
0
未到达设定频率
/速度
RS485通讯协议
响应字位定义
控制字 (位)

bit11
1
含义 变频器运行状态
功能描述
0
变频器停止状态
bit15
1
变频器接受出错
0
变频器接收正确 本位表示来自控制器的通讯帧经
校验出错,控制器应再次发送该
bit0
预留
帧。
bit7~8
预留
bit12~1 4,
预留
RS485通讯协议
1、以50Hz运行2#变频器。(此例需要将变频器频率设定成F0.03=6)
功能码号 功能码组号 命 令 /响 应 字 ( 码 )
RS485通讯协议
命令字(码)
命令字(码)
功能描述
0 无任务 1 请求读取功能码参数数据
2 请求更改功能码参数数据 14 请求更改功能码参数并存储至EEPROM
3~13,15 预留
响应字(码)
响应字(码)
内容描述
0 无响应
1 功能码参数操作正确(读取或更改)
先发高字节,再发低字节的原则
数据帧格式示意图
起始字节 (字节)
从机地址 (字节)
功能码操作 命 令 /响 应 (字节)
功能码号 (字节)

rs485通信程序

rs485通信程序

#ifndef __485_C__#define __485_C__#include <reg51.h>#include <string.h>#define unsigned char uchar#define unsigned int uint/* 通信命令 */#define __ACTIVE_ 0x01 // 主机询问从机是否存在#define __GETDATA_ 0x02 // 主机发送读设备请求#define __OK_ 0x03 // 从机应答#define __STATUS_ 0x04 // 从机发送设备状态信息#define __MAXSIZE 0x08 // 缓冲区长度#define __ERRLEN 12 // 任何通信帧长度超过12则表示出错uchar dbuf[__MAXSIZE]; // 该缓冲区用于保存设备状态信息uchar dev; // 该字节用于保存本机设备号sbit M_DE = P1^0; // 驱动器使能,1有效sbit M_RE = P1^1; // 接收器使能,0有效void get_status(); // 调用该函数获得设备状态信息,函数代码未给出void send_data(uchar type, uchar len, uchar *buf); // 发送数据帧bit recv_cmd(uchar *type); // 接收主机命令,主机请求仅包含命令信息void send_byte(uchar da); // 该函数发送一帧数据中的一个字节,由send_data()函数调用void main(){uchar type;uchar len;/* 系统初始化 */P1 = 0xff; // 读取本机设备号dev = (P1>>2);TMOD = 0x20; // 定时器T1使用工作方式2TH1 = 250; // 设置初值TL1 = 250;TR1 = 1; // 开始计时PCON = 0x80; // SMOD = 1SCON = 0x50; // 工作方式1,波特率9600bps,允许接收ES = 0; // 关闭串口中断IT0 = 0; // 外部中断0使用电平触发模式EX0 = 1; // 开启外部中断0EA = 1; // 开启中断/* 主程序流程 */while(1) // 主循环{if(recv_cmd(&type) == 0) // 发生帧错误或帧地址与本机地址不符,丢弃当前帧后返回continue;switch(type){case __ACTIVE_: // 主机询问从机是否存在send_data(__OK_, 0, dbuf); // 发送应答信息,这里buf的内容并未用到break;case __GETDATA_:len = strlen(dbuf);send_data(__STATUS_, len, dbuf); // 发送设备状态信息break;default:break; // 命令类型错误,丢弃当前帧后返回}}}void READSTATUS() interrupt 0 using 1 // 产生外部中断0时表示设备状态发生改变,该函数使用寄存器组1{get_status(); // 获得设备状态信息,并将其存入dbuf指向的存储区,数据最后一字节置0表示数据结束}/* 该函数接收一帧数据并进行检测,无论该帧是否错误,函数均会返回* 函数参数type保存接收到的命令字* 当接收到数据帧错误或其地址位不为0时(非主机发送帧),函数返回0,反之返回1 */bit recv_cmd(uchar *type){bit db = 0; // 当接收到的上一个字节为0xdb时,该位置位bit c0 = 0; // 当接收到的上一个字节为0xc0时,该位置位uchar data_buf[__ERRLEN]; // 保存接收到的帧uchar tmp;uchar ecc = 0;uchar i;M_DE = 0; // 置发送禁止,接收允许M_RE = 0;/* 接收一帧数据 */i = 0;while(!c0) // 循环直至帧接收完毕{RI = 0;while(!RI);tmp = SBUF;RI = 0;if(db == 1) // 接收到的上一个字节为0xdb{switch(tmp){case 0xdd:data_buf[i] = 0xdb; // 0xdbdd表示0xdbecc = ecc^0xdb;db = 0;break;case 0xdcdata_buf[i] = 0xc0; // 0xdbdc表示0xc0ecc = ecc^0xc0;db = 0;break;defaultreturn 0; // 帧错误,返回}i++;}switch(tmp) // 正常情况{case 0xc0: // 帧结束c0 = 1;break;case 0xdb: // 检测到转义字符db = 1;break;default: // 普通数据data_buf[i] = tmp; // 保存数据ecc = ecc^tmp; // 计算校验字节i++;}if(i == __ERRLEN) // 帧超长,错误,返回return 0;}/* 判断帧是否错误 */if(i<4) // 帧过短,错误,返回return 0;if(ecc != 0) // 校验错误,返回return 0;if(data_buf[0] != dev) // 非访问本机命令,错误,返回return 0;*type = data_buf[1]; // 获得命令字return 1; // 函数成功返回}/* 该函数发送一帧数据帧,参数type为命令字、len为数据长度、buf为要发送的数据内容 */void send_data(uchar type, uchar len, uchar *buf){uchar i;uchar ecc = 0; // 该字节用于保存校验字节M_DE = 1; // 置发送允许,接收禁止M_RE = 1;send_byte(dev); // 发送本机地址ecc = dev;send_byte(type); // 发送命令字ecc = ecc^type;send_byte(len); // 发送长度ecc = ecc^len;for(i=0; i<len; i++) // 发送数据{send_byte(*buf);ecc = ecc^(*buf);buf++;}send_byte(ecc); // 发送校验字节TI = 0; // 发送帧结束标志SBUF = 0xc0;while(!TI);TI = 0;}/* 该函数发送一个数据字节,若该字节为0xdb,则发送0xdbdd,若该字节为0xc0则,发送0xdbdc */void send_byte(uchar da){switch(da){case 0xdb: // 字节为0xdb,发送0xdbddTI = 0;SBUF = 0xdb;while(!TI);TI = 0;SBUF = 0xdd;while(!TI)TI = 0;break;case 0xc0: // 字节为0xc0,发送0xdbdcTI = 0;SBUF = 0xdb;while(!TI);TI = 0;SBUF = 0xdc;while(!TI)TI = 0;break;default: // 普通数据则直接发送TI = 0;SBUF = da;while(!TI);TI = 0;}}#endif。

RS 485.C程序源代码

RS 485.C程序源代码

***********************RS485.c文件程序源代码*************************#include<reg52.h>#include<intrins.h>SbitRS485_DIR=P1^7;//RS485方向选择引脚bit&nbsp;flagOnceTxd&nbsp;=&nbsp;0;&nbsp;&nbsp;//单次发送完成标志,即发送完一个字节bit&nbsp;cmdArrived&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;//命令到达标志,即接收到上位机下发的命令unsigned&nbsp;char&nbsp;cntRxd&nbsp;=&nbsp;0;unsigned&nbsp;char&nbsp;pdata&nbsp;bufRxd[40];&nbsp;//串口接收缓冲区&nbsp;void&nbsp;ConfigUART(unsigned&nbsp;int&nbsp;baud)&nbsp;&nbsp;//串口配置函数,baud为波特率{&nbsp;&nbsp;&nbsp;&nbsp;RS485_DIR&nbsp;=&nbsp;0;&nbsp;//RS485设置为接收方向&nbsp;&nbsp;&nbsp;&nbsp;SCON&nbsp;=&nbsp;0x50;&nbsp;&nbsp;&nbsp;//配置串口为模式1&nbsp;&nbsp;&nbsp;&nbsp;TMOD&nbsp;&amp;=&nbsp;0x0F;&nbsp;&nbsp;//清零T1的控制位&nbsp;&nbsp;&nbsp;&nbsp;TMOD&nbsp;|=&nbsp;0x20;&nbsp;&nbsp;//配置T1为模式2&nbsp;&nbsp;&nbsp;&nbsp;TH1&nbsp;=&nbsp;256&nbsp;-&nbsp;(11059200/12/32)&nbsp;/&n bsp;baud;&nbsp;&nbsp;//计算T1重载值&nbsp;&nbsp;&nbsp;&nbsp;TL1&nbsp;=&nbsp;TH1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//初值等于重载值&nbsp;&nbsp;&nbsp;&nbsp;ET1&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb sp;//禁止T1中断&nbsp;&nbsp;&nbsp;&nbsp;ES&nbsp;&nbsp;=&nbsp;1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;//使能串口中断&nbsp;&nbsp;&nbsp;&nbsp;TR1&nbsp;=&nbsp;1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb sp;//启动T1}unsigned&nbsp;char&nbsp;UartRead(unsigned&nbsp;char&nbsp;*buf,&nbsp;unsigned&nbsp;ch ar&nbsp;len)&nbsp;//串口数据读取函数,数据接收指针buf,读取数据长度len,返回值为实际读取到的数据长度{&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(len&nbsp;&gt;&nbsp;cntRxd)&nbsp;//读取长度大于接收到的数据长度时,&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;cntRxd;&nbsp;//读取长度设置为实际接收到的数据长度&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(i=0;&nbsp;i&lt;len;&nbsp;i++)&nbsp;//拷贝接收到的数据&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf++;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;cntRxd&nbsp;=&nbsp;0;&nbsp;&nbsp;//清零接收计数器&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;len;&nbsp;&nbsp;//返回实际读取长度}void&nbsp;DelayX10us(unsigned&nbsp;char&nbsp;t)&nbsp;&nbsp;//软件延时函数,延时时间(t*10)us{&nbsp;&nbsp;&nbsp;&nbsp;do&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;while&nbsp;(--t);}void&nbsp;UartWrite(unsigned&nbsp;char&nbsp;*buf,&nbsp;unsigned&nbsp;char&nbsp;len)&n bsp;//串口数据写入函数,即串口发送函数,待发送数据指针buf,数据长度len{&nbsp;&nbsp;&nbsp;&nbsp;RS485_DIR&nbsp;=&nbsp;1;&nbsp;&nbsp;//RS485设置为发送&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(len--)&nbsp;&nbsp;&nbsp;//发送数据&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flagOnceTxd&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SBUF&nbsp;=&nbsp;*buf;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(!flagOnceTxd);&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;DelayX10us(5);&nbsp;&nbsp;//等待最后的停止位完成,延时时间由波特率决定&nbsp;&nbsp;&nbsp;&nbsp;RS485_DIR&nbsp;=&nbsp;0;&nbsp;&nbsp;//RS485设置为接收}&nbsp;void&nbsp;UartDriver()&nbsp;//串口驱动函数,检测接收到的命令并执行相应动作{&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;len;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;buf[30];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(cmdArrived)&nbsp;//有命令到达时,读取处理该命令&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;UartRead(buf,&nbsp; sizeof(buf)-2);&nbsp;//将接收到的命令读取到缓冲区中&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf[len++]&nbsp;=&nbsp;'\r';&nbsp;&n bsp;&nbsp;//在接收到的数据帧后添加换车换行符后发回&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf[len++]&nbsp;=&nbsp;'\n';&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UartWrite(buf,&nbsp;len);&nbsp;&nbsp;&nbsp;&nbsp;}}&nbsp;void&nbsp;UartRxMonitor(unsigned&nbsp;char&nbsp;ms)&nbsp;&nbsp;//串口接收监控函数{&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;unsigned&nbsp;char&nbsp;cntbkp&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;unsigned&nbsp;char&nbsp;idletmr&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(cntRxd&nbsp;&gt;&nbsp;0)&nbsp;&nbsp;//接收计数器大于零时,监控总线空闲时间&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(cntbkp&nbsp;!=&nbsp;cntRxd) &nbsp;&nbsp;//接收计数器改变,即刚接收到数据时,清零空闲计时&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbspnbsp;&nbsp;&nbsp;&nbsp;&nbsp;cntbk p&nbsp;=&nbsp;cntRxd;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;idletmr&n bsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(id letmr&nbsp;&lt;&nbsp;30)&nbsp;&nbsp;//接收计数器未改变,即总线空闲时,累积空闲时间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;idletmr&nbsp;+=&nbsp;ms;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;if&nbsp;(idletmr&nbsp;&gt;=&nbsp;30)&nbsp;&nbsp;//空闲时间超过30ms 即认为一帧命令接收完毕&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmdArrived&nbsp;=&nbsp;1;&nbsp;//设置命令到达标志&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cntbkp&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;}}void&nbsp;InterruptUART()&nbsp;interrupt&nbsp;4&nbsp;&nbsp;//UART中断服务函数{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(RI)&nbsp;&nbsp;//接收到字节&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RI&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbs p;//手动清零接收中断标志位&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(cntRxd&nbsp;&lt;&nbsp;sizeof (bufRxd))&nbsp;//接收缓冲区尚未用完时,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bufRxd[cnt Rxd++]&nbsp;=&nbsp;SBUF;&nbsp;//保存接收字节,并递增计数器&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(TI)&nbsp;&nbsp;//字节发送完毕&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TI&nbsp;=&nbsp;0;&nbsp;&nbs p;&nbsp;//手动清零发送中断标志位&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flagOnceTxd&nbsp;=&nbsp;1;&nbsp;&n bsp;//设置单次发送完成标志&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}}***********************main.c文件程序源代码*************************#include&nbsp;&lt;reg52.h&gt;&nbsp;unsigned&nbsp;char&nbsp;T0RH&nbsp;=&nbsp;0;&nbsp;&nbsp;//T0重载值的高字节unsigned&nbsp;char&nbsp;T0RL&nbsp;=&nbsp;0;&nbsp;&nbsp;//T0重载值的低字节&nbsp;void&nbsp;ConfigTimer0(unsigned&nbsp;int&nbsp;ms);extern&nbsp;void&nbsp;ConfigUART(unsigned&nbsp;int&nbsp;baud);extern&nbsp;void&nbsp;UartRxMonitor(unsigned&nbsp;char&nbsp;ms);extern&nbsp;void&nbsp;UartDriver();&nbsp;void&nbsp;main&nbsp;(){&nbsp;&nbsp;&nbsp;&nbsp;EA&nbsp;=&nbsp;1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;&nbsp;//开总中断&nbsp;&nbsp;&nbsp;&nbsp;ConfigTimer0(1);&nbsp;&nbsp;//配置T0定时1ms&nbsp;&nbsp;&nbsp;&nbsp;ConfigUART(9600);&nbsp;//配置波特率为9600&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(1)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UartDriver();&nbsp;&nbsp;&nbsp;&nbsp;}<P>}</P>&nbsp;void&nbsp;ConfigTimer0(unsigned&nbsp;int&nbsp;ms)&nbsp;&nbsp;//T0配置函数{&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;long&nbsp;tmp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;11059200&nbsp;/&nbsp;12;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;//定时器计数频率&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;(tmp&nbsp;*&nbsp;ms)&nbsp;/&nbsp;1000;&n bsp;&nbsp;//计算所需的计数值&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;65536&nbsp;-&nbsp;tmp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//计算定时器重载值&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;tmp&nbsp;+&nbsp;34;&nbsp;&nbsp;&nbsp;&nb sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//修正中断响应延时造成的误差&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T0RH&nbsp;=&nbsp;(unsigned&nbsp;char)(tmp&nbsp;&gt;&gt;&nb sp;8);&nbsp;&nbsp;//定时器重载值拆分为高低字节&nbsp;&nbsp;&nbsp;&nbsp;T0RL&nbsp;=&nbsp;(unsigned&nbsp;char)tmp;&nbsp;&nbsp;&nbsp;&nbsp;TMOD&nbsp;&amp;=&nbsp;0xF0;&nbsp;&nbsp;&nbsp;//清零T0的控制位&nbsp;&nbsp;&nbsp;&nbsp;TMOD&nbsp;|=&nbsp;0x01;&nbsp;&nbsp;&nbsp;//配置T0为模式1&nbsp;&nbsp;&nbsp;&nbsp;TH0&nbsp;=&nbsp;T0RH;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//加载T0重载值&nbsp;&nbsp;&nbsp;&nbsp;TL0&nbsp;=&nbsp;T0RL;&nbsp;&nbsp;&nbsp;&nbsp;ET0&nbsp;=&nbsp;1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb sp;&nbsp;//使能T0中断&nbsp;&nbsp;&nbsp;&nbsp;TR0&nbsp;=&nbsp;1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb sp;&nbsp;//启动T0}void&nbsp;InterruptTimer0()&nbsp;interrupt&nbsp;1&nbsp;&nbsp;//T0中断服务函数{&nbsp;&nbsp;&nbsp;&nbsp;TH0&nbsp;=&nbsp;T0RH;&nbsp;&nbsp;//定时器重新加载重载值&nbsp;&nbsp;&nbsp;&nbsp;TL0&nbsp;=&nbsp;T0RL;&nbsp;&nbsp;&nbsp;&nbsp;UartRxMonitor(1);&nbsp;&nbsp;//串口接收监控}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include "iom16v.h" #include "macros.h" //波特率,晶振 #define BAUD 9600 #define FXTAL 8000000 //12 //串口接收完毕中断触发声明 #pragma interrupt_handler USART_Received_Ir:12 //变量定义:接收缓冲变量,接收标志位 unsigned char RX_Buffer=0x00,RX_Flag=0; //函数声明 void USART_Send(unsigned char); void delay(uint MS) { uint i,j;
for(i=0;i<MS;i++) for(j=0;j<1141;j++); } //串口 IO 初始化函数 void USART_IO_Init() { //PORTD=0X00; DDRD|=BIT(PD1); //PD1:TX 为输出状态 //DDRD|=BIT(PD2);}
//串口初始化函数 void USART_Init() { unsigned int Temp; USART_IO_Init(); //串口 IO 初始化函数调用
一般终端匹配采用终端电阻方法, RS-485 应在总线电缆的开始和末端都并 接终端电阻。终接电阻在 RS-485 网络中取 120Ω。相当于电缆特性阻抗的电阻, 因为大多数双绞线电缆特性阻抗大约在 100~120Ω。这种匹配方法简单有效, 但有一个缺点,匹配电阻要消耗较大功率,对于功耗限制比较严格的系统不太适 合。另外一种比较省电的匹配方式是 RC 匹配。利用一只电容 C 隔断直流成分可 以节省大部分功率。但电容 C 的取值是个难点,需要在功耗和匹配质量间进行折 衷。 还有一种采用二极管的匹配方法,这种方案虽未实现真正的“匹配”,但 它利用二极管的钳位作用能迅速削弱反射信号,达到改善信号质量的目的,节能 效果显著。
由于 PC 机默认的只带有 RS232 接口,有两种方法可以得到 PC 上位机的 RS485 电路:(1)通过 RS232/RS485 转换电路将 PC 机串口 RS232 信号转换成 RS485 信 号,对于情况比较复杂的工业环境最好是选用防浪涌带隔离珊的产品。(2)通 过 PCI 多串口卡,可以直接选用输出信号为 RS485 类型的扩展卡。
1.3 RS485 布网
网络拓扑一般采用终端匹配的总线型结构,不支持环形或星形网络。在构建 网络时,应注意如下几点:
(1)采用一条双绞线电缆作总线,将各个节点串接起来,从总线到每个节 点的引出线长度应尽量短,以便使引出线中的反射信号对总线信号的影响最低。 有些网络连接尽管不正确,在短距离、低速率仍可能正常工作,但随着通信距离 的延长或通信速率的提高,其不良影响会越来越严重,主要原因是信号在各支路 末端反射后与原信号叠加,会造成信号质量下降。
HART 网络:HART 是由现在的艾默生提出一个过度性总线标准,他主要是在 4~20 毫安电流信号上面叠加数字信号,物理层采用 BELL202 频移键控技术,以 实现部分智能仪表的功能,但此协议不是一个真正意义上开放的标准,要加入他 的基金会才能拿到协议,加入基金会要一部分的费用。技术主要被国外几家大公 司垄断,近两年国内也有公司再做,但还没有达到国外公司的水平。现在有很大 一部分的智能仪表都带有 HART 圆卡,都具备 HART 通讯功能。但从国内来看还没 有真正利用其这部分功能,最多只是利用手操器对其进行参数设定,没有发挥出 HART 智能仪表应有的功能,没有联网进行设备监控。从长远来看由于 HART 通信 速率低组网困难等原因,HART 仪表的采购量会程下滑趋势,但由于 HART 仪表已 经有十多年的历史现在在装数量非常的大,对于一些系统集成商来说还有很大的 可利用空间。
式,即一个主机带多个从机。很多情况下,连接 RS-485 通信链路时只是简单地 用一对双绞线将各个接口的“A”、“B”端连接起来。而忽略了信号地的连接, 这种连接方法在许多场合是能正常工作的,但却埋下了很大的隐患,这有二个原 因:(1)共模干扰问题: RS-485 接口采用差分方式传输信号方式,并不需要相 对于某个参照点来检测信号,系统只需检测两线之间的电位差就可以了。但人们 往往忽视了收发器有一定的共模电压范围,RS-485 收发器共模电压范围为-7~ +12V,只有满足上述条件,整个网络才能正常工作。当网络线路中共模电压超出 此范围时就会影响通信的稳定可靠,甚至损坏接口。(2)EMI 问题:发送驱动器 输出信号中的共模部分需要一个返回通路,如没有一个低阻的返回通道(信号 地),就会以辐射的形式返回源端,整个总线就会像一个巨大的天线向外辐射电 磁波。
// 校验,2 位停止位,8 位数据位
Temp=(FXTAL/BAUD/16)-1;
//求出 9600 波特率的赋值
UBRRH=((Temp>>8)&0x00ff);
//波特率寄存器高八位赋值
UBRRL=(Temp&0x00ff);
//波特率寄存器低八位赋值
//UBRR=71; //从手册中直接取得赋值,9600kbps
UCSRB|=BIT(RXCIE);
//接收完毕中断使能
}
RS485 通讯技术介绍
一、 RS485 简介
智能仪表是随着 80 年代初单片机技术的成熟而发展起来的,现在世界仪表 市场基本被智能仪表所垄断。究其原因就是企业信息化的需要,企业在仪表选型 时其中的一个必要条件就是要具有联网通信接口。最初是数据模拟信号输出简单 过程量,后来仪表接口是 RS232 接口,这种接口可以实现点对点的通信方式,但 这种方式不能实现联网功能。随后出现的 RS485 解决了这个问题。下面我们就简 单介绍一下 RS485。
最近两年一些公司基于部分企业信息化的实施已完成,工厂中已经铺设了延 伸到车间每个办公室、控制室的局域网的现状,推出了串口服务器来取代多串口 卡,这主要是利用企业已有的局域网资源减少线路投资,节约成本,相当于通过 tcp/ip 把多串口卡放在了现场。
1.4 RS485 和其它总线网络的区别
我们把工业网络归结为三类:RS485 网络、HART 网络和现场总线网络。
RX_Flag=0;
PORTD&=~BIT(PD2);
}
}
}
//串口发送函数
void USART_Send(unsigned char Data)
{
while(!(UCSRA&(BIT(UDRE)))); UDR=Data;
//数据寄存器 UDR 是否为 //UDR 赋值
while(!(UCSRA&(BIT(TXC))));
{
PORTD|=BIT(PD2);
//UART_Puts();
USART_Send('1');
//USART_Send(RX_Buffer);
RX_Flag=0;
PORTD&=~BIT(PD2);
PORTD|=BIT(PD2);
//UART_Puts();
USART_Send('2');
//USART_Send(RX_Buffer);
现场总线网络:现场总线技术是当今自动化领域技术发展热点之一,被誉为 自动化领域的计算机局域网,它的出现标志着自动化控制技术又一个新时代的开 始。现场总线是连接设置在控制现场的仪表与设置在控制室内的控制设备的数字 化、串行、多站通信的网络。其关键标志是能支持双向、多节点、总线式的全数 字通信。现场总线技术近年来成为国际上自动化和仪器仪表发展的热点,它的出 现是传统的控制系统结构产生了革命性的变化,是自控系统朝着智能化、数字化、 信息化、网络化、分散化的方向迈进,形成新型的网络集成式全分布式控制系统 ---现场总线控制系统 FCS(Fieldbus Control System)。但是现在的现场总线 的各种标准并行存在并且都有自己的生存领域,还没有形成真正统一的标准,关 键是看不到什么时候能形成统一的标准,技术也不够成熟。另外现场总线的仪表
(2)应注意总线特性阻抗的连续性,在阻抗不连续点就会发生信号的反射。 下列几种情况易产生这种不连续性:总线的不同区段采用了不同电缆,或某一段 总线上有过多收发器紧靠在一起安装,再者是过长的分支线引出到总线。
总之,应该提供一条单一、连续的信号通道作为总线。
在 RS485 组网过程中另一个需要主意的问题是终端负载电阻问题,在设备少 距离短的情况下不加终端负载电阻整个网络能很好的工作但随着距离的增加性 能将降低。理论上,在每个接收数据信号的中点进行采样时,只要反射信号在开 始采样时衰减到足够低就可以不考虑匹配。但这在实际上难以掌握,美国 MAXIM 公司有篇文章提到一条经验性的原则可以用来判断在什么样的数据速率和电缆 长度时需要进行匹配:当信号的转换时间(上升或下降时间)超过电信号沿总线 单向传输所需时间的 3 倍以上时就可以不加匹配。
UCSRA=0x00; UCSRB=0x00;
//串口控制器 A 清零 //串口控制器 B 清零
UCSRC|=BIT(URSEL)|BIT(UCSZ1)|BIT(UCSZ0); //选择 USCRC,异步操作,禁止 检验危,1 个停止位,八位数据
//UCSRC=(1<<URSEL)|(1<<USBS)|(0<<UPM0)|(3<<UCSZ0); //选择 UCSRC,异 步模式,禁止
void UART_Puts(unsigned char *Str) { if(*Str) //字符串结束 {
} } //主函数 void main() { DDRD|=BIT(PD2); //PORTD|=BIT(PD2); USART_Init(); //UART_Puts("\r\n 你发送的字符串是:");//发送字符串 PORTD&=~BIT(PD2); DDRD|=BIT(PD2); while(1) { if(RX_Flag)
相关文档
最新文档