詳細解析串口通信的原理及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,這樣就有3geluojigaowei。gaoweihediweibuzhenzhengdejianzhashuju,jiandanzhiweiluojigaohuozheluojidixiaoyan。zheyangshidejieshoushebeinenggouzhidaoyigeweidezhuangtai,youjihuipanduanshifouyouzaoshengganraoletongxinhuozheshifouchuanshuhejieshoushujushifoubutongbu。
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
熱門搜索





