3C51應(yīng)用編程設(shè)計(jì)課件_第1頁
3C51應(yīng)用編程設(shè)計(jì)課件_第2頁
3C51應(yīng)用編程設(shè)計(jì)課件_第3頁
3C51應(yīng)用編程設(shè)計(jì)課件_第4頁
3C51應(yīng)用編程設(shè)計(jì)課件_第5頁
已閱讀5頁,還剩97頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

3.1MCS-51機(jī)間通信的C語言編程3.2鍵盤和數(shù)碼顯示人機(jī)交互的C語言編程三C51應(yīng)用編程設(shè)計(jì)三C51應(yīng)用編程設(shè)計(jì)13.1MCS-51機(jī)間通信的C語言編程3.1.1點(diǎn)對點(diǎn)的串行異步通信1.通信雙方的硬件連接圖3.18031間RS—232C電平信號(hào)的傳3.1MCS-51機(jī)間通信的C語言編程3.1.1點(diǎn)對22.通信雙方的約定圖3.2點(diǎn)對點(diǎn)通信的程序框圖2.通信雙方的約定圖3.2點(diǎn)對點(diǎn)通信的程序框圖33.點(diǎn)對點(diǎn)通信編程點(diǎn)對點(diǎn)通信雙方基本等同,只是人為規(guī)定一個(gè)為發(fā)送,一個(gè)為接收。要求兩機(jī)串行口的波特率相同,因而發(fā)送和接收方串行口的初始化相同??删幹坪谐跏蓟瘮?shù)、發(fā)送函數(shù)接收函數(shù)的程序,在主函數(shù)中根據(jù)程序的發(fā)送、接收設(shè)置TR,采用條件判別決定使用發(fā)送函數(shù)還是接收函數(shù)。這樣點(diǎn)對點(diǎn)通信的雙方都可運(yùn)行此程序,只需在程序運(yùn)行之前人為設(shè)置選擇TR,一個(gè)令TR=0,一個(gè)令TR=1,然后分別編譯,在兩機(jī)上分別裝入,同時(shí)運(yùn)行。3.點(diǎn)對點(diǎn)通信編程4例1點(diǎn)對點(diǎn)通信。點(diǎn)對點(diǎn)通信的程序如下:#include<reg51.h>#defineucharunsignedchar#defineTR1 /*發(fā)送接收差別值TR=0發(fā)送*/ucharidatabuf[10];ucharpf;voidinit(void) /*串行口初始化*/{TMOD=0x20; /*設(shè)T/C1為定時(shí)方式2*/TH1=0xe8; /*設(shè)定波特率*/例1點(diǎn)對點(diǎn)通信。#include<reg51.h>5TL1=0xe8;PCON=0x00;TR1=1; /*啟動(dòng)T/C1*/SCON=0x50; /*串行口工作在方式1*/}voidsend(ucharidata*d){uchari;do{SBUF=0xaa; /*發(fā)送聯(lián)絡(luò)信號(hào)*/while(TI==0); /*等待發(fā)送出去*/TI=0;TL1=0xe8;6while(RI==0); /*等待B機(jī)回答*/RI=0;}while((SBUF^0xbb)!=0); /*B機(jī)未準(zhǔn)備好,繼續(xù)聯(lián)絡(luò)*/do{pf=0; /*清校驗(yàn)和*/for(i=0;i<16;i++){SBUF=d[i]; /*發(fā)送一個(gè)數(shù)據(jù)*/pf+=d[i]; /*求校驗(yàn)和*/while(TI==0);TI=0;}SBUF=pf; /*發(fā)送校驗(yàn)和*/while(RI==0); /*等待7while(TI==0);TI=0;while(RI==0);RI=0; /*等待B機(jī)回答*/}while(SBUF!=0); /*回答出錯(cuò),則重發(fā)*/}

