詳細解析串口通信的原理及USB轉串口通信
發布時間:2018-05-07 來源:傳感器技術 責任編輯:lina
【導讀】串口通信(SerialCommunicaTIons)的概念非常簡單,串口按位(bit)發送和接收字節。盡管比按字節(byte)的並行通信慢,但是串口可以在使用一根線發送數據的同時用另一根線接收數據。它很簡單並且能夠實現遠距離通信。
串口通信的原理
串口通信(SerialCommunicaTIons)的概念非常簡單,串口按位(bit)發送和接收字節。盡管比按字節(byte)的並行通信慢,但是串口可以在使用一根線發送數據的同時用另一根線接收數據。它很簡單並且能夠實現遠距離通信。比如IEEE488定義並行通行狀態時,規定設備線總長不得超過20米,並且任意兩個設備間的長度不得超過2米;而對於串口而言,長度可達1200米。典型地,串口用於ASCII碼字符的傳輸。通信使用3根線完成,分別是地線、發送、接(jie)收(shou)。由(you)於(yu)串(chuan)口(kou)通(tong)信(xin)是(shi)異(yi)步(bu)的(de),端(duan)口(kou)能(neng)夠(gou)在(zai)一(yi)根(gen)線(xian)上(shang)發(fa)送(song)數(shu)據(ju)同(tong)時(shi)在(zai)另(ling)一(yi)根(gen)線(xian)上(shang)接(jie)收(shou)數(shu)據(ju)。其(qi)他(ta)線(xian)用(yong)於(yu)握(wo)手(shou),但(dan)不(bu)是(shi)必(bi)須(xu)的(de)。串(chuan)口(kou)通(tong)信(xin)最(zui)重(zhong)要(yao)的(de)參(can)數(shu)是(shi)波(bo)特(te)率(lv)、數據位、停止位和奇偶校驗。對於兩個進行通信的端口,這些參數必須匹配。

