| 課程名稱 | 單片機原理及應(yīng)用 | 實驗課時 | 4 |
實驗項目 | 雙機通信實驗 | 實驗時間 | 2018.6.13/2018.6.20 |
指導(dǎo)老師 | 胡國華 | 實驗成績 | |
實驗?zāi)康模ū敬紊蠙C實驗所涉及并要求掌握的知識點) | 掌握雙機通信的基本使用方法,掌握雙機通信程序的編程方法 | ||
實驗環(huán)境 | Protues仿真軟件 KellC51 集成開發(fā)環(huán)境 微機1臺 | ||
實驗內(nèi)容 | 實驗一:方式一的應(yīng)用設(shè)計 一、實驗內(nèi)容 單片機甲、乙雙機串行通信,雙機RXD和TXD相互交叉相連,甲機P1口接8個開關(guān),乙機P1口接8個發(fā)光二極管。甲機設(shè)置為只能發(fā)送不能接收的單工方式。要求甲機讀入P1口的8個開關(guān)的狀態(tài)后,通過串行口發(fā)送到乙機,乙機將接收到的甲機的8個開關(guān)的狀態(tài)數(shù)據(jù)送入P1口,由P1口的8個發(fā)光二極管來顯示8個開關(guān)的狀態(tài)。雙方晶振均采用11.0592MHz! 二、實驗原理及步驟 三、電路設(shè)計及調(diào)試 (1)實驗電路 file:///C:/Users/zyt/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg (2)程序設(shè)計及調(diào)試 甲機: #include <reg51.h> #define uchar unsigned char #define uint unsigned int void main() { uchar temp=0; TMOD=0x20; //設(shè)置定時器T1為方式2 TH1=0xfd; //波特率9600 TL1=0xfd; SCON=0x40; //串口初始化方式1發(fā)送,不接收 PCON=0x00; // SMOD=0 TR1=1; //啟動T1 P1=0xff; //設(shè)置P1口為輸入 while(1) { while(TI==0); //如果TI=0,未發(fā)送完,循環(huán)等待 TI=0; //已發(fā)送完,把TI清0 temp=P1; //讀入P1口開關(guān)的狀態(tài)數(shù)據(jù) SBUF=temp;}} //數(shù)據(jù)送串行口發(fā)送 乙機: #include <reg51.h> #define uchar unsigned char #define uint unsigned int void main( ) { uchar temp=0; TMOD=0x20; //設(shè)置定時器T1為方式2 TH1=0xfd; //波特率9600 TL1=0xfd; SCON=0x50; //設(shè)置串口為方式1接收,REN=1 PCON=0x00; //SMOD=0 TR1=1; //啟動T1 while(1) { while(RI==0); // 若RI為0,未接收到數(shù)據(jù) RI=0; // 接收到數(shù)據(jù),則把RI清0 temp=SBUF; // 讀取數(shù)據(jù)存入temp中 P1=temp;}} // 接收的數(shù)據(jù)送P1口控制8個LED的亮與滅 實驗二:多機通信的應(yīng)用設(shè)計 一、實驗內(nèi)容 實現(xiàn)主單片機分別與3個從單片機串行通信,原理電路見圖。用戶通過分別按下開關(guān)k1、k2或k3來選擇主機與對應(yīng)1#、2#或3#從機串行通信,當(dāng)黃色LED點亮,表示主機與相應(yīng)的從機連接成功;該從機的8個綠色LED閃亮,表示主機與從機在進行串行數(shù)據(jù)通信。如果斷開k1、k2或 k3,則主機與相應(yīng)從機的串行通信中斷! 二、實驗原理及步驟 1. 實現(xiàn)主、從機串行通信,各從機程序都相同,只是地址不同。 串行通信約定如下。 。1)3臺從機的地址為01H~03H。 。2)主機發(fā)出的0xff為控制命令,使所有從機都處于SM2=1的狀態(tài)。 (3)其余的控制命令:00H—接收命令,01H—發(fā)送命令。這兩條命令是以數(shù)據(jù)幀的形式發(fā)送的。 。4)從機的狀態(tài)字如圖所示。 file:///C:/Users/zyt/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg 其中: ERR(D7位)=1,表示收到非法命令。 TRDY(D1位)=1,表示發(fā)送準(zhǔn)備完畢。 RRDY(D0位)=1,表示接收準(zhǔn)備完畢。 串行通信時,主機采用查詢方式,從機采用中斷方式。主機串口設(shè)為方式3,允許接收,并置TB8為1。因只有1個主機,所以主機SCON控制寄存器中的SM2不要置1,故控制字為11011000,即0xd8! 三、電路設(shè)計及調(diào)試 (1)實驗電路 file:///C:/Users/zyt/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg (2)程序設(shè)計及調(diào)試 //主機程序 #include <reg51.h> #include <math.h> sbit switch1=P0^0; //定義k1與P0.0連接 sbit switch2=P0^1; //定義k2與P0.1連接 sbit switch3=P0^2; //定義k3與P0.2連接 void main() //主函數(shù) { EA=1; //總中斷允許 TMOD=0x20; //設(shè)置定時器T1 定時方式2 自動裝載定時常數(shù) TL1=0xfd; //波特率設(shè)為9600 TH1=0xfd; PCON=0x00; //SMOD=0,不倍增 SCON=0xd0; //SM2設(shè)為0,TB8設(shè)為0 TR1=1; //啟動定時器T1 ES=1; //允許串口中斷 SBUF=0xff; //串口發(fā)送0xff while(TI==0); //判是否發(fā)送完畢 TI=0; //發(fā)送完畢,TI清0 while(1) { delay_ms(100); if(switch1==0) //判是否k1按下,k1按下往下執(zhí)行 { TB8=1; //發(fā)送的第9位數(shù)據(jù)為1,送TB8,準(zhǔn)備發(fā)地址幀 SBUF=0x01;//串口發(fā)1#從機的地址0x01以及TB8=1 while(TI==0); //判是否發(fā)送完畢 TI=0; //發(fā)送完畢,TI清0 TB8=0; //發(fā)送的第9位數(shù)據(jù)為0,送TB8,準(zhǔn)備發(fā)數(shù)據(jù)幀 SBUF=0x00; //串口發(fā)送0x00以及TB8=0 while(TI==0); /判是否發(fā)送完畢 TI=0; //發(fā)送完畢,TI清0 } if(switch2==0) //判是否k2按下,k2按下往下執(zhí)行 { TB8=1; //發(fā)送的第9位數(shù)據(jù)為1,發(fā)地址幀 SBUF=0x02; //串口發(fā)2#從機的地址0x02 while(TI==0); /判是否發(fā)送完畢 TI=0; //發(fā)送完畢,TI清0 TB8=0; //準(zhǔn)備發(fā)數(shù)據(jù)幀 SBUF=0x00; //發(fā)數(shù)據(jù)幀0x00及TB8=0 while(TI==0); //判是否發(fā)送完畢 TI=0; //發(fā)送完畢,TI清0 } if(switch3==0) //判是否k3按下,如按下,則往下執(zhí)行 { TB8=1; //準(zhǔn)備發(fā)地址幀 SBUF=0x03; //發(fā)3#從機地址 while(TI==0); //判是否發(fā)送完畢 TI=0; //發(fā)送完畢,TI清0 TB8=0; //準(zhǔn)備發(fā)數(shù)據(jù)幀 SBUF=0x00; //發(fā)數(shù)據(jù)幀0x00及TB8=0 while(TI==0); //判是否發(fā)送完畢 TI=0; //發(fā)送完畢,TI清0 } } } void delay_ms(unsigned int i) //函數(shù)功能:延時 { unsigned char j; for(;i>0;i--) for(j=0;j<125;j++) ; } //從機1串行通信程序 #include <reg51.h> #include <math.h> sbit led=P2^0; //定義P2.0連接的黃色LED bit rrdy=0; //接收準(zhǔn)備標(biāo)志位rrdy=0,表示未做好接收準(zhǔn)備 bit trdy=0; //發(fā)送準(zhǔn)備標(biāo)志位trdy=0,表示未做好發(fā)送準(zhǔn)備 bit err=0; //err=1,表示接收到的命令為非法命令 void main() //從機1主函數(shù) { EA=1; //總中斷打開 TMOD=0x20;//定時器1 工作方式2,自動裝載,用于串口設(shè)置波特率 TL1=0xfd; TH1=0xfd; //波特率設(shè)為9600 PCON=0x00; // SMOD=0 SCON=0xd0; //SM2設(shè)為0,TB8設(shè)為0 TR1=1; //啟動定時器T1 P1=0xff; // 向P1寫入全1,8個綠色LED全滅 ES=1; //允許串口中斷 while(RI==0); //接收控制指令0xff if(SBUF==0xff) err=0; //如果接收到的數(shù)據(jù)為0xff,err=0,表示正確 else err=1; //err=1,表示接收出錯 RI=0; //接收中斷標(biāo)志清0 SM2=1; //多機通訊控制位,SM2置1 while(1);} void int1() interrupt 4, //函數(shù)功能:定時器T1中斷函數(shù) { if(RI) //如果RI=1 { if(RB8) //如果RB8=1,表示接收的為地址幀 { RB8=0; if(SBUF==0x01) //如收的數(shù)據(jù)為地址幀0x01,是本從機的地址 { SM2=0; //則SM2清0,準(zhǔn)備接收數(shù)據(jù)幀 led=0; //點亮本從機黃色發(fā)光二極管 } } led=1; // 熄滅本從機黃色發(fā)光二極管 } RI=0; } | ||
delay_ms(50); P1=0xff; //熄滅本從機8個綠色發(fā)光二極管 } void delay_ms(unsigned int i) //函數(shù)功能:延時 { unsigned char j; for(;i>0;i--) for(j=0;j<125;j++) ;} //從機2串行通信程序 #include <reg51.h> #include <math.h> sbit led=P2^0; bit rrdy=0; bit trdy=0; bit err=0; void delay_ms(unsigned int i) {unsigned char j; for(;i>0;i--) for(j=0;j<125;j++;} void main() //從機2主程序 { EA=1; //總中斷打開 TMOD=0x20;//定時器1 工作方式2 自動裝載 用于串口設(shè)置波特率 TL1=0xfd; //SM2設(shè)為1, TB8設(shè)為0 TR1=1; //定時器1 打開 P1=0xff; ES=1; //允許串口中斷 while(RI==0); //接收控制指令 0xff if(SBUF==0xff) err=0; else err=1; RI=0; SM2=1; while(1); } void int1() interrupt 4 //函數(shù)功能:串口中斷函數(shù) {if(RI) {if(RB8) {RB8=0; if(SBUF==0x02) {SM2=0; led=0; } } else { rrdy=1;P1=SBUF; SM2=1;led=1; } RI=0; } delay_ms(50); P1=0xff;} //從機3串行通信程序 #include <reg51.h> #include <math.h> sbit led=P2^0; bit rrdy=0; bit trdy=0; bit err=0; void delay_ms(unsigned int i) //函數(shù)功能:延時 {unsigned char j; for(;i>0;i--) for(j=0;j<125;j++); } void main() //從機3主程序 { EA=1; //總中斷打開 TMOD=0x20; //T1方式2,用于串口設(shè)置波特率 TL1=0xfd;TH1=0xfd; //波特率設(shè)為9600 PCON=0x00; //波特率不倍增 0x80 為倍增 SCON=0xf0; //SM2設(shè)為1,TB8設(shè)為0 TR1=1; //接通T1 P1=0xff;ES=1; while(RI==0); //接收控制指令 0xff if(SBUF==0xff) err=0; else err=1; RI=0;SM2=1; while(1);} void int1() interrupt 4 //函數(shù)功能:串行口中斷函數(shù) {if(RI) {if(RB8) { RB8=0; if(SBUF==0x03) { SM2=0;led=0;} } else {rrdy=1;P1=SBUF; SM2=1;led=1; } RI=0; } delay_ms(50); P1=0xff;} (3)實驗中遇到的問題 按下單片機相應(yīng)的按鈕,小燈泡不亮。 | |||
總結(jié)(對上機實驗結(jié)果進行分析,上機心得體會及改進意見 | 實驗一:按下按鈕后,通過開關(guān)可以通過開關(guān)控制燈泡的亮滅, 實驗二:串行通信時,主機采用查詢方式,從機采用中斷方式。主機串行口設(shè)為方式3,允許接收,并置TB8為1.因為只有一個主機,所以主機的SCON控制寄存器中的SM2不要置1,故控制字為11011000,即0xd8.這個實驗實現(xiàn)主從機的串行通信,各從機的程序都是相同的,只是地址不同。串行通信的約定如下: (1)3臺從機的地址為01H~03H。 (2)主機發(fā)出的0xff為控制命令,使所有從機都處于SM2=1的狀態(tài)。 (3)其余的控制命令:00H—接收命令,01H—發(fā)送命令。這兩條命令是以數(shù)據(jù)幀的形式發(fā)送的。 (4)從機的狀態(tài)字如圖所示! file:///C:/Users/zyt/AppData/Local/Temp/msohtmlclip1/01/clip_image007.jpg 本次實驗增強了我們的探索能力,不意味的依賴答案,而是自己尋求解題思路,在一號的學(xué)習(xí)中起到了特別大的幫助。本次試驗教會我們很多內(nèi)容,特別是在遇到問題是如何去處理,如何正確的找到問題所在,這才是實驗課的核心意義。 | ||
| 歡迎光臨 (http://m.raoushi.com/bbs/) | Powered by Discuz! X3.1 |