您好,歡迎進(jìn)入深圳市穎特新科技有限公司官方網(wǎng)站!
串行與并行通訊方式
并行:控制簡(jiǎn)單,傳輸速度快。線多,長(zhǎng)距離成本較高且同時(shí)接受困難。
串行:將數(shù)據(jù)字節(jié)分成一位一位的行駛在一條傳輸線上進(jìn)行傳輸。如圖:
同步與異步串行通訊方式
同步串行通訊方式:同步通訊需要建立發(fā)送方對(duì)接收方時(shí)鐘的直接控制,是雙方達(dá)到完全同步。
異步串行通訊方式:通訊的發(fā)送和接收設(shè)備使用各自的時(shí)鐘控制數(shù)據(jù)的發(fā)送和接收,為使雙方收發(fā)協(xié)調(diào),要求發(fā)送和接收的時(shí)鐘盡可能一致。如圖:
異步通訊方式的特點(diǎn):
異步通訊以字符構(gòu)成的幀為單位進(jìn)行傳輸,字符與字符之間的間隙是任意的,但每個(gè)字符中的各位是以固定的時(shí)間傳送的。其一幀字符信息由4部分組成:起始位、數(shù)據(jù)位、奇偶檢驗(yàn)位、停止位。在單片機(jī)中的通訊一般情況下均使用這種幀格式。如圖:
串行通訊的制式
單工:數(shù)據(jù)傳輸僅沿一個(gè)方向,不能實(shí)現(xiàn)反向傳輸
半雙工:數(shù)據(jù)可以沿兩個(gè)方向傳輸,但是需要分時(shí)
全雙工:數(shù)據(jù)可以同時(shí)進(jìn)行雙向傳輸
串行通訊三種錯(cuò)誤校驗(yàn):奇偶校驗(yàn)、代碼和校驗(yàn)、循環(huán)冗余校驗(yàn)
RS232電平與TTL電平的轉(zhuǎn)換
PC使用的串口的電平為RS232的九針串口,MCU使用的電平是TTL電平,要使得PC 和MCU進(jìn)行通訊,就需要對(duì)其電平極性轉(zhuǎn)換。主要的幾款電平轉(zhuǎn)換芯片:MAX232、MAX202、HIN232,SIPEX320等
串行通訊速度的定義_波特率
串行通訊的速率用波特率表示,其定義為:
每秒鐘傳送二進(jìn)制代碼的位數(shù),即1波特=1位/秒,單位bps(位/秒)
eg:每秒鐘傳送240個(gè)字符,而每個(gè)字符格式包含10位(1起始、8數(shù)據(jù)、1停止),此時(shí)的波特率為:
10位*240個(gè)/秒=2400bps
串行通訊波特率的計(jì)算
單片機(jī)的串行口可設(shè)定為四種工作方式,其中方式0和方式2波特率固定,方式1和方式3波特率可變,由定時(shí)器T1的溢出率來決定。計(jì)算公式如下:
其中:fosc為系統(tǒng)晶振頻率,通常為12MHz(或者11.0592MHz),SMOD為PCON寄存器的最高位。T1的溢出率即定時(shí)器T1溢出的頻率。
電源管理寄存器_PCON
SMOD;該位與串通信波特率有關(guān)。
SMOD=0;串口方式1、2、3時(shí),波特率正常
SMOD=1;串口方式1、2、3時(shí),波特率加倍
SMOD0,LVDF,P0F,此三位為STC_MCU 所特有的,可查看相關(guān)手冊(cè)。
GF1、GF0;兩個(gè)通用標(biāo)志位,可隨意使用。
PD;掉電模式設(shè)定位,
PD=0;MCU正常工作
PD=1;MCU進(jìn)入掉電模式
IDL;空閑模式設(shè)定位
IDL=0;MCU正常工作
IDL=1;單片機(jī)進(jìn)入空閑模式
單片機(jī)的兩種模式狀態(tài):
掉電模式:進(jìn)入掉電模式后,晶振停震,CPU,定時(shí)器,串行口全部停止工作,只有外部中斷繼續(xù)工作,
可有外部中斷低電平觸發(fā)或下降沿觸發(fā)或硬件復(fù)位模式喚醒。
空閑模式:除CPU不夠工作外,其余仍繼續(xù)工作,在空閑模式下,可由任一個(gè)中斷或者硬件復(fù)位喚醒
T1的溢出率
T1的溢出率就是T1定時(shí)器溢出的頻率,只要算出T1定時(shí)器每一處一次所需的時(shí)間T,那么T的倒數(shù)即為他的溢出率。
51串行口結(jié)構(gòu)
51單片機(jī)串行口是一個(gè)可編程全雙工的通信接口,具有Uart(通用異步收發(fā)器)的全部功能,能同時(shí)進(jìn)行數(shù)據(jù)的發(fā)送與接收,也可作為同步一位寄存器使用。
51_MCU主要由兩個(gè)獨(dú)立的串行數(shù)據(jù)緩沖寄存器SBUF (一個(gè)發(fā)送,一個(gè)接收)和發(fā)送控制器、接收控制器,輸入移位寄存器及若干控制門電路。如圖:
串行口控制寄存器_SCON
SM0,SM1;工作方式選擇位,串口有四中工作方式,如下:
SM2;多機(jī)通信可控制位,SM2主要用于方式2和方式3,當(dāng)接收機(jī)的SM2=1時(shí),可以利用收的RB8來控制是否激活RI;
RB8=0,不激活RI,收到的信息丟棄
RB8=1,收到的數(shù)據(jù)進(jìn)入SBUF,并激活RI,進(jìn)而在中斷服務(wù)中將數(shù)據(jù)從SBUF讀走,
當(dāng)SM2=0時(shí),無論收到的RB8是0還是1,均可以收收到的數(shù)據(jù)進(jìn)入SBUF,并激活RI,通過控制SM2可實(shí)現(xiàn)多機(jī)通信。
在方式0時(shí),SM2必須是0,
在方式1時(shí),若SM2=1,則只有接收到有效停止位時(shí),RI才置1
REN;允許串行接收位
REN=1;允許串行口接收數(shù)據(jù)
REN=0;禁止串行口接收數(shù)據(jù)
TB8;方式2、3中發(fā)送數(shù)據(jù)的第九位,可定義其作用,奇偶檢驗(yàn),地址幀標(biāo)志等,方式0和1中,未使用
RB8;方式2、3中接收數(shù)據(jù)的第九位,可定義其作用,奇偶檢驗(yàn),地址幀標(biāo)志等,方式1,若SM2=0,則RB8是接收到的停止位。
TI;發(fā)送中斷標(biāo)志位,方式0中,串行發(fā)送第8位數(shù)據(jù)結(jié)束時(shí),或者其他方式,串行發(fā)送停止位時(shí),由內(nèi)部硬件置1,向CPU發(fā)出中斷申請(qǐng),在中斷服務(wù)程序中,須用軟件清零,取消此中斷申請(qǐng)。
RI;接收中斷標(biāo)志位, 方式0中,串行接收第8位數(shù)據(jù)結(jié)束時(shí),或者其他方式,串行接收停止位時(shí),由內(nèi)部硬件置1,向CPU發(fā)出中斷申請(qǐng),在中斷服務(wù)程序中,須用軟件清零,取消此中斷申請(qǐng)
串口方式0,串行口為同步移位寄存器的輸入輸出方式,主要永不擴(kuò)展并行輸入輸出接口,數(shù)據(jù)由RXD(P3.0)引腳輸入或者輸出,同步移位脈沖由TXD(P3.1)引腳輸出,發(fā)送和接收均為8位數(shù)據(jù),低位在先,高位在后。波特率固定fosc/12
串口方式1;10位數(shù)據(jù)一步通訊口,1起始,8數(shù)據(jù),1停止,TXD(P3.1)為數(shù)據(jù)發(fā)送引腳,RXD(P3.0)為數(shù)據(jù)接收引腳。其傳輸波特率可變,對(duì)51而言,波特率有定時(shí)器1的溢出率而決定,一般而言,在單片基于單片機(jī),單片機(jī)與計(jì)算機(jī),計(jì)算機(jī)與計(jì)算機(jī)串口通訊時(shí),基本都市選擇方式1,所以此種方式必須掌握。
串口方士2,3;11位數(shù)據(jù)的異步通訊口,XD(P3.1)為數(shù)據(jù)發(fā)送引腳,RXD(P3.0)為數(shù)據(jù)接收引腳。在這兩種方式下,1起始,9數(shù)據(jù),1停止,一幀數(shù)據(jù)11位。方式2的波特率固定為晶晶振頻率的1/64或1/32,方式3的波特率由定時(shí)器1的溢出率決定。
方式2和方式2的差別僅在于波特率的選取不同,兩種方式下,接收到的停止位與SBUF,RB8,RI都無關(guān)。
串口方式1的編程實(shí)現(xiàn)
方式1數(shù)據(jù)輸出時(shí)序圖如下:
當(dāng)數(shù)據(jù)被寫入SBUF寄存器后,單片機(jī)自動(dòng)開始從起始位發(fā)送數(shù)據(jù),發(fā)送到停止位的開始時(shí),
由內(nèi)部硬件將TI置1,向CPU申請(qǐng)中斷,接下來可在中斷服務(wù)程序中進(jìn)行相關(guān)處理,也可選擇不進(jìn)入中斷。
用軟件置REN為1時(shí),接收器以所選擇波特率的16倍速率采樣RXD引腳電平,
檢測(cè)到RXD引腳輸入電平發(fā)聲負(fù)跳變時(shí),則說明起始位有效。
將其移入輸入移位寄存器并開始接受這一幀信息的其余位。
接收過程中,數(shù)據(jù)從輸入移位寄存器右邊移入,起始位移至輸入移位寄存器的最左邊,
控制電路進(jìn)行最后一次移位,當(dāng)RI=0且SM2=0(或結(jié)收到的停止位為1)時(shí),
將接受到的9位數(shù)據(jù)前8位數(shù)據(jù)裝入接收SBUF,第九位(停止位)進(jìn)入RB8,并置RI=1,向CPU申請(qǐng)中斷,
在進(jìn)行串口的相關(guān)操作之前,需要對(duì)單片機(jī)的一些特殊寄存器和進(jìn)行初始化設(shè)置
主要是設(shè)置產(chǎn)生波特率的定時(shí)器1,串行口控制和中斷控制,具體步驟如下:
確定T1的工作方式(編程TMOD寄存器)
計(jì)算T1的初值,裝載TH1和TL1
啟動(dòng)T1(編程TCON中的TR1位)
確定串行口工作方式(編程SCON寄存器)
串行口工作在中斷方式時(shí),要進(jìn)行中斷設(shè)置(編程IE、IP寄存器)
-----------------------------------------------------------------------------------------------------------------------
//串口方式1
TMOD=0X20; //T1定時(shí)器,工作方式2
TH1=0XFD; //T1定時(shí)器裝初值
TL1=0XFD; //T1定時(shí)器裝初值
TR1=1; //啟動(dòng)T1定時(shí)器
REN=1; //允許串口接收
SM0=0; //設(shè)定串口工作方式1
SM1=1; //設(shè)定串口工作方式1
EA=1; //開總中斷
ES=1; //開串口中斷
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
//串口中斷服務(wù)程序
void ser() interrupt 4
{
RI=0; //RI清零;因?yàn)槭盏綌?shù)據(jù)或者或者發(fā)送了數(shù)據(jù)會(huì)由硬件置1
a=SBUF; //將SBUF中的數(shù)據(jù)讀走給a
flag=1; //中斷標(biāo)志位置1
}
-----------------------------------------------------------------------------------------------------------------------
串口方式0
串行口為同步移位寄存器的輸入輸出方式,主要永不擴(kuò)展并行輸入輸出接口,數(shù)據(jù)由RXD(P3.0)引腳輸入或者輸出,同步移位脈沖由TXD(P3.1)引腳輸出,發(fā)送和接收均為8位數(shù)據(jù),低位在先,高位在后。波特率固定fosc/12。
在該模式下,串行口的SBUF是作為同步移位寄存器使用的。
在串行口發(fā)送時(shí)。SBUF相當(dāng)于一個(gè)并行進(jìn)入,串行輸出的移位寄存器,
由單片機(jī)的內(nèi)部總線并行接收八位數(shù)據(jù),并從RXD信號(hào)線串行輸出,在接收操作時(shí),他有相當(dāng)于一個(gè)串行輸入、并行輸出的移位寄存器。該模式下,SM2,RB8,TB8不起作用。
方式0數(shù)據(jù)輸出時(shí)序圖如下:
發(fā)送操作在TI=0時(shí)進(jìn)行,CPU將數(shù)據(jù)移入SBUF后,RXD線上即可發(fā)出8位數(shù)據(jù),TXD上發(fā)送同步脈沖,
8位數(shù)據(jù)發(fā)送完后,TI由硬件置位,并在中斷允許的情況下向CPU申請(qǐng)中斷,
CPU相應(yīng)中斷后,先用軟件是TI清零,然后再給SBUF送下一個(gè)需要發(fā)送的字符,如此重復(fù)上述過程。
方式0數(shù)據(jù)輸入時(shí)序圖如下:
接收過程在REN=1和RI=0的條件下啟動(dòng),為此串行數(shù)據(jù)由RXD線輸入,TXD線輸出同步脈沖,
接收電路接收到8位數(shù)據(jù)后,RI自動(dòng)置位并在中斷允許的條件下向CPU發(fā)出中斷請(qǐng)求,
CPU 查詢到RI為1或者相應(yīng)中斷以后便將SBUF中的數(shù)據(jù)送到累加器,RI需要由軟件復(fù)位,
需要注意的是:
串行口工作模式0并不是一個(gè)同步通訊串口通訊方式,
它的主要用途是與外面的同步移位寄存器相連已達(dá)到擴(kuò)展單片機(jī)輸入并行口和輸出并行口的目的。
其可以通過芯片(74LS164)把串口數(shù)據(jù)轉(zhuǎn)化成并口數(shù)據(jù),通過芯片(74LS165)把并行輸出的數(shù)據(jù)轉(zhuǎn)換成串口輸出
-----------------------------------------------------------------------------------------------------------------------
使用串口工作模式0間隔發(fā)送數(shù)據(jù)0XAA
void main()
{
SCON=0; //串行口工作方式0
EA=1; //開總中斷
ES=1; //允許串口中斷
TI=0; //發(fā)送中斷標(biāo)志位
while(1)
{
SBUF=0XAA;
delay();
}
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
void ser0() interrupt 4
{
TI=0; //清楚發(fā)送中斷標(biāo)志位
}
-----------------------------------------------------------------------------------------------------------------------
串口方式2和方式3
均為11位數(shù)據(jù)的異步通信口,唯一的區(qū)別在于傳輸速率的不同。
TXD數(shù)據(jù)發(fā)送引腳,RXD數(shù)據(jù)接收引腳,1起始,
9數(shù)據(jù)(含1位附加第9位,發(fā)送時(shí)為SCON中的TB8,接收時(shí)為RB8),1停止,一幀數(shù)據(jù)11位。
方式2的波特率固定為晶晶振頻率的1/64或1/32,方式3的波特率由定時(shí)器1的溢出率決定。
串口方式2和方式3一幀數(shù)據(jù)傳送格式,如圖:
串口方式2和方式3輸出時(shí)序圖:
發(fā)送開始時(shí),先把起始位0輸出到TXD管腳,然后發(fā)送移位寄存器的的輸出位(D0)到TXD引腳
每一個(gè)移位脈沖都使輸出移位寄存器的各位右移一位,并由TXD引腳輸出,
第一次移位時(shí),停止位1移入輸出移位寄存器的第9位,以后每次移位,左邊都輸入0
當(dāng)停止移位至輸出位時(shí),左邊其余位全為零,檢測(cè)電路檢測(cè)到這一條件時(shí),使控制電路進(jìn)行最后一次移位,并置TI=1;向CPU請(qǐng)求中斷。
串口方式2和方式3輸入時(shí)序圖:
接受時(shí),數(shù)據(jù)從右邊移入輸入移位寄存器,在起始位0移到最左邊時(shí),控制電路進(jìn)行最后一次移位。
當(dāng)RI=0且SM2=0(或接收到第9位數(shù)據(jù)位1)時(shí),接收到的數(shù)據(jù)裝入接收緩沖器SBUF和RB8(接收數(shù)據(jù)的第9位),置RI=1,向CPU申請(qǐng)中斷,如果條件不滿足,則數(shù)據(jù)丟失,且不置位RI,繼續(xù)搜索RXD引腳的負(fù)跳變。
在方式2和方式3中,要用到SCON寄存器中的TB8位和RB8位,TB8為數(shù)據(jù)發(fā)送的第9位,用于方式2和方式3,由軟件更改,RB8為數(shù)據(jù)接收的第9位,用于方式2和方式3,在方式1中,如果SM2=0,則RB8用于存放接收到的停止位,在方式0下不適用該位。
-----------------------------------------------------------------------------------------------------------------------
使用串口工作方式2發(fā)送0XAA
void main()
{
SM0=1; //SMOSM1為10,串行工作方式2
SM1=0; //11位異步收發(fā)(9位數(shù)據(jù))
TB8=0; //數(shù)據(jù)發(fā)送的第9位
EA=1; //開總中斷
ES=1; //允許串口中斷
TI=0; //發(fā)送中斷標(biāo)志位
while(1)
{
SBUF=0XAA;
delay();
}
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
void ser0() interrupt 4
{
TI=0; //清楚發(fā)送中斷標(biāo)志位
}
-----------------------------------------------------------------------------------------------------------------------
單片機(jī)雙機(jī)通信
通常單片機(jī)通信有以下四種實(shí)現(xiàn)方式:
TTL電平通信
RS-232C通信
RS-422A通信
RS-485通信
TTL電平通信:
RS-232C通信:
RS-422A通信
RS-422A驅(qū)動(dòng)器為雙端驅(qū)動(dòng)器,其中一條線的邏輯為1,另一條線就為0,
具抗干擾型,能夠200mv以上的電位差,
傳輸速率90Kbps,傳輸距離可達(dá)1200m,接口電路如下:(全雙工)
RS-485通信
RS-485是RS-422A的變種,422A是全雙工,485為半雙工,
最多可使用32對(duì)差分器。如在一個(gè)網(wǎng)絡(luò)中連接超過32個(gè),還可使用中繼器。
引起傳輸線采用差動(dòng)信號(hào),所以抗干擾性好,傳輸速率可達(dá)1Mbps,接口如下:
多機(jī)通信
采用主從結(jié)構(gòu),在整個(gè)系統(tǒng)中,有且僅有一個(gè)主機(jī),其余全是從機(jī),多機(jī)通信所應(yīng)遵循的原則如下:
A.所有從機(jī)的SM2=1;處于接收地址幀狀態(tài)
B.主機(jī)發(fā)送一地址幀,其中8位是地址,第9位是地址/數(shù)據(jù)區(qū)分標(biāo)志,該位置1表示地址幀。
所有從機(jī)收到地址幀后,與本季的地址比較,對(duì)于地址相符的從機(jī),
是自己的SM2置0(已接收主機(jī)隨后發(fā)來的數(shù)據(jù)幀),并把本機(jī)地址發(fā)回主機(jī)作為應(yīng)答,
對(duì)于地址不符的,仍保持SM2=1,對(duì)主機(jī)隨后發(fā)來的數(shù)據(jù)幀不予理睬.
C.從機(jī)發(fā)送數(shù)據(jù)結(jié)束后,要發(fā)送一幀校驗(yàn)和,并置第9位(TB8)為1,作為從機(jī)數(shù)據(jù)結(jié)束的標(biāo)志。
D.主機(jī)驗(yàn)證數(shù)據(jù)時(shí),先判斷數(shù)據(jù)接收標(biāo)志(RB8),若RB8=1;表示數(shù)據(jù)傳送結(jié)束,并比較此幀校驗(yàn)和,
若正確則會(huì)送正確信號(hào)00H,命令該從機(jī)復(fù)位(即重新等待地址幀)。
若校驗(yàn)和出錯(cuò),則發(fā)送0FFH,命令該從機(jī)重發(fā)數(shù)據(jù)。
若接受偵的RB8=0;則將數(shù)據(jù)存到緩存區(qū),并準(zhǔn)備接收下一幀信息。
E.主機(jī)接到從機(jī)應(yīng)答地址后,確認(rèn)地址是否相符,如果地址不符,
則發(fā)復(fù)位信號(hào)(數(shù)據(jù)幀中TB8=1),如果地址相符,則TB8清0,開始發(fā)送數(shù)據(jù)。
從機(jī)收到復(fù)位命令后,會(huì)到監(jiān)聽地址狀態(tài)(SM2=1),否則開始接收數(shù)據(jù)和命令。
編程時(shí),可按以下方式操作:
主機(jī)發(fā)送的地址聯(lián)絡(luò)信號(hào)為00H,01H,02H,...(即從機(jī)設(shè)備地址);地址FFH為命令各從機(jī)復(fù)位,即回復(fù)SM2=1;
主機(jī)命令編碼如下:
01H:主機(jī)命令從機(jī)接收數(shù)據(jù);
02H:主機(jī)命令從機(jī)發(fā)送數(shù)句;
若有其他數(shù)據(jù),則都按02H對(duì)待。
從機(jī)狀態(tài)字格式如圖:
若ERR =1;從機(jī)收到非法命令。
若TRDY=1;從機(jī)發(fā)送準(zhǔn)備就緒
若RRDY=1;從機(jī)接收準(zhǔn)備就緒
通常,從機(jī)以中斷方式控制和主機(jī)通訊。
多機(jī)通信主機(jī)流程圖如下:
程序代碼如下:
-----------------------------------------------------------------------------------------------------------------------
#include
#define uchar unsigned char
#define uint unsigned int
#define SLAVE 0X02 //從機(jī)地址
#define NB 16
uchar rbuf[16];
uchar code tbuf[16]={"master transmit"};
void err()
{
SBUF=0XFF;
while(!TI=1);
TI=0;
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
uchar master(uchar add,uchar com)
{
while(1)
{
SBUF=SLAVE; //發(fā)呼叫地址
while(!TI=1);
TI=0;
while(!RI=1);
RI=0; //等待從機(jī)應(yīng)答
if(SBUF!=add)
{
err(); //地址錯(cuò)誤,發(fā)復(fù)位信號(hào)
}
else //地址相符
{
TB8=0; //清地址標(biāo)志
SBUF=cmd; //發(fā)命令
while(!TI=1);
TI=0;
while(!RI=1);
RI=0;
aa=SBUF; //接收狀態(tài)
if(aa&0x08==0x08) //若命令未被接收,發(fā)復(fù)位信號(hào)
{
TB8=1;
err();
}
else
{
if(cmd==0X01) //發(fā)送命令
{
if(aa&0x01==0x01) //從機(jī)準(zhǔn)備好接受
{
do
{
p=0; //清校驗(yàn)和
for(i=0;i
{
SBUF=tbuf[i]; //發(fā)送一數(shù)據(jù)
p+=tbuf[i];
while(!TI=1);
TI=0;
}
SBUF=p; //發(fā)送檢驗(yàn)和
while(!TI=1);
TI=0;
while(!RI=1);
RI=0;
}
while(SBUF!=0); //接收不正確,重新發(fā)送
TB8=1; //置地址標(biāo)志
return(0);
}
else
if(aa&0x02==0x02) //是接收命令,從機(jī)準(zhǔn)備好發(fā)送
{
while(1)
{
p=0; //清檢驗(yàn)和
for(i=0;i
{
while(!RI=1);
RI=0;
rbuf[i]=SBUF; //接收一數(shù)據(jù)
p+=rbuf[i];
}
while(!RI=1);
RI=0;
if(SBUF==p)
{
SBUF=0x00; //校驗(yàn)和相同發(fā)0X00
while(!TI=1);
TI=0;
break;
}
else
{
SBUF=0xFF;
while(!TI=1);
TI=0;
}
}
TB8=1; //置地址標(biāo)志
return(0);
}
}
}
}
}
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
void main()
{
TMOD=0x20; //T/C1定義為方式2
TL1=0XFD; //置初值
TH1=0XFD;
PCON=0X00;
TR1=1;
SCON=0XF0; //串行口方式3
master(SLAVE,0x01);
master(SLAVE,0X02);
while(1);
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
多機(jī)通信從機(jī)流程圖:
程序如下:
-----------------------------------------------------------------------------------------------------------------------
#include
#define uchar unsigned char
#define uint unsigned int
#define SLAVE 0X02
#define BN 16
uchar trbuf[16];
uchar rebuf[16];
bit tready;
bit rready;
void str(void);
void sre(void);
void main()
{
TMOD=0x20; //T/C1定義為方式2
TH1=0XFD;
TL1=0XFD;
PCON=0X00;
TR1=1;
SCON=0XF0;
ES=1; //開串行口中斷
EA=1; //開總中斷
while(1)
{
tready=1;
rready=1;
} //假定準(zhǔn)備好發(fā)送和接受
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
void ssio(void) interrupt 4
{
uchar a;
RI=0;
ES=0;
if(SBUF!=SLAVE)
{
ES=1;
goto reti;
} //非本機(jī)地址繼續(xù)監(jiān)聽
SM2=0; //取消監(jiān)聽狀態(tài)
SBUF=SLAVE; //從本地址發(fā)回
while(!TI=1);
TI=0;
while(!RI=1);
RI=0;
if(RB8=1)
{
SM2=1;
ES=1;
goto reti;
} //是復(fù)位信號(hào),恢復(fù)監(jiān)聽
a=SBUF; //接收命令
if(a==0X01)
{
if(rready=1)
SBUF=0X01; //接收準(zhǔn)備好發(fā)狀體
else
SBUF=0X00;
while(!TI=1);
TI=0;
while(!RI=1);
RI=0;
if(RB8==1)
{
SM2=1;
ES=1;
goto reti;
}
sre(); //接收數(shù)據(jù)
}
else
{
if(a==0X02) //從機(jī)向主機(jī)發(fā)送數(shù)據(jù)
{
if(tready=1)
SBUF=0X02; //發(fā)送準(zhǔn)備好發(fā)狀體
else
SBUF=0X00;
while(!TI=1);
TI=0;
while(!RI=1);
RI=0;
if(RB8==1)
{
SM2=1;
ES=1;
goto reti;
}
str(); //發(fā)送數(shù)據(jù)
}
else
{
SBUF=0X80; //命令非法,發(fā)狀態(tài)
while(!TI=1);
TI=0;
SM2=1;
ES=1; //恢復(fù)監(jiān)聽
}
}
reti;
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
void str(void) //發(fā)送數(shù)據(jù)塊
{
uchr p,i;
tready=0;
do
{
p=0; //清校驗(yàn)和
for(i=0;i
{
SBUF=trbuf[i]; //發(fā)送一數(shù)據(jù)
p+=trbuf[i];
while(!TI=1);
TI=0;
}
SBUF=p; //發(fā)送校驗(yàn)和
while(!TI=1);
TI=0;
while(!RI=1);
RI=0;
}while(SBUF!=0); //主機(jī)接收不正確,從新發(fā)送
SM2=1;
ES=1;
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
void sre(void) //接收數(shù)據(jù)塊
{
uchr p,i;
rready=0;
while(1)
{
p=0; //清校驗(yàn)和
for(i=0;i
{
while(!RI=1);
RI=0;
rebuf[i]=SBUF; //接收數(shù)據(jù)
p+=rebuf[i];
}
while(!RI=1);
RI=0;
if(SBUF==p)
{
SBUF=0X00;
break;
} //校驗(yàn)和相同發(fā)00
else
{
SBUF=0XFF; //校驗(yàn)值不同發(fā)0FF,重新接收
while(!TI=1);
TI=0;
}
}
SM2=1;
ES=1;
}
-----------------------------------------------------------------------------------------------------------------------
以上是51串口的通訊的協(xié)議內(nèi)容,也可以說是串口通訊協(xié)議。其與Uart等具有相同的傳輸性質(zhì):雙向傳輸,全雙工!
上一篇:C語言字符數(shù)組和字符串
下一篇:C語言字符串處理函數(shù)
掃碼關(guān)注我們
傳真:0755-82591176
郵箱:vicky@yingtexin.net
地址:深圳市龍華區(qū)民治街道民治大道973萬眾潤(rùn)豐創(chuàng)業(yè)園A棟2樓A08