a,波特率:這是一個衡量符號傳輸速率的參數。指的是信號被調製以後在單位時間內的變化,即單位時間內載波參數變化的次數,如每秒鍾傳送240個字符,而每個字符格式包含10位(1個起始位,1個停止位,8個數據位),這時的波特率為240Bd,比特率為10位*240個/秒=2400bps。一般調製速率大於波特率,比如曼徹斯特編碼)。通常電話線的波特率為14400,28800和36600。波特率可以遠遠大於這些值,但是波特率和距離成反比。高波特率常常用於放置的很近的儀器間的通信,典型的例子就是GPIB設備的通信。
b,數據位:這是衡量通信中實際數據位的參數。當計算機發送一個信息包,實際的數據往往不會是8位的,標準的值是6、7和8位。如何設置取決於你想傳送的信息。比如,標準的ASCII碼是0~127(7位)。擴展的ASCII碼是0~255(8位)。如果數據使用簡單的文本(標準ASCII碼),那麼每個數據包使用7位數據。每個包是指一個字節,包括開始/停止位,數據位和奇偶校驗位。由於實際數據位取決於通信協議的選取,術語“包”指任何通信的情況。
c,停止位:用於表示單個包的最後一位。典型的值為1,1.5和2位(wei)。由(you)於(yu)數(shu)據(ju)是(shi)在(zai)傳(chuan)輸(shu)線(xian)上(shang)定(ding)時(shi)的(de),並(bing)且(qie)每(mei)一(yi)個(ge)設(she)備(bei)有(you)其(qi)自(zi)己(ji)的(de)時(shi)鍾(zhong),很(hen)可(ke)能(neng)在(zai)通(tong)信(xin)中(zhong)兩(liang)台(tai)設(she)備(bei)間(jian)出(chu)現(xian)了(le)小(xiao)小(xiao)的(de)不(bu)同(tong)步(bu)。因(yin)此(ci)停(ting)止(zhi)位(wei)不(bu)僅(jin)僅(jin)是(shi)表(biao)示(shi)傳(chuan)輸(shu)的(de)結(jie)束(shu),並(bing)且(qie)提(ti)供(gong)計(ji)算(suan)機(ji)校(xiao)正(zheng)時(shi)鍾(zhong)同(tong)步(bu)的(de)機(ji)會(hui)。適(shi)用(yong)於(yu)停(ting)止(zhi)位(wei)的(de)位(wei)數(shu)越(yue)多(duo),不(bu)同(tong)時(shi)鍾(zhong)同(tong)步(bu)的(de)容(rong)忍(ren)程(cheng)度(du)越(yue)大(da),但(dan)是(shi)數(shu)據(ju)傳(chuan)輸(shu)率(lv)同(tong)時(shi)也(ye)越(yue)慢(man)。
d,奇偶校驗位:在串口通信中一種簡單的檢錯方式。有四種檢錯方式:偶、奇、高和低。當然沒有校驗位也是可以的。對於偶和奇校驗的情況,串口會設置校驗位(數據位後麵的一位),用一個值確保傳輸的數據有偶個或者奇個邏輯高位。例如,如果數據是011,那麼對於偶校驗,校驗位為0,保證邏輯高的位數是偶數個。如果是奇校驗,校驗位為1,這樣就有3個(ge)邏(luo)輯(ji)高(gao)位(wei)。高(gao)位(wei)和(he)低(di)位(wei)不(bu)真(zhen)正(zheng)的(de)檢(jian)查(zha)數(shu)據(ju),簡(jian)單(dan)置(zhi)位(wei)邏(luo)輯(ji)高(gao)或(huo)者(zhe)邏(luo)輯(ji)低(di)校(xiao)驗(yan)。這(zhe)樣(yang)使(shi)得(de)接(jie)收(shou)設(she)備(bei)能(neng)夠(gou)知(zhi)道(dao)一(yi)個(ge)位(wei)的(de)狀(zhuang)態(tai),有(you)機(ji)會(hui)判(pan)斷(duan)是(shi)否(fou)有(you)噪(zao)聲(sheng)幹(gan)擾(rao)了(le)通(tong)信(xin)或(huo)者(zhe)是(shi)否(fou)傳(chuan)輸(shu)和(he)接(jie)收(shou)數(shu)據(ju)是(shi)否(fou)不(bu)同(tong)步(bu)。
RS232概述
在我們電腦上,一般都會有一個9針的串行接口,這個串行接口叫做RS232接口,它和UART通信有關聯,但是由於現在筆記本電腦不帶9針串口,所以和單片機通信越來越趨於使用USB虛擬串口。
九針串口分工頭和母頭
公頭上5下4,上5從左到右為1.2.3.4.5;下4從左到右為6.7.8.9;
母頭上5下4,上5從左到右為5.4.3.2.1;下4從左到右為9.8.7.6;
RS232接口一共有9個引腳,分別定義是:1、載波檢測DCD;2、接收數據RXD;3、發送數據TXD;4、數據終端準備好DTR;5、信號地線SG;6、數據準備好DSR;7、請求發送RTS;8、清除發送CTS;9、振鈴提示RI。我們要讓這個串口和我們單片機進行通信,我們隻需要關心其中的2腳RXD、3腳TXD和5腳GND即可
雖(sui)然(ran)這(zhe)三(san)個(ge)引(yin)腳(jiao)的(de)名(ming)字(zi)和(he)我(wo)們(men)單(dan)片(pian)機(ji)上(shang)的(de)串(chuan)口(kou)名(ming)字(zi)一(yi)樣(yang),但(dan)是(shi)卻(que)不(bu)能(neng)直(zhi)接(jie)和(he)單(dan)片(pian)機(ji)對(dui)連(lian)通(tong)信(xin),這(zhe)是(shi)為(wei)什(shen)麼(me)呢(ne)?隨(sui)著(zhe)我(wo)們(men)了(le)解(jie)的(de)內(nei)容(rong)越(yue)來(lai)越(yue)多(duo),我(wo)們(men)得(de)慢(man)慢(man)知(zhi)道(dao),不(bu)是(shi)所(suo)有(you)的(de)電(dian)路(lu)都(dou)是(shi)5V代表高電平而0V代表低電平的。對於RS232標準來說,它是個反邏輯,也叫做負邏輯。為何叫負邏輯?它的TXD和RXD的電壓,-3V~-15V電壓代表是1,+3~+15V電壓代表是0。低電平代表的是1,而高電平代表的是0,所以稱之為負邏輯。因此電腦的9針RS232串口是不能和單片機直接連接的,需要用一個電平轉換芯片MAX232來完成
這個芯片就可以實現把標準RS232串口電平轉換成我們單片機能夠識別和承受的UART0V/5V電平。從這裏大家似乎慢慢有點明白了,其實RS232串口和UART串口,它們的協議類型是一樣的,隻是電平標準不同而已,而MAX232這個芯片起到的就是中間人的作用,它把UART電平轉換成RS232電平,也把RS232電平轉換成UART電平,從而實現標準RS232接口和單片機UART之間的通信連接。