voidreceive(ucharidata*d){uchari;do{while(RI==0);RI=0;} while((SBUF^0xaa)!=0); /*判A機(jī)請求否*/SBUF=0xbb; /*發(fā)應(yīng)答信號(hào)*/while(TI==0);TI=0;8 while(TI==0);TI=0;while(1){pf=0; /*清校驗(yàn)和*/for(i=0;i<16;i++){while(RI==0);RI=0;d[i]=SBUF; /*接收一個(gè)數(shù)據(jù)*/pf+=d[i]; /*求校驗(yàn)和*/}while(RI==0);RI=0; /*接收A機(jī)校驗(yàn)和*/if((SBUF^pf)==0) /*比較校驗(yàn)和*/{SBUF=0x00;break;} /*校驗(yàn)和相同發(fā)"00"*/else{SBUF=0xff; /*出錯(cuò)發(fā)"FF",重新接收*/ while(TI==0);TI=0;9 while(TI==0);TI=0;}}}voidmain(void){init();if(TR==0){send(buf);}else{receive(buf);}} while(TI==0);TI=0;103.1.2多機(jī)通信 1.通信接口圖3.3總線式主從式多機(jī)系統(tǒng)3.1.2多機(jī)通信圖3.3總線式主從式多機(jī)系統(tǒng)112.通信協(xié)議根據(jù)MCS-51串行口的多機(jī)通信能力,多機(jī)通信可以按照以下協(xié)議進(jìn)行:(1)首先使所有從機(jī)的SM2位置1處于只接收地址幀的狀態(tài)。(2)主機(jī)先發(fā)送一幀地址信息,其中8位地址,第9位為地址/數(shù)據(jù)信息的標(biāo)志位,該位置1表示該幀為地址信息。(3)從機(jī)接收到地址幀后,各自將接收的地址與本機(jī)的地址比較。對于地址相符的那個(gè)從機(jī),使SM2位清零,以接收主機(jī)隨后發(fā)來的所有信息;對于地址不符的從機(jī),仍保持SM2=1,對主機(jī)隨后發(fā)來的數(shù)據(jù)不予理睬,直至發(fā)送新的地址幀。2.通信協(xié)議根據(jù)MCS-51串行口的多機(jī)通信12(4)當(dāng)從機(jī)發(fā)送數(shù)據(jù)結(jié)束后,發(fā)送一幀校驗(yàn)和,并置第9位(TB8)為1,作為從機(jī)數(shù)據(jù)傳送結(jié)束標(biāo)志。(5)主機(jī)接收數(shù)據(jù)時(shí)先判斷數(shù)據(jù)結(jié)束標(biāo)志(RB8),若RB8=1,表示數(shù)據(jù)傳送結(jié)束,并比較此幀校驗(yàn)和,若正確,則會(huì)送正確信號(hào)00H,此信號(hào)令該從機(jī)復(fù)位(即重新等待地址幀);若校驗(yàn)和出錯(cuò),則發(fā)送0FFH,令該從機(jī)重發(fā)數(shù)據(jù)。若接收幀的RB8=0,則原數(shù)據(jù)到緩沖區(qū),并準(zhǔn)備接收下幀信息。(6)若主機(jī)向從機(jī)發(fā)送數(shù)據(jù),從機(jī)在第(3)步中比較地址相符后,從機(jī)令SM2=0,同時(shí)把本站地址發(fā)回主機(jī)。作為應(yīng)答之后才能收到主機(jī)發(fā)送來的數(shù)據(jù)。其它從機(jī)(SM2=1),無法收到數(shù)據(jù)。(4)當(dāng)從機(jī)發(fā)送數(shù)據(jù)結(jié)束后,發(fā)送一幀校驗(yàn)和,13(7)主機(jī)收到從機(jī)的應(yīng)答地址后,確認(rèn)地址是否相符。如果地址不符,發(fā)復(fù)位信號(hào)(數(shù)據(jù)幀中TB8=1);如果地址相符,則清TB8,開始發(fā)送數(shù)據(jù)。(8)從機(jī)接收到復(fù)位命令后回到監(jiān)聽地址狀態(tài)(SM2=1)。否則開始接收數(shù)據(jù)和命令。(7)主機(jī)收到從機(jī)的應(yīng)答地址后,確認(rèn)地址是否143.通信程序設(shè)主機(jī)發(fā)送的地址聯(lián)絡(luò)信號(hào)00H,01H,02H為從機(jī)設(shè)備地址,地址FFH是命令各從機(jī)恢復(fù)SM2為1的狀態(tài),即復(fù)位。主機(jī)的命令編碼為:01H請求從機(jī)接收主機(jī)的數(shù)據(jù)命令;02H請求從機(jī)向主機(jī)發(fā)送數(shù)據(jù)命令。其它都按從機(jī)向主機(jī)發(fā)送數(shù)據(jù)命令02H對待。3.通信程序15從機(jī)的狀態(tài)字節(jié)格式為:ERR00000TRDYRRDYD7D6D5D4D3D2D1D0RRDY=1:從機(jī)準(zhǔn)備好接收主機(jī)的數(shù)據(jù)。TRDY=1:從機(jī)準(zhǔn)備好向主機(jī)發(fā)送數(shù)據(jù)。ERR=1:從機(jī)接收到的命令是非法的。通常從機(jī)以中斷方式控制和主機(jī)的通信。程序可分成主機(jī)程序和從機(jī)程序,約定一次傳送的數(shù)據(jù)為16個(gè)字節(jié),以02H地址的從機(jī)為例。從機(jī)的狀態(tài)字節(jié)格式為:ERR00000TRDYRRDYD7161)主機(jī)程序圖3.4多機(jī)通信主機(jī)程序流程圖1)主機(jī)程序圖3.4多機(jī)通信主機(jī)程序流程圖17主機(jī)程序如下:#include<reg51.h>#defineucharunsignedchar#defineSLAVE0x02 /*從機(jī)地址*/#defineBN16ucharidatarbuf[16];ucharidatatbuf[16]={"mastertransmit"};voiderr(void){SBUF=0xff;while(TI!=1);TI=0;}主機(jī)程序如下:18ucharmaster(charaddr,ucharcommand){ucharaa,i,p;while(1){SBUF=SLAVE; /*發(fā)呼叫地址*/while(TI!=1);TI=0;while(RI!=1);RI=0; /*等待從機(jī)回答*/if(SBUF!=addr)err(); /*若地址錯(cuò),發(fā)復(fù)位信號(hào)*/else{ /*地址相符*/TB8=0; /*清地址標(biāo)志*/SBUF=command; /*發(fā)命令*/while(TI!=1);TI=0;while(RI!=1);RI=0;ucharmaster(charaddr,uchar19aa=SBUF; /*接收狀態(tài)*/if((aa&0x08)==0x08){TB8=1;err();}/*若命令未被接收,發(fā)復(fù)位信號(hào)*/else{if(command==0x01) /*是發(fā)送命令*/{if((aa&0x01)==0x01) /*從機(jī)準(zhǔn)備好接收*/{do{p=0; /*清校驗(yàn)和*/for(i=0;i<BN;i++){SBUF=tbuf[i]; /*發(fā)送一數(shù)據(jù)*/p+=tbuf[i];aa=SBUF; /*接20 while(TI!=1);TI=0;}SBUF=p; /*發(fā)送校驗(yàn)和*/while(TI==0);TI=0;while(RI==0);RI=0;}while(SBUF!=0); /*接收不正確,重新發(fā)送*/TB8=1; /*置地址標(biāo)志*/return(0)}}else{if((aa&0x02)==0x02) /*是接收命令,從機(jī)準(zhǔn)備好發(fā)送*/ while(TI!=1);TI=0;21{while(1){p=0; /*清校驗(yàn)和*/for(i=0;i<BN;i++){while(RI!=1);RI=0;rbuf[i]=SBUF; /*接收一數(shù)據(jù)*/P+=rubf[i];}while(RI==0);RI=0;if(SBUF==p){SBUF=0X00; /*校驗(yàn)和相同發(fā)"00"*/while(TI==0);TI=0;break;}{while(1)22else{SBUF=0xff; /*校驗(yàn)和不同發(fā)"0FF",重新接收*/while(TI==0);TI=0;}}TB8=1; /*置地址標(biāo)志*/Retuen(0);}}}}}}else23voidmain(viod){TMOD=0x20; /*T/C1定義為方式2*/TL1=0xfd;TH1=0xfd; /*置初值*/PCON=0x00;TR1=1;SCON=0xf0; /*串行口為方式3*/master(SLAVE,0x01);master(SLAVE,0x02);}voidmain(viod)242)從機(jī)程序圖3.5多機(jī)通信的從機(jī)中斷程序流2)從機(jī)程序圖3.5多機(jī)通信的從機(jī)中斷程序流25從機(jī)程序如下:#include<reg51.h>#defineucharunsignedchar#defineSLAVE0x02#defineBN16ucharidatatrbuf[16];ucharidatarebuf[16];bittready;bitrready;voidmain(void){從機(jī)程序如下:26TMOD=0x20; /*T/C1定義為方式2*/TL1=0xfd; /*置初值*/TH1=0xfd;PCON=0x00;TR1=1;SCON=0xf0; /*串行口為方式3*/ES=1;EA=1; /*開串行口中斷*/while(1){tready=1;rready=1;} /*假定準(zhǔn)備好發(fā)送和接收*/}TMOD=0x20;27voidssio(void)interrupt4using1{voidstr(void);voidsre(void);uchara,i;RI=0;ES=0; /*關(guān)串行口中斷*/if(SBUF!=SLAVE){ES=1;gotoreti;} /*非本機(jī)地址,繼續(xù)監(jiān)聽*/SM2=0; /*取消監(jiān)聽狀態(tài)*/SBUF=SLAVE; /*從本地址發(fā)回*/voidssio(void)inter28while(TI!=1);TI=0;while(RI!=1);RI=0;if(RB8==1){SM2=1;ES=1;gotoreti;}/*是復(fù)位信號(hào),恢復(fù)監(jiān)聽*/a=SBUF; /*接收命令*/if(a=0x01) /*從主機(jī)接收的數(shù)據(jù)*/{if(rready==1)SBUF=0x01;/*接收準(zhǔn)備好發(fā)狀態(tài)*/elseSBUF=0x00;while(TI!=1);TI=0;while(RI!=1);RI=0;if(RB8==1){SM2=1;ES=1;gotoreti;}sre(); /*接收數(shù)據(jù)*/}while(TI!=1);TI=029else{if(a=0x02) /*從機(jī)向主機(jī)發(fā)送數(shù)據(jù)*/{if(tready==1)SBUF=0x02; /*發(fā)送準(zhǔn)備好發(fā)狀態(tài)*/elseSBUF=0x00;while(TI!=1);TI=0;while(RI!=1);RI=0;if(RB8==1){SM2=1;ES=1;gotoreti;}str(); /*發(fā)送數(shù)據(jù)*/}else{30else{SBUF=0x80; /*命令非法,發(fā)狀態(tài)*/while(TI!=1);TI=0;SM2=1;ES=1; /*恢復(fù)監(jiān)聽*/}}reti:;}voidstr(void) /*發(fā)數(shù)據(jù)塊*/{ucharp,i;tready=0;do{p=0; /*清校驗(yàn)和*/else31for(i=0;i<BN;i++){SBUF=trbuf[i]; /*發(fā)送一數(shù)據(jù)*/p+=trbuf[i];while(TI!=1);TI=0;}SUBF=p; /*發(fā)送校驗(yàn)和*/while(TI==0);TI=0;while(RI==0);RI=0;}while(SBUF!=0); /*主機(jī)接收不正確,重新發(fā)送*/SM2=1;ES=1;}for(i=0;i<BN;i+32voidsre(void) /*接收數(shù)據(jù)塊*/{ucharp,i;rready=0;while(1){p=0; /*清校驗(yàn)和*/for(i=0;i<BN;i++){while(RI!=1);RI=0;rebuf[i]=SBUF; /*接收數(shù)據(jù)*/p+=rebuf[i];}voidsre(void)33while(RI!=1);RI=0;if(SBUF==p){SBUF=0x00;break;} /*校驗(yàn)和相同發(fā)"00"*/else{SBUF=0xff; /*校驗(yàn)和不同發(fā)"0FF",重新接收*/while(TI==0);TI=0;}}SM2=1;ES=1;}while(RI!=1);343.2鍵盤和數(shù)碼顯示人機(jī)交互的C語言編程3.2.1行列式鍵盤與8031的接口鍵盤輸入信息的主要過程是:(1)單片機(jī)判斷是否有鍵按下。(2)確定按下的是哪一個(gè)鍵。(3)把此步驟代表的信息翻譯成計(jì)算機(jī)所能識(shí)別的代碼,如ASCII或其它特征碼。3.2鍵盤和數(shù)碼顯示人機(jī)交互的C語言編程3.2.1行35圖3.68031與行列式鍵盤的接口圖3.68031與行列式鍵盤的接口36例24×4鍵盤的掃描程序。掃描程序查詢的內(nèi)容為:(1)查詢是否有鍵按下。首先單片機(jī)向行掃描P1.0~P1.3輸出全為"0"掃描碼F0H,然后從列檢查口P1.4~P1.7輸入列掃描信號(hào),只要有一列信號(hào)不為"1",即P1口不為F0H,則表示有鍵按下。接著要查出按下鍵所在的行、列位置。例24×4鍵盤的掃描程序。37(2)查詢按下鍵所在的行列位置。單片機(jī)將得到的信號(hào)取反,P1.4~P1.7中的為1的位便是鍵所在的列。接下來要確定鍵所在的行,需要進(jìn)行逐行掃描。單片機(jī)首先使P1.0為"0",P1.1~P1.7為"1",即向P1口發(fā)送掃描碼FEH,接著輸入列檢查信號(hào),若全為"1",表示不在第一行。接著使P1.1接地,其余為"1",再讀入列信號(hào)……這樣逐行發(fā)"0"掃描碼,直到找到按下鍵所在的行,將該行掃描碼取反保留。當(dāng)各行都掃描以后仍沒有找到,則放棄掃描,認(rèn)為是鍵的誤動(dòng)作。(2)查詢按下鍵所在的行列位置。單片機(jī)將得到38(3)對得到的行號(hào)和列號(hào)譯碼,得到鍵值。(4)鍵的抖動(dòng)處理。當(dāng)用手按下一個(gè)鍵時(shí),往往會(huì)出現(xiàn)所按鍵在閉合位置和斷開位置之間跳幾下才穩(wěn)定到閉合狀態(tài)的情況。在釋放一個(gè)鍵時(shí),也會(huì)出現(xiàn)類似的情況,這就是鍵抖動(dòng),抖動(dòng)的持續(xù)時(shí)間不一,通常不會(huì)大于10ms,若抖動(dòng)問題不解決,就會(huì)引起對閉合鍵的多次讀入,對于鍵抖動(dòng)最方便的解決方法就是當(dāng)發(fā)現(xiàn)有鍵按下后,不是立即進(jìn)行逐行掃描,而是延時(shí)10ms后再進(jìn)行。由于鍵按下的時(shí)間持續(xù)上百毫秒,延時(shí)后再也不遲。(3)對得到的行號(hào)和列號(hào)譯碼,得到鍵值。39掃描函數(shù)的返回值為鍵特征碼,若無鍵按下,返回值為0。程序如下:#include<reg51.h>#defineucharunsignedchar#defineuintunsignedintvoiddlms(void)voidkbscan(void);voidmain(void){ucharkey;while(1){key=kbscan();dlms();}}掃描函數(shù)的返回值為鍵特征碼,若無鍵按下,返回值為0。程序如下40voiddlms(void){uchari;for(i=200;i>0;i--){}}ucharkbscan(void) /*鍵掃描函數(shù)*/{ucharscode,recode;P1=oxf0;if((P1&0xf0)!=0xf0) /*若有鍵按下*/{dlms(); /*延時(shí)去抖動(dòng)*/if((P1&0xf0)!=0xf0){scode=0xfe; /*逐行掃描初值*/while((scode&0x10)!=0){P1=scode; /*輸出掃描碼*/voiddlms(void)41 if((P1&0xf0)!=0xf0) /*本行有鍵按下*/{recode=(P1&0xf0)|0x0f;return((~scode)+(~recode)); /*返回特征字節(jié)碼*/}elsescode=(scode<<1)|0x01; /*行掃描左移一位*/} }}return(0);} if((P1&0xf0)!=0xf0)423.2.2七段數(shù)碼顯示與8031的接口數(shù)碼顯示器有靜態(tài)顯示和動(dòng)態(tài)顯示兩種顯示方式。數(shù)碼顯示器有發(fā)光管的LED和液晶的LCD兩種。LED顯示器工作在靜態(tài)方式時(shí),其陰極(或其陽極)點(diǎn)連接在一起接地(或+5V),每一個(gè)的端選線(a,b,c,d,e,f,g,dp)分別與一個(gè)8位口相連。LCD數(shù)碼顯示只能工作在靜態(tài)顯示,并要求加上專門的驅(qū)動(dòng)芯片4056。LED顯示器工作在動(dòng)態(tài)顯示方式時(shí),段選碼端口I/O1用來輸出顯示字符的段選碼,I/O2輸出位選碼。I/O1不斷送待顯示字符的段選碼,I/O2不斷送出不同的位掃描碼,并使每位顯示字符停留顯示一段時(shí)間,一般為1~5ms,利用眼睛的視覺慣性,從顯示器上便可以見到相當(dāng)穩(wěn)定的數(shù)字顯示。3.2.2七段數(shù)碼顯示與8031的接口數(shù)碼43例38155控制的動(dòng)態(tài)LED顯示。圖3.7經(jīng)8155擴(kuò)展端口的6位LED動(dòng)態(tài)顯示例38155控制的動(dòng)態(tài)LED顯示。圖3.7經(jīng)81544確定的8155片內(nèi)4個(gè)端口地址如下:命令/狀態(tài)口:FFF0H口A: FFF1H口B: FFF2H口C: FFF3H確定的8155片內(nèi)4個(gè)端口地址如下:命令/狀態(tài)口:FF456位待顯示字符從左到右依次放在dis_buf數(shù)組中,顯示次序從右向左順序進(jìn)行。程序中的table為段選碼表,表中段選碼表存放的次序?yàn)?~F等。以下為循環(huán)動(dòng)態(tài)顯示6位字符的程序,8155命令字為07H。#include<absacc.h>#include<reg51.h>#defineucharunsignedchar#defineCOM8155XBYTE[0xfff0]#definePA8155XBYTE[0xfff1]#definePB8155XBYTE[0xfff2]#definePC8155XBYTE[0xfff3]6位待顯示字符從左到右依次放在dis_buf46ucharidatadis_buf[6]={2,4,6,8,10,12};ucharcodetable[18]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00};voiddl_ms(uchard);voiddisplay(ucharidata*p){ucharsel,i;COM8155=0x07; /*送命令字*/sel=0x01; /*選出右邊的LED*/for(i=0;i<6;i++){PB8155=table[*p]; /*送段碼*/ucharidatadis_buf[6]={2,447PA8155=sel; /*送位選碼*/dl_ms(1);p--; /*緩沖區(qū)下移1位*/sel=sel<<1 /*左移1位*/}}voidmain(void){display(dis_buf+5);}PA8155=sel; /48例4串行口控制的靜態(tài)LCD顯示。圖3.8串行口連接的靜態(tài)LCD顯示電路例4串行口控制的靜態(tài)LCD顯示。圖3.8串行口連接的49輸出兩位顯示,即一字節(jié)的程序如下:#include<reg51.h>#defineucharunsignedcharucharbyte=0x59;voiddisplay(ucharx){SBUF=x; /*由串口輸出*/while(TI==0); /*等待8位發(fā)送結(jié)束*/TI=0;}voidmain(void){display(byte)}輸出兩位顯示,即一字節(jié)的程序如下:50演講完畢,謝謝觀看!演講完畢,謝謝觀看!513.1MCS-51機(jī)間通信的C語言編程3.2鍵盤和數(shù)碼顯示人機(jī)交互的C語言編程三C51應(yīng)用編程設(shè)計(jì)三C51應(yīng)用編程設(shè)計(jì)523.1MCS-51機(jī)間通信的C語言編程3.1.1點(diǎn)對點(diǎn)的串行異步通信1.通信雙方的硬件連接圖3.18031間RS—232C電平信號(hào)的傳3.1MCS-51機(jī)間通信的C語言編程3.1.1點(diǎn)對532.通信雙方的約定圖3.2點(diǎn)對點(diǎn)通信的程序框圖2.通信雙方的約定圖3.2點(diǎn)對點(diǎn)通信的程序框圖543.點(diǎn)對點(diǎn)通信編程點(diǎn)對點(diǎn)通信雙方基本等同,只是人為規(guī)定一個(gè)為發(fā)送,一個(gè)為接收。要求兩機(jī)串行口的波特率相同,因而發(fā)送和接收方串行口的初始化相同??删幹坪谐跏蓟瘮?shù)、發(fā)送函數(shù)接收函數(shù)的程序,在主函數(shù)中根據(jù)程序的發(fā)送、接收設(shè)置TR,采用條件判別決定使用發(fā)送函數(shù)還是接收函數(shù)。這樣點(diǎn)對點(diǎn)通信的雙方都可運(yùn)行此程序,只需在程序運(yùn)行之前人為設(shè)置選擇TR,一個(gè)令TR=0,一個(gè)令TR=1,然后分別編譯,在兩機(jī)上分別裝入,同時(shí)運(yùn)行。3.點(diǎn)對點(diǎn)通信編程55例1點(diǎn)對點(diǎn)通信。點(diǎn)對點(diǎn)通信的程序如下:#include<reg51.h>#defineucharunsignedchar#defineTR1 /*發(fā)送接收差別值TR=0發(fā)送*/ucharidatabuf[10];ucharpf;voidinit(void) /*串行口初始化*/{TMOD=0x20; /*設(shè)T/C1為定時(shí)方式2*/TH1=0xe8; /*設(shè)定波特率*/例1點(diǎn)對點(diǎn)通信。#include<reg51.h>56TL1=0xe8;PCON=0x00;TR1=1; /*啟動(dòng)T/C1*/SCON=0x50; /*串行口工作在方式1*/}voidsend(ucharidata*d){uchari;do{SBUF=0xaa; /*發(fā)送聯(lián)絡(luò)信號(hào)*/while(TI==0); /*等待發(fā)送出去*/TI=0;TL1=0xe8;57while(RI==0); /*等待B機(jī)回答*/RI=0;}while((SBUF^0xbb)!=0); /*B機(jī)未準(zhǔn)備好,繼續(xù)聯(lián)絡(luò)*/do{pf=0; /*清校驗(yàn)和*/for(i=0;i<16;i++){SBUF=d[i]; /*發(fā)送一個(gè)數(shù)據(jù)*/pf+=d[i]; /*求校驗(yàn)和*/while(TI==0);TI=0;}SBUF=pf; /*發(fā)送校驗(yàn)和*/while(RI==0); /*等待58while(TI==0);TI=0;while(RI==0);RI=0; /*等待B機(jī)回答*/}while(SBUF!=0); /*回答出錯(cuò),則重發(fā)*/}

