嵌入式单片机基础篇(三十七)之485通讯以及51单片机程序
嵌入式单片机基础篇(三十七)之485通讯以及51单片机程序
485通讯以及51单片机程序
1、485接口:
485(一般称作RS485/EIA-485)是隶属于OSI模型物理层的电气特性规定为2线,半双工,多点通信的标准。它的电气特性和RS-232大不一样。用缆线两端的电压差值来表示传递信号。RS485仅仅规定了接受端和发送端的电气特性。它没有规定或推荐任何数据协议。
2、RS485的特点包括:
(1)接口电平低,不易损坏芯片。RS485的电气特性:逻辑“1”以两线间的电压差为+(26)V表示;逻辑“0”以两线间的电压差为-(26)V表示。接口信号电平比RS232降低了,不易损坏接口电路的芯片。
(2) 传输速率高。10米时,RS485的数据最高传输速率可达35Mbps,在1200m时,传输速度可达100Kbps。
(3)抗干扰能力强。RS485接口是采用平衡驱动器和差分接收器的组合,抗共模干扰能力增强,即抗噪声干扰性好。
(4)传输距离远,支持节点多。RS485总线最长可以传输1200m以上(速率 ≤100Kbps)一般最大支持32个节点,如果使用特制的485芯片,可以达到128个或者256个节点,最大的可以支持到400个节点。
(5)RS485推荐使用在点对点网络中,线型,总线型,不能是星型,环型网络。理想情况下RS485需要2个匹配电阻,其阻值要求等于传输电缆的特性阻抗(一般为120Ω)。没有特性阻抗的话,当所有的设备都静止或者没有能量的时候就会产生噪声,而且线移需要双端的电压差。没有终接电阻的话,会使得较快速的发送端产生多个数据信号的边缘,导致数据传输出错。485推荐的连接方式:
在上面的连接中,如果需要添加匹配电阻,我们一般在总线的起止端加入,也就是主机和设备4上面各加一个120Ω的匹配电阻。
3、收发器SP3485
图中A、B总线接口,用于连接485总线。RO是接收输出端,DI是发送数据收入端,RE是接收使能信号(低电平有效),DE是发送使能信号(高电平有效)。
4、51单片机程序:
(1)主机程序:
#include<reg52.h>typedef unsigned char uchar;sbit key=P3^4;sbit KEY=P1^0;void delay_50ms (unsigned int n){ unsigned int i;for( ;n>0;n--)for(i=6245;i>0;i--);}void myuart(){SCON=0X90; TMOD=0X20; //8位重装载PCON=0X00;TH1=0xFD; TL1=0XFD; //设置波特率为9600ES=1; //打开通信中断EA=1; //打开总中断TR1=1; //打开计数器}void main(void){myuart();while(1){ if(KEY==0){ delay_50ms (1);if(KEY==0){key=1;ES=0; EA=0; SBUF=0Xaa;while(!TI); //等待发送数据完成TI=0; //清除发送完成标志位delay_50ms (1);}while(!KEY);}else{ES=1; //打开通信中断EA=1; //打开总中断key=0;}}}void ser_int (void) interrupt 4 {unsigned char receivedata;key=0;while(!RI);receivedata=SBUF;//出去,接,收到的数据RI = 0;//清除接收中断标志位P2=receivedata;//出去,接,收到的数据delay_50ms (50);P2=0xFF;}
(2)从机程序:
#include<reg52.h>
#include <intrins.h>typedef unsigned char uchar;sbit key=P3^4;sbit SH=P1^1;sbit DS=P1^2;sbit ST=P1^3;sbit KEY=P1^0;const uchar code a[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0123456789const uchar code b[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};void delay_50ms (unsigned int n){ unsigned int i;for( ;n>0;n--)for(i=6245;i>0;i--);}
void senddate(uchar num,uchar dat)
{uchar i;ST = 0;SH =0;for(i=0;i<8;i++){SH =0;if(num>=0x80)DS=1;else DS= 0;num<<=1;SH= 1;}for(i=0;i<8;i++){SH =0;if(dat>=0x80)DS=1;else DS= 0;dat<<=1;SH= 1;}ST = 0;ST = 1;ST = 0;SH =0;DS=0;
}void myuart(){SCON=0X90; TMOD=0X20; //8位重装载PCON=0X00;TH1=0xFD; TL1=0XFD; //设置波特率为9600ES=1; //打开通信中断EA=1; //打开总中断TR1=1; //打开计数器}void main(void){myuart();while(1)
{ if(KEY==0){delay_50ms (1);if(KEY==0){key=1;EA=0;ES=0;SBUF=0x0a;//将接收到的数据放入到发送寄存器while(!TI); //等待发送数据完成TI=0; //清除发送完成标志位delay_50ms (1);}while(!KEY);}else{ES=1; //打开通信中断EA=1; //打开总中断key=0;}}} void ser_int (void) interrupt 4 {unsigned char receivedata;key=0;receivedata=SBUF;//出去,接,收到的数据while(!RI);RI = 0;//清除接收中断标志位if(receivedata==0xaa){int i;for(i=0;i<8;i++){senddate(b[i],a[i]);delay_50ms (10);}}}