USB轉串口通信
隨著技術的發展,工業上還有RS232串口通信的大量使用,但是商業技術的應用上,已經慢慢的使用USB轉UART技術取代了RS232串口,絕大多數筆記本電腦已經沒有串口這個東西了,那我們要實現單片機和電腦之間的通信該怎麼辦呢?
們隻需要在電路上添加一個USB轉串口芯片,就可以成功實現USB通信協議和標準UART串行通信協議的轉換,在我們的開發板上,我們使用的是CH340T這個芯片
我們需要用跳線帽把中間和下邊的針短接在一起。右側的CH340T這個電路很簡單,把電源、晶振接好後,6腳和7腳的DP和DM分別接USB口的2個數據引腳上去,3腳和4腳通過跳線接到了我們單片機的TXD和RXD上去。
CH340T的電路裏3腳位置加了個4148的二極管,是一個小技巧。因為STC89C52這個單片機下載程序時需要冷啟動,就是先點下載後上電,上電瞬間單片機會先檢測需要不需要下載程序。雖然單片機的VCC是由開關來控製,但是由於CH340T的3腳是輸出引腳,如果沒有此二極管,開關後級單片機在斷電的情況下,CH340T的3腳和單片機的P3.0(即RXD)引(yin)腳(jiao)連(lian)在(zai)一(yi)起(qi),有(you)電(dian)流(liu)會(hui)通(tong)過(guo)這(zhe)個(ge)引(yin)腳(jiao)流(liu)入(ru)後(hou)級(ji)電(dian)路(lu)並(bing)且(qie)給(gei)後(hou)級(ji)的(de)電(dian)容(rong)充(chong)電(dian),造(zao)成(cheng)後(hou)級(ji)有(you)一(yi)定(ding)幅(fu)度(du)的(de)電(dian)壓(ya),這(zhe)個(ge)電(dian)壓(ya)值(zhi)雖(sui)然(ran)隻(zhi)有(you)兩(liang)三(san)伏(fu)左(zuo)右(you),但(dan)是(shi)可(ke)能(neng)會(hui)影(ying)響(xiang)到(dao)正(zheng)常(chang)的(de)冷(leng)啟(qi)動(dong)。加(jia)了(le)二(er)極(ji)管(guan)後(hou),一(yi)方(fang)麵(mian)不(bu)影(ying)響(xiang)通(tong)信(xin),另(ling)外(wai)一(yi)個(ge)方(fang)麵(mian)還(hai)可(ke)以(yi)消(xiao)除(chu)這(zhe)種(zhong)不(bu)良(liang)影(ying)響(xiang)。這(zhe)個(ge)地(di)方(fang)可(ke)以(yi)暫(zan)時(shi)作(zuo)為(wei)了(le)解(jie),大(da)家(jia)如(ru)果(guo)自(zi)己(ji)做(zuo)這(zhe)類(lei)電(dian)路(lu),可(ke)以(yi)參(can)考(kao)一(yi)下(xia)。
IO口模擬UART串口通信
UART串口波特率,常用的值是300、600、1200、2400、4800、9600、14400、19200、28800、38400、57600、115200等速率。IO口模擬UART串行通信程序是一個簡單的演示程序,我們使用串口調試助手下發一個數據,數據加1後,再自動返回。
串口調試助手,這裏我們直接使用STC-ISP軟件自帶的串口調試助手,先把串口調試助手的使用給大家說一下,如圖11-6所示。第一步要選擇串口助手菜單,第二步選擇十六進製顯示,第三步選擇十六進製發送,第四步選擇COM口,這個COM口要和自己電腦設備管理器裏的那個COM口一致,波特率按我們程序設定好的選擇,我們程序中讓一個數據位持續時間是1/9600秒,那這個地方選擇波特率就是選9600,校驗位選N,數據位8,停止位1。
串口調試助手的實質就是利用電腦上的UART通信接口,發送數據給我們的單片機,也可以把我們的單片機發送的數據接收到這個調試助手界麵上。
因為初次接觸通信方麵的技術,所以我把後麵的IO模擬串口通信程序進行一下解釋,大家可以邊看我的解釋邊看程序,把底層原理先徹底弄懂。
變量定義部分就不用說了,直接看main主函數。首先是對通信的波特率的設定,在這裏我們配置的波特率是9600,那麼串口調試助手也得是9600。配置波特率的時候,我們用的是定時器T0的模式2。模式2中,不再是TH0代表高8位,TL0代表低8位了,而隻有TL0在進行計數,當TL0溢出後,不僅僅會讓TF0變1,而且還會將TH0中的內容重新自動裝到TL0中。這樣有一個好處,就是我們可以把想要的定時器初值提前存在TH0中,當TL0溢出後,TH0自動把初值就重新送入TL0了,全自動的,不需要程序中再給TL0重新賦值了,配置方式很簡單,大家可以自己看下程序並且計算一下初值。
波特率設置好以後,打開中斷,然後等待接收串口調試助手下發的數據。接收數據的時候,首先要進行低電平檢測while(PIN_RXD),若沒有低電平則說明沒有數據,一旦檢測到低電平,就進入啟動接收函數StartRXD()。接收函數最開始啟動半個波特率周期,初學可能這裏不是很明白。大家回頭看一下我們的圖11-2裏li邊bian的de串chuan口kou數shu據ju示shi意yi圖tu,如ru果guo在zai數shu據ju位wei電dian平ping變bian化hua的de時shi候hou去qu讀du取qu,因yin為wei時shi序xu上shang的de誤wu差cha以yi及ji信xin號hao穩wen定ding性xing的de問wen題ti很hen容rong易yi讀du錯cuo數shu據ju,所suo以yi我wo們men希xi望wang在zai信xin號hao最zui穩wen定ding的de時shi候hou去qu讀du數shu據ju。除chu了le信xin號hao變bian化hua的de那na個ge沿yan的de位wei置zhi外wai,其qi它ta位wei置zhi都dou很hen穩wen定ding,那na麼me我wo們men現xian在zai就jiu約yue定ding在zai信xin號hao中zhong間jian位wei置zhi去qu讀du取qu電dian平ping狀zhuang態tai,這zhe樣yang能neng夠gou保bao證zheng我wo們men讀du的de一yi定ding是shi正zheng確que的de。
一yi旦dan讀du到dao了le起qi始shi信xin號hao,我wo們men就jiu把ba當dang前qian狀zhuang態tai設she定ding成cheng接jie收shou狀zhuang態tai,並bing且qie打da開kai定ding時shi器qi中zhong斷duan,第di一yi次ci是shi半ban個ge周zhou期qi進jin入ru中zhong斷duan後hou,對dui起qi始shi位wei進jin行xing二er次ci判pan斷duan一yi下xia,確que認ren一yi下xia起qi始shi位wei是shi低di電dian平ping,而er不bu是shi一yi個ge幹gan擾rao信xin號hao。以yi後hou每mei經jing過guo1/9600秒進入一次中斷,並且把這個引腳的狀態讀到RxdBuf裏邊。等待接收完畢之後,我們再把這個RxdBuf加1,再通過TXD引腳發送出去,同樣需要先發一位起始位,然後發8個數據位,再發結束位,發送完畢後,程序運行到while(PIN_RXD),等待第二輪信號接收的開始。
uart模塊介紹
IO口模擬串口通信,讓大家了解了串口通信的本質,但是我們的單片機程序卻需要不停的檢測掃描單片機IOkoushoudaodeshuju,daliangzhanyongledanpianjideyunxingshijian。zheshihoujiuhuiyoucongmingrenxiangle,qishiwomenbingbushihenguanxintongxindeguocheng,womenzhixuyaoyigetongxindejieguo,zuizhongdedaojieshoudaodeshujujiuxingle。zheyangwomenkeyizaidanpianjineibuzuoyigeyingjianmokuai,rangtazidongjieshoushuju,jieshouwanle,tongzhiwomenyixiajiukeyile,womende51單片機內部就存在這樣一個UART模塊,要正確使用它,當然還得先把對應的特殊功能寄存器配置好。
51單片機的UART串口的結構由串行口控製寄存器SCON、發送和接收電路三部分構成,先來了解一下串口控製寄存器SCON。
SCON串行控製器的位分配(地址:0x98)
位:符號:複位值: 0:RI:0;1:TI:0;2:RB8:0;3:TB8:0;4:REN:0;5:SM2:0;6:SM1:0;7:SM0:0;
0位RI:接收中斷標誌位,當接收電路接收到停止位的中間位置時,RI由硬件置1,必須通過軟件清零
1位TI:發送中斷標誌位,當發送電路發送到停止位的中間位置時,TI由硬件置1,必須通過軟件清零。
2位RB8:模式2和3中接收到的第9位數據(很少用),模式1用來接收停止位。
3位TB8:模式2和3中要發送的第9位數據(很少用)。
4位REN:使能串行接收。由軟件置位使能接收,軟件清零則禁止接收。
5位SM2:多機通信控製位(極少用),模式1直接清零。
6位SM1和7位SM0:
這兩位共同決定了串口通信的模式0~模式3共4種模式。我們最常用的就是模式1,也就是SM0=0,SM1=1,下邊我們重點就講模式1,其它模式從略。
對於串口的四種模式,模式1是最常用的,就是我們前邊提到的1位起始位,8位數據位和1位停止位。下麵我們就詳細介紹模式1的工作細節和使用方法,至於其它3種模式與此也是大同小異,真正遇到需要使用的時候大家再去查閱相關資料就行了。
在我們使用IO口模擬串口通信的時候,串口的波特率是使用定時器T0的中斷體現出來的。在硬件串口模塊中,有一個專門的波特率發生器用來控製發送和接收數據的速度。對於STC89C52單片機來講,這個波特率發生器隻能由定時器T1或定時器T2產生,而不能由定時器T0產生,這和我們模擬的通信是完全不同的概念。
如果用定時器2,需要配置額外的寄存器,默認是使用定時器1的,我們本章內容主要就使用定時器T1作為波特率發生器來講解,方式1下的波特率發生器必須使用定時器T1的模式2,也就是自動重裝載模式,定時器的重載值計算公式為:
TH1 = TL1 = 256 - 晶振值/12 /2/16 /波特率
和波特率有關的還有一個寄存器,是一個電源管理寄存器PCON,他的最高位可以把波特率提高一倍,也就是如果寫PCON |= 0x80以後,計算公式就成了:
TH1 = TL1 = 256 - 晶振值/12 /16 /波特率
公式中數字的含義這裏解釋一下,256是8位定時器的溢出值,也就是TL1的溢出值,晶振值在我們的開發板上就是11059200,12是說1個機器周期等於12個時鍾周期,值得關注的是這個16,我們來重點說明。在IO口kou模mo擬ni串chuan口kou通tong信xin接jie收shou數shu據ju的de時shi候hou,采cai集ji的de是shi這zhe一yi位wei數shu據ju的de中zhong間jian位wei置zhi,而er實shi際ji上shang串chuan口kou模mo塊kuai比bi我wo們men模mo擬ni的de要yao複fu雜za和he精jing確que一yi些xie。他ta采cai取qu的de方fang式shi是shi把ba一yi位wei信xin號hao采cai集ji16次,其中第7、8、9次取出來,這三次中其中兩次如果是高電平,那麼就認定這一位數據是1,如果兩次是低電平,那麼就認定這一位是0,這樣一旦受到意外幹擾讀錯一次數據,也依然可以保證最終數據的正確性。
串口通信的發送和接收電路在物理上有2個名字相同的SBUF寄存器,它們的地址也都是0x99,但是一個用來做發送緩衝,一個用來做接收緩衝。意思就是說,有2個房間,兩個房間的門牌號是一樣的,其中一個隻出人不進人,另外一個隻進人不出人,這樣的話,我們就可以實現UART的全雙工通信,相互之間不會產生幹擾。但是在邏輯上呢,我們每次隻操作SBUF,單片機會自動根據對它執行的是“讀”還是“寫”操作來選擇是接收SBUF還是發送SBUF,後邊通過程序,我們就會徹底了解這個問題。
UART串口程序:
一般情況下,我們編寫串口通信程序的基本步驟如下所示:
1、配置串口為模式1。
2、配置定時器T1為模式2,即自動重裝模式。
3、根據波特率計算TH1和TL1的初值,如果有需要可以使用PCON進行波特率加倍。
4、打開定時器控製寄存器TR1,讓定時器跑起來。
這裏還要特別注意一下,就是在使用T1做波特率發生器的時候,千萬不要再使能T1的中斷了。
我們先來看一下由IO口模擬串口通信直接改為使用硬件UART模塊時的程序代碼,看看程序是不是簡單了很多,因為大部分的工作硬件模塊都替我們做了。程序功能和IO口模擬的是完全一樣的。