voidreceive(ucharidata*d){uchari;do{while(RI==0);RI=0;} while((SBUF^0xaa)!=0); /*判A機(jī)請求否*/SBUF=0xbb; /*發(fā)應(yīng)答信號(hào)*/while(TI==0);TI=0;59 while(TI==0);TI=0;while(1){pf=0; /*清校驗(yàn)和*/for(i=0;i<16;i++){while(RI==0);RI=0;d[i]=SBUF; /*接收一個(gè)數(shù)據(jù)*/pf+=d[i]; /*求校驗(yàn)和*/}while(RI==0);RI=0; /*接收A機(jī)校驗(yàn)和*/if((SBUF^pf)==0) /*比較校驗(yàn)和*/{SBUF=0x00;break;} /*校驗(yàn)和相同發(fā)"00"*/else{SBUF=0xff; /*出錯(cuò)發(fā)"FF",重新接收*/ while(TI==0);TI=0;60 while(TI==0);TI=0;}}}voidmain(void){init();if(TR==0){send(buf);}else{receive(buf);}} while(TI==0);TI=0;613.1.2多機(jī)通信 1.通信接口圖3.3總線式主從式多機(jī)系統(tǒng)3.1.2多機(jī)通信圖3.3總線式主從式多機(jī)系統(tǒng)622.通信協(xié)議根據(jù)MCS-51串行口的多機(jī)通信能力,多機(jī)通信可以按照以下協(xié)議進(jìn)行:(1)首先使所有從機(jī)的SM2位置1處于只接收地址幀的狀態(tài)。(2)主機(jī)先發(fā)送一幀地址信息,其中8位地址,第9位為地址/數(shù)據(jù)信息的標(biāo)志位,該位置1表示該幀為地址信息。(3)從機(jī)接收到地址幀后,各自將接收的地址與本機(jī)的地址比較。對于地址相符的那個(gè)從機(jī),使SM2位清零,以接收主機(jī)隨后發(fā)來的所有信息;對于地址不符的從機(jī),仍保持SM2=1,對主機(jī)隨后發(fā)來的數(shù)據(jù)不予理睬,直至發(fā)送新的地址幀。2.通信協(xié)議根據(jù)MCS-51串行口的多機(jī)通信63(4)當(dāng)從機(jī)發(fā)送數(shù)據(jù)結(jié)束后,發(fā)送一幀校驗(yàn)和,并置第9位(TB8)為1,作為從機(jī)數(shù)據(jù)傳送結(jié)束標(biāo)志。(5)主機(jī)接收數(shù)據(jù)時(shí)先判斷數(shù)據(jù)結(jié)束標(biāo)志(RB8),若RB8=1,表示數(shù)據(jù)傳送結(jié)束,并比較此幀校驗(yàn)和,若正確,則會(huì)送正確信號(hào)00H,此信號(hào)令該從機(jī)復(fù)位(即重新等待地址幀);若校驗(yàn)和出錯(cuò),則發(fā)送0FFH,令該從機(jī)重發(fā)數(shù)據(jù)。若接收幀的RB8=0,則原數(shù)據(jù)到緩沖區(qū),并準(zhǔn)備接收下幀信息。(6)若主機(jī)向從機(jī)發(fā)送數(shù)據(jù),從機(jī)在第(3)步中比較地址相符后,從機(jī)令SM2=0,同時(shí)把本站地址發(fā)回主機(jī)。作為應(yīng)答之后才能收到主機(jī)發(fā)送來的數(shù)據(jù)。其它從機(jī)(SM2=1),無法收到數(shù)據(jù)。(4)當(dāng)從機(jī)發(fā)送數(shù)據(jù)結(jié)束后,發(fā)送一幀校驗(yàn)和,64(7)主機(jī)收到從機(jī)的應(yīng)答地址后,確認(rèn)地址是否相符。如果地址不符,發(fā)復(fù)位信號(hào)(數(shù)據(jù)幀中TB8=1);如果地址相符,則清TB8,開始發(fā)送數(shù)據(jù)。(8)從機(jī)接收到復(fù)位命令后回到監(jiān)聽地址狀態(tài)(SM2=1)。否則開始接收數(shù)據(jù)和命令。(7)主機(jī)收到從機(jī)的應(yīng)答地址后,確認(rèn)地址是否653.通信程序設(shè)主機(jī)發(fā)送的地址聯(lián)絡(luò)信號(hào)00H,01H,02H為從機(jī)設(shè)備地址,地址FFH是命令各從機(jī)恢復(fù)SM2為1的狀態(tài),即復(fù)位。主機(jī)的命令編碼為:01H請求從機(jī)接收主機(jī)的數(shù)據(jù)命令;02H請求從機(jī)向主機(jī)發(fā)送數(shù)據(jù)命令。其它都按從機(jī)向主機(jī)發(fā)送數(shù)據(jù)命令02H對待。3.通信程序66從機(jī)的狀態(tài)字節(jié)格式為:ERR00000TRDYRRDYD7D6D5D4D3D2D1D0RRDY=1:從機(jī)準(zhǔn)備好接收主機(jī)的數(shù)據(jù)。TRDY=1:從機(jī)準(zhǔn)備好向主機(jī)發(fā)送數(shù)據(jù)。ERR=1:從機(jī)接收到的命令是非法的。通常從機(jī)以中斷方式控制和主機(jī)的通信。程序可分成主機(jī)程序和從機(jī)程序,約定一次傳送的數(shù)據(jù)為16個(gè)字節(jié),以02H地址的從機(jī)為例。從機(jī)的狀態(tài)字節(jié)格式為:ERR00000TRDYRRDYD7671)主機(jī)程序圖3.4多機(jī)通信主機(jī)程序流程圖1)主機(jī)程序圖3.4多機(jī)通信主機(jī)程序流程圖68主機(jī)程序如下:#include<reg51.h>#defineucharunsignedchar#defineSLAVE0x02 /*從機(jī)地址*/#defineBN16ucharidatarbuf[16];ucharidatatbuf[16]={"mastertransmit"};voiderr(void){SBUF=0xff;while(TI!=1);TI=0;}主機(jī)程序如下:69ucharmaster(charaddr,ucharcommand){ucharaa,i,p;while(1){SBUF=SLAVE; /*發(fā)呼叫地址*/while(TI!=1);TI=0;while(RI!=1);RI=0; /*等待從機(jī)回答*/if(SBUF!=addr)err(); /*若地址錯(cuò),發(fā)復(fù)位信號(hào)*/else{ /*地址相符*/TB8=0; /*清地址標(biāo)志*/SBUF=command; /*發(fā)命令*/while(TI!=1);TI=0;while(RI!=1);RI=0;ucharmaster(charaddr,uchar70aa=SBUF; /*接收狀態(tài)*/if((aa&0x08)==0x08){TB8=1;err();}/*若命令未被接收,發(fā)復(fù)位信號(hào)*/else{if(command==0x01) /*是發(fā)送命令*/{if((aa&0x01)==0x01) /*從機(jī)準(zhǔn)備好接收*/{do{p=0; /*清校驗(yàn)和*/for(i=0;i<BN;i++){SBUF=tbuf[i]; /*發(fā)送一數(shù)據(jù)*/p+=tbuf[i];aa=SBUF; /*接71 while(TI!=1);TI=0;}SBUF=p; /*發(fā)送校驗(yàn)和*/while(TI==0);TI=0;while(RI==0);RI=0;}while(SBUF!=0); /*接收不正確,重新發(fā)送*/TB8=1; /*置地址標(biāo)志*/return(0)}}else{if((aa&0x02)==0x02) /*是接收命令,從機(jī)準(zhǔn)備好發(fā)送*/ while(TI!=1);TI=0;72{while(1){p=0; /*清校驗(yàn)和*/for(i=0;i<BN;i++){while(RI!=1);RI=0;rbuf[i]=SBUF; /*接收一數(shù)據(jù)*/P+=rubf[i];}while(RI==0);RI=0;if(SBUF==p){SBUF=0X00; /*校驗(yàn)和相同發(fā)"00"*/while(TI==0);TI=0;break;}{while(1)73else{SBUF=0xff; /*校驗(yàn)和不同發(fā)"0FF",重新接收*/while(TI==0);TI=0;}}TB8=1; /*置地址標(biāo)志*/Retuen(0);}}}}}}else74voidmain(viod){TMOD=0x20; /*T/C1定義為方式2*/TL1=0xfd;TH1=0xfd; /*置初值*/PCON=0x00;TR1=1;SCON=0xf0; /*串行口為方式3*/master(SLAVE,0x01);master(SLAVE,0x02);}voidmain(viod)752)從機(jī)程序圖3.5多機(jī)通信的從機(jī)中斷程序流2)從機(jī)程序圖3.5多機(jī)通信的從機(jī)中斷程序流76從機(jī)程序如下:#include<reg51.h>#defineucharunsignedchar#defineSLAVE0x02#defineBN16ucharidatatrbuf[16];ucharidatarebuf[16];bittready;bitrready;voidmain(void){從機(jī)程序如下:77TMOD=0x20; /*T/C1定義為方式2*/TL1=0xfd; /*置初值*/TH1=0xfd;PCON=0x00;TR1=1;SCON=0xf0; /*串行口為方式3*/ES=1;EA=1; /*開串行口中斷*/while(1){tready=1;rready=1;} /*假定準(zhǔn)備好發(fā)送和接收*/}TMOD=0x20;78voidssio(void)interrupt4using1{voidstr(void);voidsre(void);uchara,i;RI=0;ES=0; /*關(guān)串行口中斷*/if(SBUF!=SLAVE){ES=1;gotoreti;} /*非本機(jī)地址,繼續(xù)監(jiān)聽*/SM2=0; /*取消監(jiān)聽狀態(tài)*/SBUF=SLAVE; /*從本地址發(fā)回*/voidssio(void)inter79while(TI!=1);TI=0;while(RI!=1);RI=0;if(RB8==1){SM2=1;ES=1;gotoreti;}/*是復(fù)位信號(hào),恢復(fù)監(jiān)聽*/a=SBUF; /*接收命令*/if(a=0x01) /*從主機(jī)接收的數(shù)據(jù)*/{if(rready==1)SBUF=0x01;/*接收準(zhǔn)備好發(fā)狀態(tài)*/elseSBUF=0x00;while(TI!=1);TI=0;while(RI!=1);RI=0;if(RB8==1){SM2=1;ES=1;gotoreti;}sre(); /*接收數(shù)據(jù)*/}while(TI!=1);TI=080else{if(a=0x02) /*從機(jī)向主機(jī)發(fā)送數(shù)據(jù)*/{if(tready==1)SBUF=0x02; /*發(fā)送準(zhǔn)備好發(fā)狀態(tài)*/elseSBUF=0x00;while(TI!=1);TI=0;while(RI!=1);RI=0;if(RB8==1){SM2=1;ES=1;gotoreti;}str(); /*發(fā)送數(shù)據(jù)*/}else{81else{SBUF=0x80; /*命令非法,發(fā)狀態(tài)*/while(TI!=1);TI=0;SM2=1;ES=1; /*恢復(fù)監(jiān)聽*/}}reti:;}voidstr(void) /*發(fā)數(shù)據(jù)塊*/{ucharp,i;tready=0;do{p=0; /*清校驗(yàn)和*/else82for(i=0;i<BN;i++){SBUF=trbuf[i]; /*發(fā)送一數(shù)據(jù)*/p+=trbuf[i];while(TI!=1);TI=0;}SUBF=p; /*發(fā)送校驗(yàn)和*/while(TI==0);TI=0;while(RI==0);RI=0;}while(SBUF!=0); /*主機(jī)接收不正確,重新發(fā)送*/SM2=1;ES=1;}for(i=0;i<BN;i+83voidsre(void) /*接收數(shù)據(jù)塊*/{ucharp,i;rready=0;while(1){p=0; /*清校驗(yàn)和*/for(i=0;i<BN;i++){while(RI!=1);RI=0;rebuf[i]=SBUF; /*接收數(shù)據(jù)*/p+=rebuf[i];}voidsre(void)84while(RI!=1);RI=0;if(SBUF==p){SBUF=0x00;break;} /*校驗(yàn)和相同發(fā)"00"*/else{SBUF=0xff; /*校驗(yàn)和不同發(fā)"0FF",重新接收*/while(TI==0);TI=0;}}SM2=1;ES=1;}while(RI!=1);853.2鍵盤和數(shù)碼顯示人機(jī)交互的C語言編程3.2.1行列式鍵盤與8031的接口鍵盤輸入信息的主要過程是:(1)單片機(jī)判斷是否有鍵按下。(2)確定按下的是哪一個(gè)鍵。(3)把此步驟代表的信息翻譯成計(jì)算機(jī)所能識(shí)別的代碼,如ASCII或其它特征碼。3.2鍵盤和數(shù)碼顯示人機(jī)交互的C語言編程3.2.1行86圖3.68031與行列式鍵盤的接口圖3.68031與行列式鍵盤的接口87例24×4鍵盤的掃描程序。掃描程序查詢的內(nèi)容為:(1)查詢是否有鍵按下。首先單片機(jī)向行掃描P1.0~P1.3輸出全為"0"掃描碼F0H,然后從列檢查口P1.4~P1.7輸入列掃描信號(hào),只要有一列信號(hào)不為"1",即P1口不為F0H,則表示有鍵按下。接著要查出按下鍵所在的行、列位置。例24×4鍵盤的掃描程序。88(2)查詢按下鍵所在的行列位置。單片機(jī)將得到的信號(hào)取反,P1.4~P1.7中的為1的位便是鍵所在的列。接下來要確定鍵所在的行,需要進(jìn)行逐行掃描。單片機(jī)首先使P1.0為"0",P1.1~P1.7為"1",即向P1口發(fā)送掃描碼FEH,接著輸入列檢查信號(hào),若全為"1",表示不在第一行。接著使P1.1接地,其余為"1",再讀入列信號(hào)……這樣逐行發(fā)"0"掃描碼,直到找到按下鍵所在的行,將該行掃描碼取反保留。當(dāng)各行都掃描以后仍沒有找到,則放棄掃描,認(rèn)為是鍵的誤動(dòng)作。(2)查詢按下鍵所在的行列位置。單片機(jī)將得到89(3)對得到的行號(hào)和列號(hào)譯碼,得到鍵值。(4)鍵的抖動(dòng)處理。當(dāng)用手按下一個(gè)鍵時(shí),往往會(huì)出現(xiàn)所按鍵在閉合位置和斷開位置之間跳幾下才穩(wěn)定到閉合狀態(tài)的情況。在釋放一個(gè)鍵時(shí),也會(huì)出現(xiàn)類似的情況,這就是鍵抖動(dòng),抖動(dòng)的持續(xù)時(shí)間不一,通常不會(huì)大于10ms,若抖動(dòng)問題不解決,就會(huì)引起對閉合鍵的多次讀入,對于鍵抖動(dòng)最方便的解決方法就是當(dāng)發(fā)現(xiàn)有鍵按下后,不是立即進(jìn)行逐行掃描,而是延時(shí)10ms后再進(jìn)行。由于鍵按下的時(shí)間持續(xù)上百毫秒,延時(shí)后再也不遲。(3)對得到的行號(hào)和列號(hào)譯碼,得到鍵值。90掃描函數(shù)的返回值為鍵特征碼,若無鍵按下,返回值為0。程序如下:#include<reg51.h>#defineucharunsignedchar#defineuintunsignedintvoiddlms(void)voidkbscan(void);voidmain(void){ucharkey;while(1){key=kbscan();dlms();}}掃描函數(shù)的返回值為鍵特征碼,若無鍵按下,返回值為0。程序如下91voiddlms(void){uchari;for

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論