国产免费AV|泡泡玛特欧洲总部将设在伦敦|中文天堂网www新版资源在线|一本久道综合在线中文|国精产品一二三产区的使用方法|香蕉鱼在线观看|www.27eee
ELEOK
標題:
51單片機MAX487實現RS485通信程序Proteus仿真
[打印本頁]
作者:
eng
時間:
2021-6-14 02:35
標題:
51單片機MAX487實現RS485通信程序Proteus仿真
RS-485總線標準規定了總線接口的電氣特性標準即對于2個邏輯狀態的定義:正電平在+2V~+6V之間,表示一個邏輯狀態;負電平在-2V~-6V之間,則表示另一個邏輯狀態;數字信號采用差分傳輸方式,能夠有效減少噪聲信號的干擾。RS-485工業總線標準能夠有效支持多個分節點和通信距離遠,并且對于信息的接收靈敏度較高等特性。在工業通信網絡中,RS-485總線一般主要用于與外部各種工業設備進行信息傳輸和數據交換,所具備的對于噪聲的有效抑制能力、高效的數據傳輸速率與良好的數據傳輸的可靠性能以及可擴展的通信電纜的長度是其他的許多工業通信標準所無法比擬的。因此,RS-485總線在諸多個領域得到了廣泛的應用,比如在工業控制領域、交通的自動化控制領域和現場總線通信網絡等。
RS-485接口的最大傳輸距離標準值為4000英尺,實際上可達 3000米(理論上的數據,在實際操作中,極限距離僅達1200米左右),另外RS-232-C接口在總線上只允許連接1個收發器,即單站能力。RS485接口在總線上是允許連接多達128個收發器。即具有多站能力,這樣用戶可以利用單一的RS-485接口方便地建立起設備網絡。
本例程為STC89C52+RS485模塊組成的“一主兩從”模型。從機可拓展多位,修改主、從機地址即可。
本資料包含源文件、仿真程序。實測通過。
完整程序代碼和proteus仿真文件下載
RS485多機通信-1602顯示從機信息.zip
(180.8 KB, 售價: 5 E幣)
2023-5-17 09:16 上傳
點擊文件名下載附件
售價: 5 E幣
[記錄]
[
購買
]
2.png
(9.71 KB)
下載附件
2021-6-14 02:32 上傳
MAX487仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
1.png
(270.45 KB)
下載附件
2021-6-14 02:31 上傳
部分源碼:完整源碼見附件
#include<reg51.h>
#include<string.h>
#include "lcd.h"
#define _SUCC_ 0x0f//數據傳送成功
#define _ERR_ 0xf0//數據傳送失敗
unsigned char aa=0xff;//主機與從機之間通信標志
unsigned char temp=0xff;
unsigned char Buff[20];//數據緩沖區
unsigned char recive[6]; //用于保存從機發送的數據
sbit KEY1=P1^3;
sbit KEY2=P1^2;
sbit KEY3=P1^1;
sbit KEY4=P1^0;
sbit KEY5=P3^2;
sbit KEY6=P3^3;
//sbit KEY5=P1^4;
//sbit KEY6=P1^5;
//延時1ms函數
void delay_1ms(unsigned int i)
{
unsigned int x,y;
for(x=i;x>0;x--)
for(y=110;y>0;y--);
}
//串口初始化函數
void init()
{
TMOD=0x20; //定時器1工作于方式2
TH1=0xfd;
TL1=0xfd; //波特率為9600
PCON=0;
SCON=0xd0; //串口工作于方式3
TR1=1; //開啟定時器
TI=0;
RI=0;
}
//發送數據函數
void SEND_data(unsigned char *Buff)
{
unsigned char i,lenth,check;
lenth=strlen(Buff); //計算數據長度
check=lenth;
TI=0; //發送數據長度
TB8=0; //發送數據幀
SBUF=lenth;
while(!TI);
TI=0;
for(i=0;i<lenth;i++) //發送數據
{
check=check^Buff[i];
TB8=0;
SBUF=Buff[i];
while(!TI);
TI=0;
}
TB8=0; //發送校驗字節
SBUF=check;
while(!TI);
TI=0;
}
//接收數據函數
unsigned char RECE_data(unsigned char *Buff)
{
unsigned char i;
unsigned char lenth;
unsigned char check;
RI=0; //接收數據長度
while(!RI);
if(RB8==1)
{
RI = 0;
return 0xfe; //若接收到地址幀,則返回0xfe
}
lenth=SBUF;
RI=0;
check=lenth;
for(i=0;i<lenth;i++) //接收數據
{
while(!RI);
if(RB8==1) //若接收到地址幀,則返回0xfe
return 0xfe;
Buff[i]=SBUF;
check=check^(Buff[i]);
RI=0;
}
while(!RI); //接收校驗字節
if(RB8==1) //若接收到地址幀,則返回0xfe
return 0xfe;
temp=SBUF;
RI=0;
check=temp^check; //將從主機接收到的校驗碼與自己計算的校驗碼比對
if(check!=0) //校驗碼不一致,表明數據接收錯誤,向主機發送錯誤信號,函數返回0xff
{
TI=0;
TB8=0;
SBUF=_ERR_;
while(!TI);
TI=0;
return 0xff;
}
TI=0; //校驗碼一致,表明數據接收正確,向主機發送成功信號,函數返回0x00
TB8=0;
SBUF=_SUCC_;
while(!TI);
TI=0;
return 0;
}
//發送從機地址
void ADDR_data(unsigned addr)
{
while(temp!=addr) //主機等待從機返回其地址作為應答信號
{
TI=0; //發送從機地址
TB8=1; //發送地址幀
SBUF=addr;
while(!TI);
TI=0;
RI=0;
while(!RI);
temp=SBUF;
RI=0;
}
}
void keyscan()
{
if(KEY1==0)
{
LcdWriteCom(0x01); //清屏
delay_1ms(5);
if(KEY1==0)
{
while(!KEY1);
ADDR_data(0x01);//發送從機地址
temp=_ERR_; //主機等待從機數據接收成功信號
while(temp!=_SUCC_)
{
unsigned char Buff[]={0xfe};
SEND_data(Buff);//發送數據
RI=0;
while(!RI);
temp=SBUF;
RI=0;
}
SM2=0; //接收數據幀
aa=0xff; //從機接收數據,并將數據保存到數據緩沖區
while(aa==0xff)
{
aa=RECE_data(Buff);
P0 = 0xff;
}
P0 = 0xfe;
recive[0] = Buff[0];
recive[1] = Buff[1];
recive[2] = Buff[2];
}
}
if(KEY2==0)
{
LcdWriteCom(0x01); //清屏
delay_1ms(5);
if(KEY2==0)
{
while(!KEY2);
ADDR_data(0x01);
temp=_ERR_; //主機等待從機數據接收成功信號
while(temp!=_SUCC_)
{
unsigned char Buff[]={0xff};
SEND_data(Buff);
RI=0;
while(!RI);
RI=0;
temp=SBUF;
}
}
}
if(KEY3==0)
{
LcdWriteCom(0x01); //清屏
delay_1ms(5);
if(KEY3==0)
{
while(!KEY3);
ADDR_data(0x02);
temp=_ERR_; //主機等待從機數據接收成功信號
while(temp!=_SUCC_)
{
unsigned char Buff[]={0xfe};
SEND_data(Buff);
RI=0;
while(!RI);
temp=SBUF;
RI=0;
}
SM2=0; //接收數據幀
aa=0xff; //從機接收數據,并將數據保存到數據緩沖區
while(aa==0xff)
{
aa=RECE_data(Buff);
P0 = 0xff;
}
P0 = 0xfe;
/*
recive[3] = Buff[0];
recive[4] = Buff[1];
recive[5] = Buff[2];
*/
recive[0] = Buff[0];
recive[1] = Buff[1];
recive[2] = Buff[2];
}
}
if(KEY4==0)
{
LcdWriteCom(0x01); //清屏
delay_1ms(5);
if(KEY4==0)
{
while(!KEY4);
ADDR_data(0x02);
temp=_ERR_; //主機等待從機數據接收成功信號
while(temp!=_SUCC_)
{
unsigned char Buff[]={0xff};
SEND_data(Buff);
RI=0;
while(!RI);
temp=SBUF;
RI=0;
}
}
}
if(KEY5==0)
{
LcdWriteCom(0x01); //清屏
delay_1ms(5);
if(KEY5==0)
{
while(!KEY5);
ADDR_data(0x01);
temp=_ERR_; //主機等待從機數據接收成功信號
while(temp!=_SUCC_)
{
unsigned char Buff[]={0xff};
SEND_data(Buff);
RI=0;
while(!RI);
temp=SBUF;
RI=0;
}
ADDR_data(0x02);
temp=_ERR_; //主機等待從機數據接收成功信號
while(temp!=_SUCC_)
{
unsigned char Buff[]={0xff};
SEND_data(Buff);
RI=0;
while(!RI);
temp=SBUF;
RI=0;
}
}
}
if(KEY6==0)
{
LcdWriteCom(0x01); //清屏
delay_1ms(5);
if(KEY6==0)
{
while(!KEY6);
ADDR_data(0x01);
temp=_ERR_; //主機等待從機數據接收成功信號
while(temp!=_SUCC_)
{
unsigned char Buff[]={0xff};
SEND_data(Buff);
RI=0;
while(!RI);
temp=SBUF;
RI=0;
}
ADDR_data(0x02);
temp=_ERR_; //主機等待從機數據接收成功信號
while(temp!=_SUCC_)
{
unsigned char Buff[]={0xff};
SEND_data(Buff);
RI=0;
while(!RI);
temp=SBUF;
RI=0;
}
}
}
}
void main()
{
init();
LcdInit(); //初始化LCD1602
LcdWriteCom(0x01);
while(1)
{
keyscan();
LcdWriteData(recive[0]);
LcdWriteData(recive[1]);
LcdWriteData(recive[2]);
/*
LcdWriteData(recive[3]);
LcdWriteData(recive[4]);
LcdWriteData(recive[5]);
*/
LcdWriteCom(0x80);
}
}
復制代碼
歡迎光臨 ELEOK (http://m.afoofa.cn/)
Powered by Discuz! X5.0