通信實例與ASCLL碼
先拋開我們使用的漢字不談,那麼我們常用的字符就包含了0~9的數字、A~Z/a~z的字母、還有各種標點符號等。那麼在單片機係統裏麵我們怎麼來表示它們呢?ASCII碼(AmericanStandardCodeforInformationInterchange,即美國信息互換標準代碼)可以完成這個使命:我們知道,在單片機中一個字節的數據可以有0~255共256個值,我們取其中的0~127共128個值賦予了它另外一層涵義
我們用字符格式發送一個小寫的a,返回一個十六進製的0x61,數碼管上顯示的也是61,ASCII碼表裏字符a對應十進製是97,等於十六進製的0x61;我們再用字符格式發送一個數字1,返回一個十六進製的0x31,數碼管上顯示的也是31,ASCII表裏字符1對應的十進製是49,等於十六進製的0x31。這下大家就該清楚了:所謂的十六進製發送和十六進製接收,都是按字節數據的真實值進行的;而字符格式發送和字符格式接收,是按ASCII碼(ma)表(biao)中(zhong)字(zi)符(fu)形(xing)式(shi)進(jin)行(xing)的(de),但(dan)它(ta)實(shi)際(ji)上(shang)最(zui)終(zhong)傳(chuan)輸(shu)的(de)還(hai)是(shi)一(yi)個(ge)字(zi)節(jie)數(shu)據(ju)。這(zhe)個(ge)表(biao)格(ge),當(dang)然(ran)不(bu)需(xu)要(yao)大(da)家(jia)去(qu)記(ji)住(zhu),理(li)解(jie)它(ta),用(yong)的(de)時(shi)候(hou)過(guo)來(lai)查(zha)就(jiu)行(xing)了(le)。
51單片機串口通信實例(字符串接收和發送)
#include《reg52.h》
//------------------串口通信協議-----------------//
/*
客戶端數據包格式解釋(長度恒為15):
例如:A01_fmq_01Off___#
A--------數據包的開始標記(可以為A到Z,意味著數據包可以有26種)
01-----設備代號
fmq_01Off___--------指令(長度恒為10),指令的前4個人字符是指令頭部,指令的後6個字符是指令尾部
#---------數據包的結束標記
服務器端數據包格式解釋(長度恒為15):
例如:A02_SenT010250#
A--------數據包的開始標記(可以為A到Z,意味著數據包可以有26種)
02-----設備代號
SenT010250--------指令(長度恒為10),指令的前4個人字符是指令頭部,指令的後6個字符是指令尾部
#---------數據包的結束標記
*/
char buf_string[16]; //定義數據包長度為15個字符
#define deviceID_1Bit ‘0’ //用於串口通信時,定義本地設備ID的第1位
#define deviceID_2Bit ‘2’ //用於串口通信時,定義本地設備ID的第2位
#define datapackage_headflag ‘A’ //用於串口通信時,定義數據包頭部的驗證標記
char DataPackage_DS18B20[16]={datapackage_headflag,deviceID_1Bit,deviceID_2Bit,‘_’,‘S’,‘e’,‘n’,‘T’,‘X’,‘X’,‘X’,‘X’,‘X’,‘X’,‘#’};
char HeartBeat[16]={datapackage_headflag,deviceID_1Bit,deviceID_2Bit,‘_’,‘B’,‘e’,‘a’,‘t’,‘X’,‘X’,‘X’,‘X’,‘X’,‘X’,‘#’};
//----------------------------------------------//
/*******************************
串口通信
MCU:89C52RC 11.0592MHz
//11.0592MHz 0xd0 1200bps
//12MHz 0xcc 1200bps
//11.0592MHz 0xfa 9600bps
//0xf4 11.0592MHz 0xf3 12MHz 4800bps
//均在SMOD=1的情況下(波特率倍增模式)
*******************************/
//串口發送函數
void PutString(unsigned char *TXStr)
{
ES=0;
while(*TXStr!=0)
{
SBUF=*TXStr;
while(TI==0);
TI=0;
TXStr++;
}
ES=1;
}
//串口接收函數
bit ReceiveString()
{
char * RecStr=buf_string;
char num=0;
unsigned char count=0;
loop:
*RecStr=SBUF;
count=0;
RI=0;
if(num《14) //數據包長度為15個字符,嚐試連續接收15個字符
{
num++;
RecStr++;
while(!RI)
{
count++;
if(count》130)return 0; //接收數據等待延遲,等待時間太久會導致CPU運算閑置,太短會出現“數據包被分割”,默認count=130
}
goto loop;
}
return 1;
}
//定時器1用作波特率發生器
void Init_USART()
{
SCON=0x50; //串口方式1,使能接收
TMOD|=0x20; //定時器1工作方式2(8位自動重裝初值)
TMOD&=~0x10;
TH1=0xfa; //9600bps
TL1=0xfa;
PCON|=0x80; //SMOD=1
TR1=1;
TI=0;
RI=0;
//PS=1; //提高串口中斷優先級
ES=1; //開啟串口中斷使能
}
//比較指令頭部
bit CompareCMD_head(char CMD_head[])
{
unsigned char CharNum;
for(CharNum=0;CharNum《4;CharNum++) //指令長度為10個字符
{
if(!(buf_string[CharNum+4]==CMD_head[CharNum]))
{
return 0; //指令頭部匹配失敗
}
}
return 1; //指令頭部匹配成功
}
//比較指令尾部(start:從哪裏開始比較,quality:比較多少個字符,CMD_tail[]:要比較的字符串)
bit CompareCMD_tail(unsigned char start,unsigned char quality,char CMD_tail[])
{
unsigned char CharNum;
for(CharNum=0;CharNum《quality;CharNum++)
{
if(!(buf_string[start+CharNum]==CMD_tail[CharNum]))
{
return 0;
}
}
return 1;
}
bit Deal_UART_RecData() //處理串口接收數據包函數(成功處理數據包則返回1,否則返回0)
{
//PutString(buf_string);
if(buf_string[0]==datapackage_headflag&&buf_string[14]==‘#’) //進行數據包頭尾標記驗證
{
switch(buf_string[1]) //識別發送者設備ID的第1位數字
{
case ‘0’:
switch(buf_string[2]) //識別發送者設備ID的第2位數字
{
case ‘3’:
if(CompareCMD_head(“Ligt”)) //判斷指令頭部是否為“Ligt”
{
//下麵是指令尾部分析
switch(buf_string[8])
{
case ‘0’:
switch(buf_string[9])
{
case ‘0’:
return 0;
case ‘1’:
if(CompareCMD_tail(10,3,“Off”)) //A03_Ligt01Off_#
{
//要執行的代碼
return 1;
}
if(CompareCMD_tail(10,3,“On_”))
{
return 1;
}
return 0;
default:
return 0;
}
case ‘1’:
default:
return 0;
}
}
if(CompareCMD_head(“SenT”))
{
}
if(CompareCMD_head(“jdq_”))
{
}
if(CompareCMD_head(“Try!”))
{
}
return 0;
default:
return 0;
}
default:
return 0;
}
}
return 0;
}
/************************
中斷函數
************************/
//串口中斷服務函數-----------
void USART() interrupt 4 //標誌位TI和RI需要手動複位,TI和RI置位共用一個中斷入口
{
if(ReceiveString())
{
//數據包長度正確則執行以下代碼
Deal_UART_RecData();
}
else
{
//數據包長度錯誤則執行以下代碼
//LED1=~LED1;
}
RI=0; //接收並處理一次數據後把接收中斷標誌清除一下,拒絕響應在中斷接收忙的時候發來的請求
}
/***************************
主函數
***************************/
void main()
{
EA=1;
Init_USART();
while(1)
{
//PutString(buf_string);//空格20H,回車0DH
}
}
特別推薦
- 噪聲中提取真值!瑞盟科技推出MSA2240電流檢測芯片賦能多元高端測量場景
- 10MHz高頻運行!氮矽科技發布集成驅動GaN芯片,助力電源能效再攀新高
- 失真度僅0.002%!力芯微推出超低內阻、超低失真4PST模擬開關
- 一“芯”雙電!聖邦微電子發布雙輸出電源芯片,簡化AFE與音頻設計
- 一機適配萬端:金升陽推出1200W可編程電源,賦能高端裝備製造
技術文章更多>>
- 築基AI4S:摩爾線程全功能GPU加速中國生命科學自主生態
- 一秒檢測,成本降至萬分之一,光引科技把幾十萬的台式光譜儀“搬”到了手腕上
- AI服務器電源機櫃Power Rack HVDC MW級測試方案
- 突破工藝邊界,奎芯科技LPDDR5X IP矽驗證通過,速率達9600Mbps
- 通過直接、準確、自動測量超低範圍的氯殘留來推動反滲透膜保護
技術白皮書下載更多>>
- 車規與基於V2X的車輛協同主動避撞技術展望
- 數字隔離助力新能源汽車安全隔離的新挑戰
- 汽車模塊拋負載的解決方案
- 車用連接器的安全創新應用
- Melexis Actuators Business Unit
- Position / Current Sensors - Triaxis Hall
熱門搜索
微波功率管
微波開關
微波連接器
微波器件
微波三極管
微波振蕩器
微電機
微調電容
微動開關
微蜂窩
位置傳感器
溫度保險絲
溫度傳感器
溫控開關
溫控可控矽
聞泰
穩壓電源
穩壓二極管
穩壓管
無焊端子
無線充電
無線監控
無源濾波器
五金工具
物聯網
顯示模塊
顯微鏡結構
線圈
線繞電位器
線繞電阻


