因?yàn)槌醮谓佑|通信方面的技術(shù),所以我對(duì)這個(gè)程序進(jìn)行一下解釋?zhuān)蠹铱梢赃吙次业慕忉屵吙闯绦�,把底層原理先徹底弄懂�?/div>變量定義部分就不用說(shuō)了,直接看main主函數(shù)。首先是對(duì)通信的波特率的設(shè)定,在這里我們配置的波特率是9600,那么串口調(diào)試助手也得是9600。配置波特率的時(shí)候,我們用的是定時(shí)器0的模式2。模式2中,不再是TH0代表高8位,TL0代表低8位了,而只有TL0在進(jìn)行計(jì)數(shù)了。當(dāng)TL0溢出后,不僅僅會(huì)讓TF0變1,而且還會(huì)將TH0中的內(nèi)容重新自動(dòng)裝到TL0中。這樣有一個(gè)好處,我們可以把我們想要的定時(shí)器初值提前存在TH0中,當(dāng)TL0溢出后,TH0自動(dòng)把初值就重新送入TL0了,全自動(dòng)的,不需要程序上再給TL0重新賦值了,配置方式很簡(jiǎn)單,大家可以自己看下程序并且計(jì)算一下初值。
波特率設(shè)置好以后,打開(kāi)中斷,然后等待接收串口調(diào)試助手下發(fā)的數(shù)據(jù)。接收數(shù)據(jù)的時(shí)候,首先要進(jìn)行低電平檢測(cè) while (PIN_RXD),若沒(méi)有低電平則說(shuō)明沒(méi)有數(shù)據(jù),一旦檢測(cè)到低電平,就進(jìn)入啟動(dòng)接收函數(shù)StartRXD()。接收函數(shù)最開(kāi)始啟動(dòng)半個(gè)波特率周期,初學(xué)可能這里不是很明白。大家回頭看一下我們的圖11-2里邊的串口數(shù)據(jù)示意圖,信號(hào)在數(shù)據(jù)位電平變化的時(shí)候去讀,因?yàn)闀r(shí)序上的誤差以及信號(hào)穩(wěn)定性的問(wèn)題很容易讀錯(cuò)數(shù)據(jù),所以我們希望在信號(hào)最穩(wěn)定的時(shí)候去讀數(shù)據(jù)。除了信號(hào)變化的那個(gè)沿的位置外,其他位置都很穩(wěn)定,那么我們現(xiàn)在就約定在信號(hào)中間位置去讀取電平狀態(tài),這樣能夠保證我們信號(hào)讀的是對(duì)的。
一旦讀到了起始信號(hào),我們就把當(dāng)前狀態(tài)設(shè)定成接受狀態(tài),并且打開(kāi)定時(shí)器中斷,第一次是半個(gè)周期進(jìn)入中斷后,對(duì)起始位進(jìn)行二次判斷一下,確認(rèn)一下起始位是低電平,而不是一個(gè)干擾信號(hào)。以后每經(jīng)過(guò)9600分之一秒進(jìn)入一次中斷,并且把這個(gè)引腳的狀態(tài)讀到RxdBuf里邊。等待接收完畢之后,我們?cè)侔堰@個(gè)RxdBuf加1,再通過(guò)TXD引腳發(fā)送出去,同樣需要先發(fā)一位起始位,然后發(fā)8個(gè)數(shù)據(jù)位,再發(fā)結(jié)束位,發(fā)送完畢后,程序運(yùn)行到while (PIN_RXD),等待第二輪信號(hào)接收的開(kāi)始。
#include <reg52.h>
sbit PIN_RXD = P3^0; //接收引腳定義
sbit PIN_TXD = P3^1; //發(fā)送引腳定義
bit RxdOrTxd = 0; //指示當(dāng)前狀態(tài)為接收還是發(fā)送
bit RxdEnd = 0; //接收結(jié)束標(biāo)志
bit TxdEnd = 0; //發(fā)送結(jié)束標(biāo)志
unsigned char RxdBuf = 0; //接收緩沖器
unsigned char TxdBuf = 0; //發(fā)送緩沖器
void ConfigUART(unsigned int baud);
void StartTXD(unsigned char dat);
void StartRXD();
void main ()
{
ConfigUART(9600); //配置波特率為9600
EA = 1; //開(kāi)總中斷
while(1)
{
while (PIN_RXD); //等待接收引腳出現(xiàn)低電平,即起始位
StartRXD(); //啟動(dòng)接收
while (!RxdEnd); //等待接收完成
StartTXD(RxdBuf+1); //接收到的數(shù)據(jù)+1后,發(fā)送回去
while (!TxdEnd); //等待發(fā)送完成
}
}
void ConfigUART(unsigned int baud) //串口配置函數(shù),baud為波特率
{
TMOD &= 0xF0; //清零T0的控制位
TMOD |= 0x02; //配置T0為模式2
TH0 = 256 - (11059200/12) / baud; //計(jì)算T0重載值
}
void StartRXD() //啟動(dòng)串行接收
{
TL0 = 256 - ((256-TH0) >> 1); //接收啟動(dòng)時(shí)的T0定時(shí)為半個(gè)波特率周期
ET0 = 1; //使能T0中斷
TR0 = 1; //啟動(dòng)T0
RxdEnd = 0; //清零接收結(jié)束標(biāo)志
RxdOrTxd = 0; //設(shè)置當(dāng)前狀態(tài)為接收
}
void StartTXD(unsigned char dat) //啟動(dòng)串行發(fā)送,dat為待發(fā)送字節(jié)數(shù)據(jù)
{
TxdBuf = dat; //待發(fā)送數(shù)據(jù)保存到發(fā)送緩沖器
TL0 = TH0; //T0計(jì)數(shù)初值為重載值
ET0 = 1; //使能T0中斷
TR0 = 1; //啟動(dòng)T0
PIN_TXD = 0; //發(fā)送起始位
TxdEnd = 0; //清零發(fā)送結(jié)束標(biāo)志
RxdOrTxd = 1; //設(shè)置當(dāng)前狀態(tài)為發(fā)送
}
void InterruptTimer0() interrupt 1 //T0中斷服務(wù)函數(shù),處理串行發(fā)送和接收
{
static unsigned char cnt = 0; //bit計(jì)數(shù)器,記錄當(dāng)前正在處理的位
if (RxdOrTxd) //串行發(fā)送處理
{
cnt++;
if (cnt <= 8) //低位在先依次發(fā)送8bit數(shù)據(jù)位
{
PIN_TXD = TxdBuf & 0x01;
TxdBuf >>= 1;
}
else if (cnt == 9) //發(fā)送停止位
{
PIN_TXD = 1;
}
else //發(fā)送結(jié)束
{
cnt = 0; //復(fù)位bit計(jì)數(shù)器
TR0 = 0; //關(guān)閉T0
TxdEnd = 1; //置發(fā)送結(jié)束標(biāo)志
}
}
else //串行接收處理
{
if (cnt == 0) //處理起始位
{
if (!PIN_RXD) //起始位為0時(shí),清零接收緩沖器,準(zhǔn)備接收數(shù)據(jù)位
{
RxdBuf = 0;
cnt++;
}
else //起始位不為0時(shí),中止接收
{
TR0 = 0; //關(guān)閉T0
}
}
else if (cnt <= 8) //處理8位數(shù)據(jù)位
{
RxdBuf >>= 1; //低位在先,所以將之前接收的位向右移
if (PIN_RXD) //接收腳為1時(shí),緩沖器最高位置1;為0時(shí)不處理即仍保持移位后的0
{
RxdBuf |= 0x80;
}
cnt++;
}
else //停止位處理
{
cnt = 0; //復(fù)位bit計(jì)數(shù)器
TR0 = 0; //關(guān)閉T0
if (PIN_RXD) //停止位為1時(shí),方能認(rèn)為數(shù)據(jù)有效
{
RxdEnd = 1; //置接收結(jié)束標(biāo)志
}
}
}
}
同學(xué)們通過(guò)學(xué)習(xí)我們的程序,也慢慢感受到了,程序的延時(shí)部分已經(jīng)不再使用簡(jiǎn)單的delay來(lái)完成了,我們要通過(guò)我們的程序編寫(xiě)積累,慢慢提高自己靈活運(yùn)用定時(shí)器的能力。一個(gè)小小的定時(shí)器,可以幫我們完成很多很多工作。
11.5 UART串口通信的基本應(yīng)用11.5.1 通信的三種基本類(lèi)型我們常用的通信通�?梢苑譃閱喂ぁ腚p工、全雙工通信。
單工就是指只允許一方向另外一方傳送信息,而另一方不能回傳信息。比如我們的電視遙控器,我們的收音機(jī)廣播等,都是單工通信技術(shù)。
半雙工是指數(shù)據(jù)可以在雙方之間相互傳播,但是同一時(shí)刻只能其中一方發(fā)給另外一方,比如我們的對(duì)講機(jī)就是典型的半雙工。
全雙工通信就發(fā)送數(shù)據(jù)的同時(shí)也能夠接受數(shù)據(jù),兩者同步進(jìn)行,就如同我們的電話一樣,我們說(shuō)話的同時(shí)也可以聽(tīng)到對(duì)方的聲音。
11.5.2 UART模塊介紹IO口模擬串口通信,大家了解了串口通信的實(shí)質(zhì),但是我們的單片機(jī)程序卻需要不停的檢測(cè)掃描單片機(jī)IO口收到的數(shù)據(jù),大量占用了CPU資源。這時(shí)候就會(huì)有聰明人想了,其實(shí)我們不是很關(guān)心通信的過(guò)程,我們只需要一個(gè)通信的結(jié)果,最終得到接收到的數(shù)據(jù)就行了。這樣我們可以在單片機(jī)內(nèi)部做一個(gè)硬件模塊,讓他自動(dòng)接收數(shù)據(jù),接收完了,通知我們一下就可以了,我們的51單片機(jī)內(nèi)部就存在這樣一個(gè)UART模塊,要正確使用它,當(dāng)然還得先把對(duì)應(yīng)的特殊功能寄存器配置好。
51單片機(jī)的UART串行口的結(jié)構(gòu)由串行口控制寄存器SCON、發(fā)送和接收電路三部分構(gòu)成,先來(lái)了解一下串口控制寄存器SCON。
表11-1 SCON--串行控制寄存器的位分配(地址:98H)
可位尋址;復(fù)位值:0x00;復(fù)位源:任何復(fù)位
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
符號(hào) | SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
表11-2 SCON--串行控制寄存器的位描述
| | |
| | 這兩位共同決定了串口通信的模式0到模式3共4種模式。我們最常用的就是模式1,也就是SM0=0,SM1=1,下邊我們重點(diǎn)就講模式1,其他模式從略。 |
| |
| | 多機(jī)通信控制位(很少用),模式1直接清零。 |
| | 使能串行接收。由軟件置位使能接收,軟件清零則禁止接收 |
| | 模式2和3中將要發(fā)送的第9位數(shù)據(jù)(很少用) |
| | 模式2和3中接收第9位數(shù)據(jù)(很少用),模式1用來(lái)接收停止位 |
| | 發(fā)送中斷標(biāo)志位,模式1下,在數(shù)據(jù)位最后一位發(fā)送結(jié)束,開(kāi)始發(fā)送停止位時(shí)由硬件自動(dòng)置1,必須通過(guò)軟件清零。也就是說(shuō),再發(fā)送前我們清零TI,發(fā)送數(shù)據(jù),數(shù)據(jù)發(fā)送到停止位時(shí),TI硬件置1,方便我們CPU查詢(xún)發(fā)送完畢狀態(tài)。 |
| | 接收中斷標(biāo)志位,當(dāng)接收電路接收到停止位的中間位置時(shí),RI由硬件置1。也就是說(shuō),接收數(shù)據(jù)之前我們必須清零RI,接受數(shù)據(jù)到停止位的中間位置時(shí),RI硬件置1,方便我們CPU查詢(xún)到接收狀態(tài)。 |
前邊學(xué)了那么多寄存器的配置,相信SCON這個(gè)地方,對(duì)于大多數(shù)同學(xué)來(lái)說(shuō)已經(jīng)不是難點(diǎn)了,應(yīng)該能看懂并且可以自己配置了。對(duì)于串口的四種模式,模式1是最常用的,就是我們前邊提到的1位起始位,8位數(shù)據(jù)位和1位結(jié)束位。因?yàn)槲覀兊慕坛滩煌诮炭茣?shū),只要有的功能都一一介紹,我們只介紹實(shí)用的技術(shù),所以其他3種模式,真正遇到需要使用的時(shí)候大家再去查資料就行。
在我們使用IO口模擬串口通信的時(shí)候,我們串口的波特率是使用定時(shí)器0的中斷體現(xiàn)出來(lái)的。在實(shí)際串口模塊中,有一個(gè)專(zhuān)門(mén)的波特率發(fā)生器用來(lái)控制發(fā)送數(shù)據(jù)的速度和讀取接收數(shù)據(jù)的速度。對(duì)于STC89C52RC單片機(jī)來(lái)講,這個(gè)波特率發(fā)生器只能由定時(shí)器1或定時(shí)器2產(chǎn)生,而不能由定時(shí)器0產(chǎn)生,這和我們模擬的通信是完全不同的概念。
如果用定時(shí)器2,需要配置額外的寄存器,默認(rèn)是使用定時(shí)器1的,我們本章內(nèi)容主要是使用定時(shí)器1作為波特率發(fā)生器來(lái)講解,方式1下的波特率發(fā)生器必須使用定時(shí)器1的模式2,也就是自動(dòng)重裝載模式,定時(shí)器的初值具體的計(jì)算公式是:
TH1 = TL1 = 256 - 晶振值/12 /2/16 /波特率
和波特率有關(guān)的還有一個(gè)寄存器,是一個(gè)電源管理寄存器PCON,他的最高位可以把波特率提高一倍,也就是如果寫(xiě)PCON |=0x80以后,計(jì)算公式就成了
TH1 = TL1 = 256 - 晶振值/12 /16 /波特率
數(shù)字的含義這里解釋一下,256是8位數(shù)據(jù)的溢出值,也就是TL1的溢出值,11059200就是我們板子上單片機(jī)的晶振,12是說(shuō)1個(gè)機(jī)器周期是12個(gè)時(shí)鐘周期,值得關(guān)注的是這個(gè)16,重點(diǎn)說(shuō)明。我們?cè)?/font>IO口模擬串口通信接收數(shù)據(jù)的時(shí)候,我們采集的是這一位數(shù)據(jù)的中間位置,而實(shí)際上串口模塊比我們模擬的要復(fù)雜和精確一些。他采取的方式是把一位信號(hào)采集16次,其中第7、8、9次取出來(lái),這三次中其中兩次如果是高電平,那么就認(rèn)定這一位數(shù)據(jù)是1,如果兩次是低電平,那么就認(rèn)定這一位是0,這樣一旦受到意外干擾讀錯(cuò)一次數(shù)據(jù),也依然可以保證最終數(shù)據(jù)的正確性。
了解了串口采集模式,在這里要給大家留一個(gè)思考題�!熬д裰�/12/2/16/波特率”這個(gè)地方計(jì)算的時(shí)候,出現(xiàn)不能除盡,或者出現(xiàn)小數(shù)怎么辦,允許出現(xiàn)多大的偏差?把這部分理解了,也就理解了我們的晶振為何使用11.0592M了。
串口通信的發(fā)送和接收電路,我們主要了解一下他們?cè)谖锢砩嫌?font face="Times New Roman">2個(gè)名字相同的SBUF寄存器,他們的地址也都是99H,但是一個(gè)用來(lái)做發(fā)送緩沖,一個(gè)用來(lái)做接收緩沖。意思就是說(shuō),有2個(gè)房間,兩個(gè)房間的門(mén)牌號(hào)是一樣的,其中一個(gè)只出人不進(jìn)人,另外一個(gè)只進(jìn)人不出人,這樣的話,我們就可以實(shí)現(xiàn)UART的全雙工通信,相互之間不會(huì)產(chǎn)生干擾。但是在邏輯上呢,我們每次只操作SBUF,單片機(jī)會(huì)自動(dòng)根據(jù)對(duì)它執(zhí)行的是“讀”還是“寫(xiě)”操作來(lái)選擇是接收SBUF還是發(fā)送SBUF,后邊通過(guò)程序,我們就會(huì)徹底了解這個(gè)問(wèn)題。
11.5.3 UART串口程序一般情況下,我們編寫(xiě)串口通信程序的基本步驟如下所示:
1、配置串口為模式1。
2、配置定時(shí)器T1為模式2,即自動(dòng)重裝模式。
3、確定波特率大小,計(jì)算定時(shí)器TH1和TL1的初值,如果有需要可以使用PCON進(jìn)行波特率加倍。
4、打開(kāi)定時(shí)器控制寄存器TR1,讓定時(shí)器跑起來(lái)。
這個(gè)地方還要特別注意一下,就是在使用T1做波特率發(fā)生器的時(shí)候,千萬(wàn)不要再使能T1的中斷了。
我們先來(lái)看一下由IO口模擬串口通信直接改為使用硬件UART模塊時(shí)程序代碼,看看程序是不是簡(jiǎn)單了很多,因?yàn)榇蟛糠值墓ぷ饔布K都替我們做了。程序功能和IO口模擬的是完全一樣的。
#include <reg52.h>
void ConfigUART(unsigned int baud);
void main ()
{
ConfigUART(9600); //配置波特率為9600
while(1)
{
while (!RI); //等待接收完成
RI = 0; //清零接收中斷標(biāo)志位
SBUF = SBUF + 1; //接收到的數(shù)據(jù)+1后,發(fā)送回去;
//等號(hào)左邊的SBUF實(shí)際上就是發(fā)送SBUF,因?yàn)閷?duì)它的操作是“寫(xiě)”;
//等號(hào)右邊的是接收SBUF,因?yàn)閷?duì)它的操作是“讀”。
while (!TI); //等待發(fā)送完成
TI = 0; //清零發(fā)送中斷標(biāo)志位
}
}
void ConfigUART(unsigned int baud) //串口配置函數(shù),baud為波特率
{
SCON = 0x50; //配置串口為模式1
TMOD &= 0x0F; //清零T1的控制位
TMOD |= 0x20; //配置T1為模式2
TH1 = 256 - (11059200/12/32) / baud; //計(jì)算T1重載值
TL1 = TH1; //初值等于重載值
ET1 = 0; //禁止T1中斷
TR1 = 1; //啟動(dòng)T1
}
當(dāng)然了,這個(gè)程序還是在主循環(huán)里等待接收中斷標(biāo)志位和發(fā)送中斷標(biāo)志位的方法來(lái)編寫(xiě)的,而實(shí)際工程開(kāi)發(fā)中,當(dāng)然就不能這么干了,所以就用到了串口中斷,來(lái)看一下程序。
#include <reg52.h>
void ConfigUART(unsigned int baud);
void main ()
{
ConfigUART(9600); //配置波特率為9600
while(1);
}
void ConfigUART(unsigned int baud) //串口配置函數(shù),baud為波特率
{
SCON = 0x50; //配置串口為模式1
TMOD &= 0x0F; //清零T1的控制位
TMOD |= 0x20; //配置T1為模式2
TH1 = 256 - (11059200/12/32) / baud; //計(jì)算T1重載值
TL1 = TH1; //初值等于重載值
ET1 = 0; //禁止T1中斷
TR1 = 1; //啟動(dòng)T1
ES = 1; //打開(kāi)串口中斷
EA = 1; //打開(kāi)總中斷
}
void InterruptUART() interrupt 4
{
if (RI) //接收到字節(jié)
{
RI = 0; //手動(dòng)清零接收中斷標(biāo)志位
SBUF = SBUF + 1;//接收數(shù)據(jù)+1發(fā)回去,左邊為發(fā)送SBUF,右邊為接收SBUF。
}
if (TI) //字節(jié)發(fā)送完畢
{
TI = 0; //手動(dòng)清零發(fā)送中斷標(biāo)志位
}
}
大家可以試驗(yàn)一下試試,看看是不是和前邊用IO口模擬通信實(shí)現(xiàn)的效果一致,而主循環(huán)卻完全空出來(lái)了,我們就可以隨意添加其它功能代碼進(jìn)去。
11.6 字符和數(shù)據(jù)之間的轉(zhuǎn)換我們學(xué)串口通信的應(yīng)用主要是實(shí)現(xiàn)單片機(jī)和電腦之間的信息互發(fā),可以用電腦控制單片機(jī)的一些信息,可以把單片機(jī)的一些信息狀況發(fā)給電腦上的軟件。下面我們就做一個(gè)簡(jiǎn)單的例程,實(shí)現(xiàn)單片機(jī)串口調(diào)試助手發(fā)送的數(shù)據(jù),在我們開(kāi)發(fā)板上的數(shù)碼管上顯示出來(lái)。
#include <reg52.h>
sbit ADDR3 = P1^3; //LED選擇地址線3
sbit ENLED = P1^4; //LED總使能引腳
unsigned char code LedChar[] = { //數(shù)碼管顯示字符轉(zhuǎn)換表
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6] = { //數(shù)碼管
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
unsigned char T0RH = 0; //T0重載值的高字節(jié)
unsigned char T0RL = 0; //T0重載值的低字節(jié)
unsigned char RxdByte = 0; //串口接收到的字節(jié)
void ConfigTimer0(unsigned int ms);
void ConfigUART(unsigned int baud);
void main ()
{
P0 = 0xFF; //P0口初始化
ADDR3 = 1; //選擇數(shù)碼管
ENLED = 0; //LED總使能
EA = 1; //開(kāi)總中斷
ConfigTimer0(1); //配置T0定時(shí)1ms
ConfigUART(9600); //配置波特率為9600
while(1)
{ //將接收字節(jié)在數(shù)碼管上以十六進(jìn)制形式顯示出來(lái)
LedBuff[0] = LedChar[RxdByte & 0x0F];
LedBuff[1] = LedChar[RxdByte >> 4];
}
}
void ConfigTimer0(unsigned int ms) //T0配置函數(shù)
{
unsigned long tmp;
tmp = 11059200 / 12; //定時(shí)器計(jì)數(shù)頻率
tmp = (tmp * ms) / 1000; //計(jì)算所需的計(jì)數(shù)值
tmp = 65536 - tmp; //計(jì)算定時(shí)器重載值
tmp = tmp + 31; //修正中斷響應(yīng)延時(shí)造成的誤差
T0RH = (unsigned char)(tmp >> 8); //定時(shí)器重載值拆分為高低字節(jié)
T0RL = (unsigned char)tmp;
TMOD &= 0xF0; //清零T0的控制位
TMOD |= 0x01; //配置T0為模式1
TH0 = T0RH; //加載T0重載值
TL0 = T0RL;
ET0 = 1; //使能T0中斷
TR0 = 1; //啟動(dòng)T0
}
void ConfigUART(unsigned int baud) //串口配置函數(shù),baud為波特率
{
SCON = 0x50; //配置串口為模式1
TMOD &= 0x0F; //清零T1的控制位
TMOD |= 0x20; //配置T1為模式2
TH1 = 256 - (11059200/12/32) / baud; //計(jì)算T1重載值
TL1 = TH1; //初值等于重載值
ET1 = 0; //禁止T1中斷
ES = 1; //使能串口中斷
TR1 = 1; //啟動(dòng)T1
}
void LedScan() //LED顯示掃描函數(shù)
{
static unsigned char index = 0;
P0 = 0xFF; //關(guān)閉所有段選位,顯示消隱
P1 = (P1 & 0xF8) | index; //位選索引值賦值到P1口低3位
P0 = LedBuff[index]; //相應(yīng)顯示緩沖區(qū)的值賦值到P0口
if (index < 5) //位選索引0-5循環(huán),因有6個(gè)數(shù)碼管
index++;
else
index = 0;
}
void InterruptTimer0() interrupt 1 //T0中斷服務(wù)函數(shù)
{
TH0 = T0RH; //定時(shí)器重新加載重載值
TL0 = T0RL;
LedScan(); //LED掃描顯示
}
void InterruptUART() interrupt 4
{
if (RI) //接收到字節(jié)
{
RI = 0; //手動(dòng)清零接收中斷標(biāo)志位
RxdByte = SBUF; //接收到的數(shù)據(jù)保存到接收字節(jié)變量中
SBUF = RxdByte; //接收到的數(shù)據(jù)又直接發(fā)回,這叫回顯-"echo",以提示用戶(hù)輸入的信息是否已正確接收
}
if (TI) //字節(jié)發(fā)送完畢
{
TI = 0; //手動(dòng)清零發(fā)送中斷標(biāo)志位
}
}
細(xì)心的同學(xué)可能會(huì)發(fā)現(xiàn),在串口調(diào)試助手發(fā)送選項(xiàng)和接收選項(xiàng)處,還有個(gè)“字符格式發(fā)送”和“字符格式顯示”,這是什么意思呢?