實(shí)驗(yàn)一:方式一的應(yīng)用設(shè)計(jì)
一、實(shí)驗(yàn)內(nèi)容
單片機(jī)甲、乙雙機(jī)串行通信,雙機(jī)RXD和TXD相互交叉相連,甲機(jī)P1口接8個(gè)開(kāi)關(guān),乙機(jī)P1口接8個(gè)發(fā)光二極管。甲機(jī)設(shè)置為只能發(fā)送不能接收的單工方式。要求甲機(jī)讀入P1口的8個(gè)開(kāi)關(guān)的狀態(tài)后,通過(guò)串行口發(fā)送到乙機(jī),乙機(jī)將接收到的甲機(jī)的8個(gè)開(kāi)關(guān)的狀態(tài)數(shù)據(jù)送入P1口,由P1口的8個(gè)發(fā)光二極管來(lái)顯示8個(gè)開(kāi)關(guān)的狀態(tài)。雙方晶振均采用11.0592MHz。
二、實(shí)驗(yàn)原理及步驟
三、電路設(shè)計(jì)及調(diào)試
(1)實(shí)驗(yàn)電路
file:///C:/Users/zyt/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg
(2)程序設(shè)計(jì)及調(diào)試
甲機(jī):
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
void main()
{
uchar temp=0;
TMOD=0x20; //設(shè)置定時(shí)器T1為方式2
TH1=0xfd; //波特率9600
TL1=0xfd;
SCON=0x40; //串口初始化方式1發(fā)送,不接收
PCON=0x00; // SMOD=0
TR1=1; //啟動(dòng)T1
P1=0xff; //設(shè)置P1口為輸入
while(1)
{
while(TI==0); //如果TI=0,未發(fā)送完,循環(huán)等待
TI=0; //已發(fā)送完,把TI清0
temp=P1; //讀入P1口開(kāi)關(guān)的狀態(tài)數(shù)據(jù)
SBUF=temp;}} //數(shù)據(jù)送串行口發(fā)送
乙機(jī):
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
void main( )
{
uchar temp=0;
TMOD=0x20; //設(shè)置定時(shí)器T1為方式2
TH1=0xfd; //波特率9600
TL1=0xfd;
SCON=0x50; //設(shè)置串口為方式1接收,REN=1
PCON=0x00; //SMOD=0
TR1=1; //啟動(dòng)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個(gè)LED的亮與滅
實(shí)驗(yàn)二:多機(jī)通信的應(yīng)用設(shè)計(jì)
一、實(shí)驗(yàn)內(nèi)容
實(shí)現(xiàn)主單片機(jī)分別與3個(gè)從單片機(jī)串行通信,原理電路見(jiàn)圖。用戶(hù)通過(guò)分別按下開(kāi)關(guān)k1、k2或k3來(lái)選擇主機(jī)與對(duì)應(yīng)1#、2#或3#從機(jī)串行通信,當(dāng)黃色LED點(diǎn)亮,表示主機(jī)與相應(yīng)的從機(jī)連接成功;該從機(jī)的8個(gè)綠色LED閃亮,表示主機(jī)與從機(jī)在進(jìn)行串行數(shù)據(jù)通信。如果斷開(kāi)k1、k2或 k3,則主機(jī)與相應(yīng)從機(jī)的串行通信中斷!
二、實(shí)驗(yàn)原理及步驟
1. 實(shí)現(xiàn)主、從機(jī)串行通信,各從機(jī)程序都相同,只是地址不同。
串行通信約定如下。
。1)3臺(tái)從機(jī)的地址為01H~03H。
。2)主機(jī)發(fā)出的0xff為控制命令,使所有從機(jī)都處于SM2=1的狀態(tài)。
。3)其余的控制命令:00H—接收命令,01H—發(fā)送命令。這兩條命令是以數(shù)據(jù)幀的形式發(fā)送的。
。4)從機(jī)的狀態(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í),主機(jī)采用查詢(xún)方式,從機(jī)采用中斷方式。主機(jī)串口設(shè)為方式3,允許接收,并置TB8為1。因只有1個(gè)主機(jī),所以主機(jī)SCON控制寄存器中的SM2不要置1,故控制字為11011000,即0xd8。
三、電路設(shè)計(jì)及調(diào)試
(1)實(shí)驗(yàn)電路
file:///C:/Users/zyt/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg
(2)程序設(shè)計(jì)及調(diào)試
//主機(jī)程序
#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è)置定時(shí)器T1 定時(shí)方式2 自動(dòng)裝載定時(shí)常數(shù)
TL1=0xfd; //波特率設(shè)為9600
TH1=0xfd;
PCON=0x00; //SMOD=0,不倍增
SCON=0xd0; //SM2設(shè)為0,TB8設(shè)為0
TR1=1; //啟動(dòng)定時(shí)器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#從機(jī)的地址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#從機(jī)的地址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#從機(jī)地址
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ù)功能:延時(shí)
{
unsigned char j;
for(;i>0;i--)
for(j=0;j<125;j++)
;
}
//從機(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() //從機(jī)1主函數(shù)
{
EA=1; //總中斷打開(kāi)
TMOD=0x20;//定時(shí)器1 工作方式2,自動(dòng)裝載,用于串口設(shè)置波特率
TL1=0xfd;
TH1=0xfd; //波特率設(shè)為9600
PCON=0x00; // SMOD=0
SCON=0xd0; //SM2設(shè)為0,TB8設(shè)為0
TR1=1; //啟動(dòng)定時(shí)器T1
P1=0xff; // 向P1寫(xiě)入全1,8個(gè)綠色LED全滅
ES=1; //允許串口中斷
while(RI==0); //接收控制指令0xff
if(SBUF==0xff) err=0; //如果接收到的數(shù)據(jù)為0xff,err=0,表示正確
else err=1; //err=1,表示接收出錯(cuò)
RI=0; //接收中斷標(biāo)志清0
SM2=1; //多機(jī)通訊控制位,SM2置1
while(1);}
void int1() interrupt 4, //函數(shù)功能:定時(shí)器T1中斷函數(shù)
{
if(RI) //如果RI=1
{
if(RB8) //如果RB8=1,表示接收的為地址幀
{
RB8=0;
if(SBUF==0x01) //如收的數(shù)據(jù)為地址幀0x01,是本從機(jī)的地址
{
SM2=0; //則SM2清0,準(zhǔn)備接收數(shù)據(jù)幀
led=0; //點(diǎn)亮本從機(jī)黃色發(fā)光二極管
}
}
led=1; // 熄滅本從機(jī)黃色發(fā)光二極管
}
RI=0;
}