一、RS485基础
1 RS485
电子工业协会(EIA)于1983年制订并发布RS-485标准,并经通讯工业协会(TIA)修订后命名为TIA/EIA-485-A,习惯地称之为RS-485标准。RS-485标准只规定了平衡发送器和接收器的电特性,而没有规定接插件、传输电缆和应用层通信协议。
RS-485标准数据信号采用差分传输方式(Differential Driver Mode),也称作平衡传输,它使用一对双绞线,将其中一线定义为A,另一线定义为B。
通常情况下,发送发送器A、B之间的正电平在+2~+6V,是一个逻辑状态;负电平在-2~-6V,是另一个逻辑状态。另有一个信号地C。在RS-485器件中,一般还有一个“使能”控制信号。“使能”信号用于控制发送发送器与传输线的切断与连接,当“使能”端起作用时,发送发送器处于高阻状态,称作“第三态”,它是有别于逻辑“1”与“0”的第三种状态。
对于接收发送器,也作出与发送发送器相对的规定,收、发端通过平衡双绞线将A-A与B-B对应相连。当在接收端A-B之间有大于+200mV的电平时,输出为正逻辑电平;小于-200mV时,输出为负逻辑电平。在接收发送器的接收平衡线上,电平范围通常在200mV至6V之间。参见图所示。定义逻辑1(正逻辑电平)为B>A的状态,逻辑0(负逻辑电平)为A>B的状态,A、B之间的压差不小于200mV。
RS-485标准的最大传输距离约为1219米,最大传输速率为10Mbps。通常,RS-485网络采用平衡双绞线作为传输媒体。平衡双绞线的长度与传输速率成反比,只有在20kbps速率以下,才可能使用规定最长的电缆长度。只有在很短的距离下才能获得最高速率传输。一般来说,15米长双绞线最大传输速率仅为1Mbps。注意:并不是所有的RS-485收发器都能够支持高达10Mbps的通讯速率。如果采用光电隔离方式,则通讯速率一般还会受到光电隔离器件响应速度的限制。
RS-485网络采用直线拓朴结构,需要安装2个终端匹配电阻,其阻值要求等于传输电缆的特性阻抗(一般取值为120Ω)。在矩距离、或低波特率波数据传输时可不需终端匹配电阻,即一般在300米以下、19200bps不需终端匹配电阻。终端匹配电阻安装在RS-485传输网络的两个端点,并联连接在A-B引脚之间。
RS-485标准通常被用作为一种相对经济、具有相当高噪声抑制、相对高的传输速率、传输距离远、宽共模范围的通信平台。同时,RS-485电路具有控制方便、成本低廉等优点。 在过去的20年时间里,建议性标准RS-485作为一种多点差分数据传输的电气规范,被应用在许多不同的领域,作为数据传输链路。目前,在我国应用的现场网络中,RS-485半双工异步通信总线也是被各个研发机构广泛使用的数据通信总线。但是基于在RS-485总线上任一时刻只能存在一个主机的特点,它往往应用在集中控制枢纽与分散控制单元之间。
2 RS232、RS422和RS485
(1)RS232与RS485
前文简单描述过RS232,它的全称是RS-232-C,是美国电子工业协会EIA(Electronic Industry Association)制定的一种串行物理接口标准。RS是英文“推荐标准”的缩写,232为标识号,C表示修改次数。RS-232-C标准规定,驱动器允许有2500pF的电容负载,通信距离将受此电容限制,例如,采用150pF/m的通信电缆时,最大通信距离为15m;若每米电缆的电容量减小,通信距离可以增加。传输距离短的另一原因是RS-232属单端信号传送,存在共地噪声和不能抑制共模干扰等问题,因此一般用于20m以内的通信。
RS-485采用平衡发送和差分接收,因此具有抑制共模干扰的能力。加上总线收发器具有高灵敏度,能检测低至200mV的电压,故传输信号能在千米以外得到恢复。 RS-485采用半双工工作方式,任何时候只能有一点处于发送状态,因此,发送电路须由使能信号加以控制。RS-485用于多点互连时非常方便,可以省掉许多信号线。应用RS-485 可以联网构成分布式系统,其允许最多并联32台驱动器和32台接收器。
即它们间的区别
1)从接线上,RS232是三线制,RS485是两线制;
2)从传输距离上,RS232只能传输15米,RS485最远可以传输1200米;
3)从速率上,RS232是全双工传输,RS485是半双工传输;
4)从协议层上,RS232只支持点对点通讯(1:1),RS485支持总线形式通讯(1:N);
(2)RS232RS422与RS485
RS-232、RS-422与RS-485都是串行数据接口标准,最初都是由电子工业协会(EIA)制订并发布的,RS-232在1962年发布,命名为EIA-232-E,作为工业标准,以保证不同厂家产品之间的兼容。RS-422由RS-232发展而来,它是为弥补RS-232之不足而提出的。为改进RS-232 通信距离短、速率低的缺点,RS-422定义了一种平衡通信接口,将传输速率提高到10Mb/s,传输距离延长到4000英尺(速率低于100kb/s时),并允许在一条平衡总线上连接最多10个接收器。RS-422是一种单机发送、多机接收的单向、平衡传输规范,被命名为TIA/EIA-422-A标准。为扩展应用范围,EIA又于1983年在RS-422基础上制定了RS-485标准,增加了多点、双向通信能力,即允许多个发送器连接到同一条总线上,同时增加了发送器的驱动能力和冲突保 护特性,扩展了总线共模范围,后命名为TIA/EIA-485-A标准。由于EIA提出的建议标准都是以“RS”作为前缀,所以在通讯工业领域,仍然习惯将上述标准以RS作前缀称谓。
RS-232、RS-422与RS-485标准只对接口的电气特性做出规定,而不涉及接插件、电缆或协议,在此基础上用户可以建立自己的高层通信协议。因此在视频界的应用,许多厂家都建立了一套高层通信协议,或公开或厂家独家使用。如录像机厂家中的Sony与*对录像机的RS-422控制协议是有差异的,视频服务器上的控制协议则更多了,如Louth、Odetis协议是公开的,而ProLINK则是基于Profile上的。
二、BBG上的RS485通信
1 RS485通信电路
一般的RS485通信电路如下图所示,PC机或MCU上的串口,通过RS232转RS485电路,将RS232信号转为RS485信号,然后在电缆上进行数据的传递,图中的5代表地线,2、3代表RXD或TXD,即他们是交叉相连的。
在RS485通信网络中一般采用的是主从通信方式,即一个主机带多个从机。很多情况下,连接RS-485通信链路时只是简单地用一对双绞线将各个接口的“A”、“B”端连接起来。而忽略了信号地的连接,这种连接方法在许多场合是能正常工作的,但却埋下了很大的隐患,这有二个原因:(1)共模干扰问题: RS-485接口采用差分方式传输信号方式,并不需要相对于某个参照点来检测信号,系统只需检测两线之间的电位差就可以了。但人们往往忽视了收发器有一定的共模电压范围,RS-485收发器共模电压范围为-7~+12V,只有满足上述条件,整个网络才能正常工作。当网络线路*模电压超出此范围时就会影响通信的稳定可靠,甚至损坏接口。(2)EMI问题:发送驱动器输出信号中的共模部分需要一个返回通路,如没有一个低阻的返回通道(信号地),就会以辐射的形式返回源端,整个总线就会像一个巨大的天线向外辐射电磁波。
2 RS232转RS485模块
1)使用MAX485芯片模块
下面是最常用的TTL串口转RS485电路模块,该模块采用经典的MAX485芯片,使用电路也非常简单,基础上参照其芯片数据手册就可实现。但唯一的缺点是使用软件的方式进行流控,如下图所示的DE和RE引脚,而在Linux系统中,如果在应用层来控制这两个引脚,由于RS485总线对时序的要求,本人没有实现。可能在类似单片机MCU等非运行操作系统的环境下,有较大的应用。而在Linux系统中,需要重新实现相应的驱动。
2)使用RS485 CAN Cape
下面是waveshare(微雪)公司推出的一款BBB Cape的应用,并提供源码,有兴趣的可以尝试。
3)使用自动流控芯片模块
下面的模块,采用了最新的RS485转换芯片,它的优点在于其自带了自动流控功能,即硬件控制,这样在使用过程中,就如使用RS232串口一样来使用,无需关心流控的时序。
3 软件实现
1 接收程序
/* rs485_recv.c */
#include
#include
#include
#include
#include
#define BAUDRATE B19200
#define MODEMDEVICE "/dev/ttyO2"
#define _POSIX_SOURCE 1
int main()
{
int fd, c=0, res;
struct termios oldtio, newtio;
char buf[256];
printf("Start...n");
fd = open(MODEMDEVICE, O_RDWR|O_NOCTTY);
if (fd < 0) {
perror(MODEMDEVICE);
exit(1);
}
printf("Open...n");
tcgetattr(fd, &oldtio);
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = BAUDRATE|CS8|CLOCAL|CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = ICANON;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio);
printf("Reading...n");
while(1) {
res = read(fd, buf, 255);
buf[res]=0;
printf("res=%d buf=%sn", res, buf);
if (buf[0] == \'@\') break;
}
printf("Close...n");
close(fd);
tcsetattr(fd, TCSANOW, &oldtio);
return 0;
}
2 发送程序
/* rs485_send.c */
#include
#include
#include
#include
#include
#define BAUDRATE B19200
#define MODEMDEVICE "/dev/ttyO2"
#define _POSIX_SOURCE 1
#define STOP \'@\'
int main()
{
int fd, c=0, res;
struct termios oldtio, newtio;
char ch;
static char s1[20];
printf("Start...n");
fd = open(MODEMDEVICE, O_RDWR|O_NOCTTY);
if (fd < 0) {
perror(MODEMDEVICE);
exit(1);
}
printf("Open...n");
tcgetattr(fd, &oldtio);
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = BAUDRATE|CS8|CLOCAL|CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = ICANON;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio);
printf("Writing...n");
while(1) {
while((ch=getchar()) != STOP) {
s1[0]=ch;
res=write(fd, s1, 1);
}
s1[0]=ch;
s1[1]=\'n\';
res = write(fd, s1, 2);
break;
}
printf("Close...n");
close(fd);
tcsetattr(fd, TCSANOW, &oldtio);
return 0;
}
关注微信公众号【口袋物联】,微信号为koudaiwulian,更多物联网知识等着你
BeagleBone Green开发板试用帖汇总
|