RS485通信和Modbus协议实例分析

合集下载

MODBUS中485传输例程分析(参考)

MODBUS中485传输例程分析(参考)
}
case 0x0076:
{
Uart0_send_buff[i] = Out_current & 0xff;
i++;
Uart0_send_buff[i] = (Out_current >> 8) & 0xff;
{
unsigned char i;
unsigned short crc = 0xFFFF;
if(len==0)
{
len = 1;
}
while(len--)
{
crc ^= *ptr;
Uart0_send_buff[i] = (Mkgz_bz >> 8) & 0xff; //高8位
i++;
}//后面不放break的目的是继续往下执行
case 0x0066:
{
Uart0_send_pointer = Uart0_send_buff;
USART_SendData(USART2, *Uart0_send_pointer++);
USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
i++;
}
case 0x00A6:
{
Uart0_send_buff[i] = OutX_current & 0xff;
i++;
Uart0_send_buff[i] = (OutX_current >> 8) & 0xff;
Uart0_send_buff[2] = 2 * Uart0_rev_buff[5]; //读的字节数

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

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

2
3
4
状 态 字
5
实际 运行 数据
6
实际 运行 数据
7
异 或 校 验
校验
起 始 字 节
从 状 机 态 地 字 址
字节定义 头 地址 状态区
数据区
RS485通讯协议
长帧(起始字节=02H)
发送顺序 1 (字节) 控制器至变频器:
2 3 4 5 6 7 8 9 10 11
起 始 字 节
从 功 命 功能 机 能 令 码设 地 码 字 定值 址 号
1 0
RS485通讯协议
响应字定义 控制字 (位)
bit5

1 0
含义
停机2状态 非停机2状态
功能描述
变频器执行停机2命令,处于停机状态
bit6
1 0
控制禁止状态 控制允许状态 上位机控制 本地控制方式
到达设定频率/ 速度 未到达设定频率 /速度
因停机1或停机2或变频器故障或异常命令使变 频器停机的状态,需控制字恢复到准备运行状态 使其复位
bit9
1 0
bit10
1 0
变频器只允许本地控制(面板和端子)
RS485通讯协议
响应字位定义 控制字 (位)
bit11

1 0
含义 变频器运行状态 变频器停止状态 变频器接受出错
功能描述
bit15
1
0
bit0 bit7~8 bit12~1 4,
变频器接收正确
预留 预留 预留
本位表示来自控制器的通讯帧经 校验出错,控制器应再次发送该 帧。
RS485通讯协议
控制字定义 控制字 (位) bit0 值 1 0 bit1 含义 运行命令 方式0停车 功能描述 起动变频器 减速停车

ZNJC2 RS485通讯 modbus 协议

ZNJC2 RS485通讯 modbus 协议

_MODBUS 通讯协议说明1. 通讯相关的参数2.通讯说明2.1 数据格式说明控制器采用RS-485总线,协议符合ModBus 规约,数据格式有标准MODBUS-RTU 、 非标准MODBUS-RTU(16进制)和ASC(ASC Ⅱ码)3种格式。

数据传输均采用8位数据位、1位停止位、无奇偶校验位。

波特率可设为2400、4800、9600和19200 bit/s 。

通讯传送分为独立的信息头,和发送的编码数据。

以下的通讯传送方式定义与RTU通讯规约相兼容:2.2 非标准MODBUS-RTU(16进制)数据格式详细说明下面以RTU(16进制)数据格式进行详细说明,ASC Ⅱ码数据格式只是把16进制代码转换成ASC Ⅱ码字符。

地址码:这个字节表明由用户设定地址码的从机将接收由主机发送来的信息。

并且每个从机都有具有唯一的地址码,并且响应回送均以各自的地址码开始。

主机发送的地址码表明将发送到的从机地址,而从机发送的地址码表明回送的从机地址。

功能码:通讯传送的第二个字节。

ModBus 通讯规约定义功能号为01H 到7FH 。

本控制器利用其中的一部分功能码。

作为主机请求发送,通过功能码告诉从机执行什么动作。

作为从机响应,从机发送的功能码与从主机发送来的功能码一样,并表明从机已响应主机进行操作。

如果从机发送的功能码的最高位 (比如功能码大于7FH),则表明从机没有响应操作或发送出错。

数据区:数据区是根据不同的功能码而不同。

CRC码:二字节的错误检测码。

当通讯命令发送至仪器时,符合相应地址码的设备接通讯命令,并除去地址码,读取信息,如果没有出错,则执行相应的任务;然后把执行结果返送给发送者。

返送的信息中包括地址码、执行动作的功能码、执行动作后结果的数据以及错误校验码。

如果出错就不发送任何信息。

2.2.2 信息帧格式:(1)地址码:地址码是信息帧的第一字节(8位),从1到255。

这个字节表明由用户设置地址的从机将接收由主机发送来的信息。

MODBUS实例485通讯解析

MODBUS实例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.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.1102=7;外部1有效;ii.1103=8;由串行通讯给定;iii.0002=初始频率;如果不设置,为菜单1104的值;iv.0001=0x06;命令寄存器:0001;v.0001=0x0f;vi.0001=0x2f;启动;vii.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。

modbus通讯协议与485

modbus通讯协议与485

Modbus通讯协议与4851. 什么是Modbus通讯协议?Modbus通讯协议是一种用于串行通信的协议,常用于工业自动化领域中的设备间通讯。

该协议设计简单、易于实现,因此被广泛应用于工业现场中。

Modbus协议支持多种物理介质,包括串口(如RS-232、RS-485)和以太网(如TCP/IP),其中,Modbus-RTU和Modbus-TCP是较为常见的两种实现方式。

2. 485总线介绍485总线是一种串行通信标准,广泛用于远距离数据传输。

它能实现多个设备通过同一条总线进行通信,且可实现传输距离高达1200米,通信速率可达到10 Mb/s。

相较于RS-232,RS-485是一个全双工的通信接口,并且支持多主设备,能够同时连接多个设备,使多个设备能够实现互相通信。

3. Modbus-RTU协议Modbus-RTU是一种基于二进制的Modbus协议实现方式,主要用于串口通信。

以下是Modbus-RTU常用的帧格式:起始符地址功能码数据区 CRC校验其中,起始符为11位的低电平信号,用于起始帧的标识,地址为设备的唯一标识符,功能码表示操作的具体功能,数据区包含要发送或接收的数据,CRC校验用于验证数据的完整性。

Modbus-RTU支持多种功能码,包括读取单个寄存器、读取多个寄存器、写单个寄存器等。

其通信速率可根据设备需要进行设置。

4. Modbus-TCP协议Modbus-TCP是Modbus协议的一种基于以太网的实现方式。

它使用常用的TCP/IP网络进行通信,能够实现高速、可靠的数据传输。

Modbus-TCP与Modbus-RTU相比,最明显的区别是使用了不同的物理介质和通信协议。

Modbus-TCP通过以太网进行数据传输,其帧格式与Modbus-RTU有所不同。

Modbus-TCP协议使用了标准的TCP/IP协议作为传输层协议,因此具有较高的灵活性和互操作性。

它可以与现有的以太网基础设施无缝集成,并且支持在局域网或广域网上进行远程数据传输。

RS485实验一报告模板

RS485实验一报告模板

实验一基于RS485和牛顿模块的A/D、D/A实验一、实验目的和要求(1)熟悉RS485总线与牛顿模块的结构组成,了解其工作过程,认识其结构形式。

(2)熟悉牛顿模块的基本工作原理。

(3)掌握应用RS485和牛顿模块进行电压输出和电压采集的方法。

二、主要仪器设备计算机、R-8017、R-8024、R-8043D、R-8053、RS232转RS485模块、24V稳压源三、实验内容和原理(1)RS485网络分析RS485采用差分信号负逻辑,+2V~+6V表示“0”,- 6V~- 2V表示“1”。

RS485有两线制和四线制两种接线,四线制只能实现点对点的通信方式,现很少采用,现在多采用的是两线制接线方式,这种接线方式为总线式拓扑结构在同一总线上最多可以挂接32个结点。

在RS485通信网络中一般采用的是主从通信方式,即一个主机带多个从机。

很多情况下,连接RS-485通信链路时只是简单地用一对双绞线将各个接口的“A”、“B”端连接起来。

而忽略了信号地的连接,这种连接方法在许多场合是能正常工作的,但却埋下了很大的隐患,这有二个原因:1>.共模干扰问题:RS-485接口采用差分方式传输信号方式,并不需要相对于某个参照点来检测信号,系统只需检测两线之间的电位差就可以了。

但人们往往忽视了收发器有一定的共模电压范围,RS-485收发器共模电压范围为-7~+12V,只有满足上述条件,整个网络才能正常工作。

当网络线路中共模电压超出此范围时就会影响通信的稳定可靠,甚至损坏接口。

2>.EMI问题:发送驱动器输出信号中的共模部分需要一个返回通路,如没有一个低阻的返回通道(信号地),就会以辐射的形式返回源端,整个总线就会像一个巨大的天线向外辐射电磁波。

由于PC机默认的只带有RS232接口,有两种方法可以得到PC上位机的RS485电路:1>.通过RS232/RS485转换电路将PC机串口RS232信号转换成RS485信号,对于情况比较复杂的工业环境最好是选用防浪涌同时带隔离栅的产品。

485通信讲解(附案例)

485通信讲解(附案例)

RS485通讯协议
控制字定义
控制字 (位)

bit9
1
含义
点动反转
0
点动反转停止
bit10
1
主站控制有效
0
主站控制无效
bit14
1
运行方向正转
0
运行方向反转
bit11~13 ,bit15 、4
未定 义
预留
功能描述
主站下发的当前控制字和运行设定值 有效 主站下发的当前控制字和运行设定值 无效,变频器保持前一次的控制字和 运行设定值
发送顺序 1 2 3 4 5
6
(字节)
变频器至控制器:
起 始 字 节
从 机 地 址
响 应 字
功 能 码 号
功能 码实 际值
功能 码实 际值
控制区
78
数据区 校验
9
10 11
状 态 字
状 态 字
实际 运行 数据
实际 运行 数据
异 或 校 验
字节定义 头 地址 命令区
参数区
控制区 数据区 校验
RS485通讯协议
67
起 始 字 节
从 机 地 址
控 制 字
控 制 字
运行 数据 设定
运行 数据 设定
异 或 校 验
字节定义头地址控制区 数据区 校验
发送顺序 1 2 3 4 5 (字节)
67
变频器至控制器:
起 始 字 节
从 机 地 址
状 态 字
状 态 字
实际 运行 数据
实际 运行 数据
异 或 校 验
字节定义头地址状态区 数据区 校验
1、以50Hz运行2#变频器。(此例需要将变频器频率设定成F0.03=6)

485通信讲解

485通信讲解

485通信讲解标题:485通信协议与相关案例分析摘要:本文将详细介绍485通信协议的基本原理、通信模式以及相关案例分析,旨在帮助读者全面了解和应用485通信协议。

引言:485通信协议是一种用于串行通信的工业标准协议,常被应用于在工控系统等环境中实现设备之间的可靠通信。

本文将从原理到应用进行全面解析,通过案例分析展示其在实际项目中的应用场景和效果。

一、485通信协议的基本原理(400字)1.物理层:485通信协议采用差分信号传输,通过两个信号线(A和B)来传输数据。

A线传输逻辑高电平,B线传输逻辑低电平,两者之间产生差分电压用以表示二进制数据的0和12.数据链路层:485通信协议采用主从模式,一个设备作为主站,其他设备作为从站。

主站负责发送指令,从站接收并响应主站的指令。

通信中使用标准的帧结构,包括起始位、数据位、校验位和停止位。

3.电气特性:由于485通信协议可支持长距离通信和多个设备的连接,因此需要考虑电气特性。

主要包括传输速率、传输距离、驱动能力等方面。

二、485通信协议的通信模式(200字)1.单主从模式:由一个主站设备控制多个从站设备,主站负责发起通信请求,从站接收并响应请求。

这种模式常用于工业自动化系统中的智能仪表、传感器等设备的通信。

2.多主从模式:允许多个主站设备同时控制多个从站设备,主站之间通过总线共享信息。

每个主站设备都可控制总线上的任意一个从站设备,并实现数据的读取、写入等操作。

这种模式适用于需要多个主站设备同时交互的应用场景。

三、485通信协议的应用案例分析(600字)1.工业自动化控制系统:485通信协议被广泛应用于工业自动化控制系统中,实现不同设备之间的数据交换和控制。

例如,工厂的温度控制系统中,主站设备负责发送温度设定指令给多个从站设备,从站设备接收指令并控制温度设备进行调节。

通过485通信协议,实现了系统的自动化控制和数据的收集。

2.楼宇自动化系统:在楼宇自动化系统中,485通信协议常用于控制和监测设备之间的通信。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

18.1 RS485通信实际上在RS485之前RS232就已经诞生,但是RS232有几处不足的地方:1、接口的信号电平值较高,达到十几V,容易损坏接口电路的芯片,而且和TTL电平不兼容,因此和单片机电路接起来的话必须加转换电路。

2、传输速率有局限,不可以过高,一般到几十Kb/s就到极限了。

3、接口使用信号线和GND与其他设备形成共地模式的通信,这种共地模式传输容易产生干扰,并且抗干扰性能也比较弱。

4、传输距离有限,最多只能通信几十米。

5、通信的时候只能两点之间进行通信,不能够实现多机联网通信。

针对RS232接口的不足,就不断出现了一些新的接口标准,RS485就是其中之一,他具备以下的特点:1、我们在讲A/D的时候,讲过差分信号输入的概念,同时也介绍了差分输入的好处,最大的优势是可以抑制共模干扰。

尤其工业现场的环境比较复杂,干扰比较多,所以通信如果采用的是差分方式,就可以有效的抑制共模干扰。

而RS485就是一种差分通信方式,它的通信线路是两根,通常用A和B或者D+和D-来表示。

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

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

3、RS485内部的物理结构,采用的是平衡驱动器和差分接收器的组合,抗干扰能力也大大增加。

4、传输距离最远可以达到1200米左右,但是他的传输速率和传输距离是成反比的,只有在100Kb/s 以下的传输速度,才能达到最大的通信距离,如果需要传输更远距离可以使用中继。

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

RS485的接口非常简单,和RS232所使用的MAX232是类似的,只需要一个RS485转换器,就可以直接和我们单片机的UART串行接口连接起来,并且完全使用的是和UART一致的异步串行通信协议。

但是由于RS485是差分通信,因此接收数据和发送数据是不能同时进行的,也就是说它是一种半双工通信。

那我们如何判断什么时候发送,什么时候接收呢?RS485类的芯片很多,这节课我们以MAX485为例讲解RS485通信,如图18-1所示。

图18-1 MAX485硬件接口MAX485是美信(Maxim)推出的一款常用RS485转换器。

其中5脚和8脚是电源引脚,6脚和7脚就是485通信中的A和B两个引脚,而1脚和4脚分别接到我们单片机的RXD和TXD引脚上,直接使用单片机UART进行数据接收和发送。

而2脚和3脚就是方向引脚了,其中2脚是低电平使能接收器,3脚是高电平使能输出驱动器。

我们把这两个引脚连到一起,平时不发送数据的时候,保持这两个引脚是低电平,让MAX485处于接收状态,当需要发送数据的时候,把这个引脚拉高,发送数据,发送完毕后再拉低这个引脚就可以了。

为了提高RS485的抗干扰性能,需要在靠近MAX485的A和B引脚之间并接一个电阻,这个电阻阻值从100欧到1K都可以。

在这里我们还要介绍一下如何使用KST-51单片机开发板进行外围扩展实验。

我们的开发板只能把基本的功能给同学们做出来提供实验练习,但是同学们学习的脚步不应该停留在这个实验板上。

如果想进行更多的实验,就可以通过单片机开发板的扩展接口进行扩展实验。

大家可以看到蓝绿色的单片机座周围有32个插针,这32个插针就是把单片机的32个IO引脚全部都引出来了。

在原理图上体现出来的就是我们的J4、J5、J6、J7这4个器件,如图18-2所示。

图18-2 单片机扩展接口这32个IO口不是所有的IO口都可以用来对外扩展,其中既作为数据输出,又可以作为数据输入的引脚是不可以用的,比如P3.2、P3.4、P3.6引脚,这三个引脚是不可用的。

比如P3.2这个引脚,如果我们用来扩展,发送的信号如果和DS18B20的时序吻合,会导致DS18B20拉低引脚,影响通信。

除这3个IO口以外的其他29个IO口,都可以使用杜邦线接上插针,扩展出来使用。

当然了,如果把当前的IO口应用于扩展功能了,板子上的相应的功能就实现不了了,也就是说需要扩展功能和板载功能二选一。

在进行RS485实验中,我们通信用的引脚必须是P3.0和P3.1,此外还有一个方向控制引脚,我们使用杜邦线将其连接到P1.7上去。

RS485的另外一端,大家可以使用一个USB转485模块,用双绞线把开发板和模块上的A和B分别对应连起来,USB那头插入电脑,然后就可以进行通信了。

学习了第13章的实用串口通信的方法和程序后,做这种串口通信的方法就很简单了,基本是一致的。

我们使用实用串口通信的思路,做了一个简单的程序,通过串口调试助手下发任意个字符,单片机接收到后在末尾添加“回车+换行”符后再送回,在调试助手上重新显示出来,先把程序贴出来。

程序中需要注意的一点是:因为平常都是将485设置为接收状态,只有在发送数据的时候才将485改为发送状态,所以在UartWrite()函数开头将485方向引脚拉高,函数退出前再拉低。

但是这里有一个细节,就是单片机的发送和接收中断产生的时刻都是在停止位的一半上,也就是说每当停止位传送了一半的时候,RI或TI就已经置位并且马上进入中断(如果中断使能的话)函数了,接收的时候自然不会存在问题,但发送的时候就不一样了:当紧接这向SBUF写入一个字节数据时,UART硬件会在完成上一个停止位的发送后,再开始新字节的发送,但如果此时不是继续发送下一个字节,而是已经发送完毕了,要停止发送并将485方向引脚拉低以使485重新处于接收状态时就有问题了,因为这时候最后的这个停止位实际只发送了一半,还没有完全完成,所以就有了UartWrite()函数内DelayX10us(5)这个操作,这是人为的增加了延时50us,这50us的时间正好让剩下的一半停止位完成,那么这个时间自然就是由通信波特率决定的了,为波特率周期的一半。

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

相关文档
最新文档