一、多機(jī)通信原理
在多機(jī)通信中,主機(jī)必須要能對各個(gè)從機(jī)進(jìn)行識別,在51系列單片機(jī)中可以通過SCON寄存器的SM2位來實(shí)現(xiàn)。當(dāng)串口以方式2或方式3發(fā)送數(shù)據(jù)時(shí),每一幀信息都是11位,第9位是數(shù)據(jù)可編程位,通過給TB8置1或置0來區(qū)別地址幀和數(shù)據(jù)幀,當(dāng)該位為1時(shí),發(fā)送地址幀;該位為0時(shí),發(fā)送數(shù)據(jù)幀。
在多機(jī)通信過程中,主機(jī)先發(fā)送某一從機(jī)的地址,等待從機(jī)的應(yīng)答,所有的從機(jī)接收到地址幀后與本機(jī)地址進(jìn)行比較,若相同,則將SM2置0準(zhǔn)備接收數(shù)據(jù);若不同,則丟棄當(dāng)前數(shù)據(jù),SM2位不變。
二、多機(jī)通信電路圖
此處,U1作為主機(jī),U2為從機(jī)1,U3為從機(jī)2。
三、C語言程序
(1)主機(jī)程序
#include#include
#define _SUCC_0x0f//數(shù)據(jù)傳送成功#define _ERR_0xf0//數(shù)據(jù)傳送失敗unsigned char Table[9]={0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};unsigned char Buff[20];//數(shù)據(jù)緩沖區(qū)unsigned char temp=0xff;sbit KEY1=P1^6;sbit KEY2=P1^7;//unsigned char addr;
//延時(shí)1ms函數(shù)void delay_1ms(unsigned int t){unsigned int x,y;for(x=t;x>0;x--)for(y=110;y>0;y--);}//緩沖區(qū)初始化void Buff_init(){unsigned char i;//將Table里的數(shù)據(jù)放到緩沖區(qū)里for(i=0;i<9;i++)???{??Buff[i]= Table[i];??delay_1ms(100);?}?}//串口初始化函數(shù)void serial_init(){?TMOD=0x20;?//定時(shí)器1工作于方式2?TH1=0xfd;???TL1=0xfd;?//波特率為9600?PCON=0;?SCON=0xd0;??//串口工作于方式3?TR1=1;??//開啟定時(shí)器?TI=0;?RI=0;}//發(fā)送數(shù)據(jù)函數(shù)void SEND_data(unsigned char *Buff){?unsigned char i;?unsigned char lenth;?unsigned char check;?lenth=strlen(Buff);??????//計(jì)算數(shù)據(jù)長度?check=lenth;
TI=0;//發(fā)送數(shù)據(jù)長度TB8=0;//發(fā)送數(shù)據(jù)幀SBUF=lenth;while(!TI);TI=0;for(i=0;i;i++)>
TB8=0;//發(fā)送校驗(yàn)字節(jié)SBUF=check;while(!TI);TI=0;}//向指定從機(jī)地址發(fā)送數(shù)據(jù)void ADDR_data(unsigned addr){while(temp!=addr)//主機(jī)等待從機(jī)返回其地址作為應(yīng)答信號{TI=0;//發(fā)送從機(jī)地址TB8=1;//發(fā)送地址幀SBUF=addr;while(!TI);TI=0;RI=0;while(!RI);temp=SBUF;RI=0;}
temp=_ERR_;//主機(jī)等待從機(jī)數(shù)據(jù)接收成功信號while(temp!=_SUCC_){SEND_data(Buff);RI=0;while(!RI);temp=SBUF;RI=0;}}
void main(){Buff_init();serial_init();while(1){if(KEY1==0){delay_1ms(5);if(KEY1==0){while(!KEY1);ADDR_data(0x01);}}if(KEY2==0){delay_1ms(5);if(KEY2==0){while(!KEY2);ADDR_data(0x02);}}
}}
(2)從機(jī)1程序
#include#include
#define addr0x01//從機(jī)1的地址#define _SUCC_0x0f//數(shù)據(jù)傳送成功#define _ERR_0xf0//數(shù)據(jù)傳送失敗unsigned char aa=0xff;//主機(jī)與從機(jī)之間通信標(biāo)志unsigned char Buff[20];//數(shù)據(jù)緩沖區(qū)
//串口初始化函數(shù)void serial_init(){TMOD=0x20;//定時(shí)器1工作于方式2TH1=0xfd;TL1=0xfd;//波特率為9600PCON=0;SCON=0xd0;//串口工作于方式3TR1=1;//開啟定時(shí)器TI=0;RI=0;}//接收數(shù)據(jù)函數(shù)unsigned char RECE_data(unsigned char *Buff){unsigned char i,temp;unsigned char lenth;unsigned char check;
RI=0;//接收數(shù)據(jù)長度while(!RI);if(RB8==1)//若接收到地址幀,則返回0xfereturn 0xfe;lenth=SBUF;RI=0;check=lenth;for(i=0;i;i++)>
while(!RI);//接收校驗(yàn)字節(jié)if(RB8==1)//若接收到地址幀,則返回0xfereturn 0xfe;temp=SBUF;RI=0;check=temp^check;//將從主機(jī)接收到的校驗(yàn)碼與自己計(jì)算的校驗(yàn)碼比對if(check!=0)//校驗(yàn)碼不一致,表明數(shù)據(jù)接收錯(cuò)誤,向主機(jī)發(fā)送錯(cuò)誤信號,函數(shù)返回0xff{TI=0;TB8=0;SBUF=_ERR_;while(!TI);TI=0;return 0xff;}TI=0;//校驗(yàn)碼一致,表明數(shù)據(jù)接收正確,向主機(jī)發(fā)送成功信號,函數(shù)返回0x00TB8=0;SBUF=_SUCC_;while(!TI);TI=0;return 0;}
void main(){serial_init();while(1){SM2=1;//接收地址幀while(aa!=addr)//從機(jī)等待主機(jī)請求自己的地址{RI=0;while(!RI);aa=SBUF;RI=0;}
TI=0;//一旦被請求,從機(jī)返回自己的地址作為應(yīng)答,等待接收數(shù)據(jù)TB8=0;SBUF=addr;while(!TI);TI=0;
SM2=0;//接收數(shù)據(jù)幀aa=0xff;//從機(jī)接收數(shù)據(jù),并將數(shù)據(jù)保存到數(shù)據(jù)緩沖區(qū)while(aa==0xff){aa=RECE_data(Buff);}if(aa==0xfe)continue;P1=Buff[1];//查看接收到的數(shù)據(jù)}}
(3)從機(jī)2程序
#include#include
#define addr0x02//從機(jī)2的地址#define _SUCC_0x0f//數(shù)據(jù)傳送成功#define _ERR_0xf0//數(shù)據(jù)傳送失敗unsigned char aa=0xff;//主機(jī)與從機(jī)之間通信標(biāo)志unsigned char Buff[20];//數(shù)據(jù)緩沖區(qū)
//串口初始化函數(shù)void serial_init(){TMOD=0x20;//定時(shí)器1工作于方式2TH1=0xfd;TL1=0xfd;//波特率為9600PCON=0;SCON=0xd0;//串口工作于方式3TR1=1;//開啟定時(shí)器TI=0;RI=0;}//接收數(shù)據(jù)函數(shù)unsigned char RECE_data(unsigned char *Buff){unsigned char i,temp;unsigned char lenth;unsigned char check;
RI=0;//接收數(shù)據(jù)長度while(!RI);if(RB8==1)//若接收到地址幀,則返回0xfereturn 0xfe;lenth=SBUF;RI=0;check=lenth;for(i=0;i;i++)>
while(!RI);//接收校驗(yàn)字節(jié)if(RB8==1)//若接收到地址幀,則返回0xfereturn 0xfe;temp=SBUF;RI=0;check=temp^check;//將從主機(jī)接收到的校驗(yàn)碼與自己計(jì)算的校驗(yàn)碼比對if(check!=0)//校驗(yàn)碼不一致,表明數(shù)據(jù)接收錯(cuò)誤,向主機(jī)發(fā)送錯(cuò)誤信號,函數(shù)返回0xff{TI=0;TB8=0;SBUF=_ERR_;while(!TI);TI=0;return 0xff;}TI=0;//校驗(yàn)碼一致,表明數(shù)據(jù)接收正確,向主機(jī)發(fā)送成功信號,函數(shù)返回0x00TB8=0;SBUF=_SUCC_;while(!TI);TI=0;return 0;}
void main(){serial_init();while(1){SM2=1;//接收地址幀while(aa!=addr)//從機(jī)等待主機(jī)請求自己的地址{RI=0;while(!RI);aa=SBUF;RI=0;}
TI=0;//一旦被請求,從機(jī)返回自己地址作為應(yīng)答,等待接收數(shù)據(jù)TB8=0;SBUF=addr;while(!TI);TI=0;
SM2=0;//接收數(shù)據(jù)幀aa=0xff;//從機(jī)接收數(shù)據(jù),并將數(shù)據(jù)保存到數(shù)據(jù)緩沖區(qū)while(aa==0xff){aa=RECE_data(Buff);}if(aa==0xfe)continue;P1=Buff[2];//查看接收到的數(shù)據(jù)}}
-
51單片機(jī)
+關(guān)注
關(guān)注
276文章
5707瀏覽量
125751 -
多機(jī)通信
+關(guān)注
關(guān)注
0文章
16瀏覽量
9259
原文標(biāo)題:51單片機(jī)多機(jī)通信
文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
51單片機(jī)多機(jī)通信問題
51單片機(jī)多機(jī)通信問題
基于51單片機(jī)的多機(jī)通信的設(shè)計(jì)+源代碼
PC機(jī)與多MCS-51單片機(jī)間的串行通信設(shè)計(jì)?

51單片機(jī)多機(jī)通信過程
單片機(jī)之間多機(jī)通信演示電路設(shè)計(jì)
8031單片機(jī)多機(jī)系統(tǒng)的實(shí)時(shí)通信
如何使用51單片機(jī)進(jìn)行多機(jī)通信的資料和程序及電路圖免費(fèi)下載

單片機(jī)多機(jī)通信系統(tǒng)的設(shè)計(jì)

MCS-51單片機(jī)多機(jī)通信的工作原理解析

評論