当先锋百科网

首页 1 2 3 4 5 6 7

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

	在自动化领域,随着分布式控制系统的发展,迫切需要一种总线能适合远距离的数字通信。在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毫米波雷达发送的数据进行解码和修改参数,每段代码都打上了注释,很好理解的。