第七章 RS485串口通信
前言
RS485与RS232类似,也是一种串口通信方式。但是RS485与RS232相比,传送的更远、连接的设备更多。
一、程序设计和仿真
1.proteus仿真
单片机与MAX487接线细节图
2.程序
/RE | DE | 作用 |
0 | 0 | 只接收数据 |
0 | 1 | 接收或发送数据 |
1 | 1 | 只发送数据 |
主机只发送 从机只接收
主机程序
#include <reg52.h>
sbit P1_0=P1^0;//接/RE信号引脚
sbit P1_1=P1^1;//接DE信号引脚
void delay();//声明延时子程序
void main()
{
int tmp;//显示变量
TMOD=0x20;//设置T1为方式2
TH1=0xFD;//设置波特率为9600
TL1=0xFD;
SCON=0x50;//设置串口方式1
PCON=0x00;//SMOD=0,频率不倍增
TR1=1;//定时器1开始计数
P1_0=1;//只发送数据,不接收数据
P1_1=1;
while(1)
{
tmp=1;//显示变量初值设置
while(tmp<=128)//直到最高位为1
{
SBUF=~tmp;//求反后送出,发光二极管低电平亮
while(TI==0);//等待发送完成
TI=0;//发送标志清零
tmp=tmp<<1;//显示变量左移一位
delay();//调用延时子程序
}
}
}
void delay()//延时子程序
{
int i,j;
for(i=0;i<100;i++)
for(j=0;j<1000;j++)
}
从机程序
#include <reg52.h>
sbit P1_0=P1^0;//接/RE信号引脚
sbit P1_1=P1^1;//接DE信号引脚
unsigned char k;//接收数据变量
void delay();
void main()
{
TMOD=0x20;//设置T1为方式2
TH1=0xFD;//设置波特率为9600
TL1=0xFD;
SCON=0x50;//设置串口为方式1
PCON=0x00;
TR1=1;//定时器1开始计数
P1_0=0;//设置信号为只读状态
P1_1=0;
while(1)
{
while(RI==0);//等待接收完毕
k=SBUF;//读缓冲区数据
RI=0;//接收标志位清零
P0=k;//数据送P0口显示
delay();//调用延时子程序
}
}
void delay()
{
int i,j;
for(i=0;i<100;i++)
for(j=0;j<1000;j++)
}
从机区别接收数据
一个从机接收4位及以下数据,一个从机接收4位以上的数据
若将传过来的数据求反就是1、2、4、8、16、32、64、128,4位及以下的数据就是小于等于8的数据。
只需要在显示数据前判断数据是否等于8,若是则显示,否则不予显示。
if(~k<=8)//新加行,将k求反比较是否小于等于8
p0=k;//原有行,在P0口输出数据
这样,就实现的显示4位及以下的数据。同样,4位及以上也很容易,将判断语句改为:
if(~k>8)//新加行,将k求反比较是否大于8
p0=k;//原有行,在P0口输出数据
同时发送和接收
主机程序
#include <reg52.h>
sbit P1_0=P1^0;
sbit P1_1=P1^1;
unsigned char k;//新加行,定义接收变量
void delay();
void main()
{
int tmp;
TMOD=0x20;
TH1=0xFD;
TL1=0xFD;
SCON=0x50;
PCON=0x00;
TR1=1;
P1_0=0;//修改行,将赋值1改为0
P1_1=1;
while(1)
{
tmp=1;
while(tmp<=128)
{
SBUF=~tmp;
while(TI==0);
TI=0;
tmp=tmp<<1;
delay();
}
if(RI)//新加行,若有接收数据到
{
k=SBUF;//新加行,取缓冲区数据
RI=0;//新加行,接收标志位清零
P0=k;//新加行,在P0口接收数据
delay();//新加行,调用延时子程序
P0=0xff;//新加行,P0口数据清除
}
}
}
void delay()
{
int i,j;
for(i=0;i<100;i++)
for(j=0;j<1000;j++);
}
可发送数据的从机程序
#include <reg52.h>
sbit P1_0=P1^0;
sbit P1_1=P1^1;
sbit S=P3^2;
unsigned char k;//新加行,定义一个按钮
void delay();
void main()
{
TMOD=0x20;
TH1=0xFD;
TL1=0xFD;
SCON=0x50;
PCON=0x00;
TR1=1;
P1_0=0;
P1_1=1;//修改行,将0改为1
while(1)
{
while(RI==0);
k=SBUF;
RI=0;
if(~k>8)
P0=k;
delay();
P0=0xff;
if(S==0)//新加行,若按钮按下
{
SBUF=~0x81;//新加行,向缓冲区发送数据
while(TI==0);//新加行,等待发送完毕
TI=0;//新加行,发送标志位清零
}
}
}
void delay()
{
int i,j;
for(i=0;i<100;i++)
for(j=0;j<1000;j++);
}
总结
RS-485看似简单,实际应用的时候还是有很多需要去理解和注意的地方。