提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
在自动化领域,随着分布式控制系统的发展,迫切需要一种总线能适合远距离的数字通信。在rs-422标准的基础上,eia研究出了一种支持多节点、远距离和接收高灵敏度的rs-485总线标准。
rs-485标准采用平衡式发送,差分式接收的数据收发器来驱动总线,具体规格要求:
1. 接收器的输入电阻rin≥12kΩ
2. 驱动器能输出±7v的共模电压
3.输入端的电容≤50pf
4. 在节点数为32个,配置了120Ω的终端电阻的情况下,驱动器至少还能输出电压1.5v(终端电阻的大小与所用双绞线的参数有关)
5.接收器的输入灵敏度为200mv即(v+)-(v-)≥0.2v,表示信号"0";(v+)-(v-)≤-0.2v,表示信号"1"
因为rs-485的远距离、多节点(32个)以及传输线成本低的特性,使得eia rs-485成为工业应用中数据传输的首选标准。基于此,rs-485的自动化领域的应用非常广泛。
提示:以下是本篇文章正文内容,下面案例可供参考
一、RS485引脚功能
这里以芯力特的485芯片为例如图1:
引脚功能:
1.接收器输出端(接单片机的RXD引脚)
2.接收器输出使能控制(接收器输出使能控制。当/RE 接低电平时RO 输出有效;当/RE 接高电平时RO 为高阻态)
3.驱动器输出使能控制(DE 接高电平时驱动器输出有效,DE 为低电平时输出为高阻态)
4.DI驱动器输入(接单片机的TXD引脚)
5.接地
6.接收器同相输入和驱动器同相输出端
7.接收器反相输入和驱动器反相输出端
8.接电源
二、RS485驱动程序
1.串口初始化程序
void Uart()
{
EA = 1; //打开总中断
ES = 1; //打开串口中断
TR1 = 1; //打开定时器1
REN = 1; //允许串口接收
SCON = 0X50; //串口1 可变波特率8位数据方式
TMOD = 0X20; //定时器1 8位自动重装模式
TL1 = 0XDC; //
TH1 = 0XDC; //波特率9600
PCON = 0X00; //波特率不加倍
AUXR = 0X40; //辅助寄存器 时钟不分频
}
2.串口中断服务程序
代码如下(示例):
void UartIsr()interrupt 4
{
if(TI == 1) //发送标志位是否为1
{
TI = 0; //置位发送标志位
sending=0; //置0发送标志位
}
if(RI == 1) //接收标志位是否为1
{
RI = 0; //置位接收标志位
num[ix++] = SBUF; //将接收到的数据赋给num数组的第ix++个
if(ix > 8) //判断ix是否加到8之上了 代表已经接收完成
{
ix = 0; //置0 ix标志位
}
}
}
这里的num[ ]数组用来接收RS485发送过来的数据,定义为全局变量num[30],这里定义长度为30,因为不确定长度所以尽量定义长一点。
2.RS485解码程序
代码如下(示例):
void Read_Rs485()
{
if(num[0] == 'x' && num[5] == 'y' && num[ix-1] == '\n') //判断接收到的第1位和第5位和第ix-1位是否分别为“x”,“y”,“\n”
{ //ix-1位是要适配不等长的数据,因为前面用的是i++,所以ix-1才是最后一位
switch(num[1]) //判断接收到的第二个数据 车速的百位
{
case '0' : LD_Sd[0] = 0; break; //如果是字符串“0” 那么LD_Sd[0]就为0
case '1' : LD_Sd[0] = 100; break; //如果是字符串“1” 那么LD_Sd[0]就为100
}
switch(num[2]) //判断接收到的第三个数据 车速的十位
{
case '0' : LD_Sd[1] = 0; break; //如果是字符串“0” 那么LD_Sd[1]就为0
case '1' : LD_Sd[1] = 10; break; //如果是字符串“1” 那么LD_Sd[1]就为10
case '2' : LD_Sd[1] = 20; break; //如果是字符串“2” 那么LD_Sd[1]就为20
case '3' : LD_Sd[1] = 30; break; //如果是字符串“3” 那么LD_Sd[1]就为30
case '4' : LD_Sd[1] = 40; break; //如果是字符串“4” 那么LD_Sd[1]就为40
case '5' : LD_Sd[1] = 50; break; //如果是字符串“5” 那么LD_Sd[1]就为50
case '6' : LD_Sd[1] = 60; break; //如果是字符串“6” 那么LD_Sd[1]就为60
case '7' : LD_Sd[1] = 70; break; //如果是字符串“7” 那么LD_Sd[1]就为70
case '8' : LD_Sd[1] = 80; break; //如果是字符串“8” 那么LD_Sd[1]就为80
case '9' : LD_Sd[1] = 90; break; //如果是字符串“9” 那么LD_Sd[1]就为90
}
switch(num[3]) //判断接收到的第四个数据 车速的个位
{
case '0' : LD_Sd[2] = 0; break; //如果是字符串“0” 那么LD_Sd[2]就为0
case '1' : LD_Sd[2] = 1; break; //如果是字符串“1” 那么LD_Sd[2]就为1
case '2' : LD_Sd[2] = 2; break; //如果是字符串“2” 那么LD_Sd[2]就为2
case '3' : LD_Sd[2] = 3; break; //如果是字符串“3” 那么LD_Sd[2]就为3
case '4' : LD_Sd[2] = 4; break; //如果是字符串“4” 那么LD_Sd[2]就为4
case '5' : LD_Sd[2] = 5; break; //如果是字符串“5” 那么LD_Sd[2]就为5
case '6' : LD_Sd[2] = 6; break; //如果是字符串“6” 那么LD_Sd[2]就为6
case '7' : LD_Sd[2] = 7; break; //如果是字符串“7” 那么LD_Sd[2]就为7
case '8' : LD_Sd[2] = 8; break; //如果是字符串“8” 那么LD_Sd[2]就为8
case '9' : LD_Sd[2] = 9; break; //如果是字符串“9” 那么LD_Sd[2]就为9
}
for(q=0; q<ix; q++) //清除接收到的数据
{
num[q] = 0; //清除num第q个数据
}
ix = 0; //置0 ix标志位
}
}
因为我接收的是24G毫米波雷达发过来的车辆速度值,所以定义了一个数组LD_Sd[4]用来存放解码后得到的数据。在接收完成后一定要把接收数组里面的数据清除,并且将ix标志位清零。具体原理都在程序注释里面。
3.RS485发送程序
void send(unsigned char d) //发送一个字节的数据,形参d即为待发送数据。
{
SBUF=d; //将数据写入到串口缓冲
sending=1; //设置发送标志
while(sending); //等待发送完毕
}
/************************************************************************************************/
/*函数名:发送字符串函数 */
/*功能:使用串口发送字符串 */
/************************************************************************************************/
void sendc(unsigned char * pd)
{
while((*pd)!='\0') //发送字符串,直到遇到0才结束
{
send(*pd); //发送一个字符
pd++; //移动到下一个字符
}
}
/************************************************************************************************/
/*函数名:雷达初始化函数 */
/*功能:设置雷达模块的初值,灵敏度/刷新率/速度方向,带加解锁 */
/************************************************************************************************/
void Send_Start()
{
RS485 = 1; //拉高485控制接口,选择为发送数据
sendc(Unlock); //解锁
Delay(10); //延时10毫秒
sendc(Lmd); //灵敏度 设置为5
Delay(10); //延时10毫秒
sendc(Sxl); //刷新率 设置为0
Delay(10); //延时10毫秒
sendc(Fx); //方向 设置为仅来向
Delay(10); //延时10毫秒
sendc(lock); //加锁
Delay(20); //延时20毫秒
RS485 = 0; //拉低485控制接口,选择为接收数据
}
这里的RS485为接收/发送,当RS485为0的时候,是接收数据,当RS485为1的时候,是发送数据。
总结
以上RS485接收不等长混合数据的代码,然后对一个24G毫米波雷达发送的数据进行解码和修改参数,每段代码都打上了注释,很好理解的。