方淼榮++錢光明
摘要:將一個(gè)模塊(如串口攝像頭)與STM32單片機(jī)通過(guò)接口相連時(shí),一個(gè)重要程序調(diào)試手段是:經(jīng)單片機(jī)向模塊發(fā)一系列的命令,然后檢查模塊產(chǎn)生的有關(guān)應(yīng)答信息。該文以“WIFI圖片自動(dòng)拍攝和網(wǎng)絡(luò)傳送”這一設(shè)計(jì)實(shí)踐為例,介紹了三個(gè)與串口有關(guān)的調(diào)試技巧:在中斷服務(wù)子程序中實(shí)現(xiàn)應(yīng)答信息的即收即發(fā)、設(shè)置轉(zhuǎn)發(fā)緩沖區(qū)實(shí)現(xiàn)應(yīng)答信息的先存后發(fā)、以及用延時(shí)來(lái)暫代應(yīng)答信息的正確性判斷。實(shí)驗(yàn)效果證明了這三個(gè)技巧簡(jiǎn)單、實(shí)用和有效。
關(guān)鍵詞:串口;模塊;應(yīng)答信息;轉(zhuǎn)發(fā)緩沖區(qū)
中圖分類號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2016)06-0234-02
1 引言
STM32單片機(jī)串口眾多,如USART1~USART5[1]。這些串口不但方便了我們進(jìn)行產(chǎn)品設(shè)計(jì),而且非常有利于程序調(diào)試。因?yàn)榭梢阅贸鲆粋€(gè)或幾個(gè)串口連接(或通過(guò)USB轉(zhuǎn)串口連接)PC機(jī),顯示程序調(diào)試中的重要信息,這樣的串口下稱調(diào)試用串口。
利用串口來(lái)調(diào)試,利用串口來(lái)接模塊。我們將USART1作調(diào)試用串口,USART2串口接WIFI模塊Gainspan GS1011,USART3串口接攝像頭模塊PTC08,完成基于WIFI的圖片自動(dòng)拍攝和網(wǎng)絡(luò)傳送[2] [3]。無(wú)論對(duì)哪一個(gè)模塊,都需要一系列的命令才能完成有關(guān)操作,模塊對(duì)每一個(gè)命令一般都有相應(yīng)的應(yīng)答信息。應(yīng)答信息反映命令的執(zhí)行情況,決定程序下一步的走向。因此,應(yīng)答信息無(wú)疑是調(diào)試過(guò)程中非常重要的信息。實(shí)驗(yàn)中為了快速、初步地傳出圖像,基于應(yīng)答信息,我們采用了以下幾個(gè)簡(jiǎn)單實(shí)用的調(diào)試技巧。
2 在中斷服務(wù)子程序中轉(zhuǎn)發(fā)——應(yīng)答信息即收即發(fā)
無(wú)論是單獨(dú)調(diào)試接串口的攝像頭,還是WIFI模塊,當(dāng)速率高至115200時(shí),這一方法均比較有效。實(shí)驗(yàn)機(jī)型為STM32F103RC,系統(tǒng)時(shí)鐘72MHz,256kB Flash,48kB SRAM。以攝像頭調(diào)試為例說(shuō)明之,圖1是連接示意。
圖中攝像頭接收單片機(jī)發(fā)來(lái)的指令(可以是單片機(jī)程序發(fā)出的也可是PC機(jī)發(fā)來(lái)的),然后依據(jù)指令向單片機(jī)應(yīng)答信息,這些應(yīng)答信息由USART1發(fā)向PC機(jī)顯示。對(duì)于這兩個(gè)串口而言,發(fā)送數(shù)據(jù)時(shí)均采用查詢方式,接收數(shù)據(jù)時(shí)均以中斷方式進(jìn)行。圖2是發(fā)送數(shù)據(jù)流程(以USART1為例),圖3是接收數(shù)據(jù)中斷服務(wù)子程序流程(以USART2為例)。
圖2中的TC意為“發(fā)送完成”。每次要發(fā)送數(shù)據(jù)之前,檢查一下上次是否發(fā)完,如果已發(fā)完,TC就為“1”,即可發(fā)送一新的字節(jié)?!跋葯z查TC后發(fā)字節(jié)”的操作會(huì)使TC清“0”。
圖3中的RXNE意為“接收非空”。一旦有數(shù)據(jù)到來(lái),RXNE將為“1”,系統(tǒng)運(yùn)行進(jìn)入該中斷服務(wù)子程序,通過(guò)該子程序讀入一個(gè)字節(jié)。流程中判斷USART2的RXNE是否為“1”,可理解為如果是別的原因進(jìn)入中斷的話,需另作處理?!敖邮找粋€(gè)字節(jié)”這一讀操作使RXNE清“0”。
現(xiàn)在再看圖1??赏ㄟ^(guò)圖2的方式向攝像頭發(fā)命令,那么,怎樣將攝像頭的應(yīng)答信息快速及時(shí)地顯示到PC機(jī)呢?只要在圖3的“接收一個(gè)字節(jié)”程序框后,將圖2所示的程序段加進(jìn)去即可。這樣就實(shí)現(xiàn)了:攝像頭如果有應(yīng)答信息發(fā)到STM32單片機(jī)的USART2口,單片機(jī)馬上被中斷,進(jìn)入中斷服務(wù)子程序,該子程序讀入應(yīng)答信息,隨即轉(zhuǎn)到單片機(jī)的USART1口,由USART1發(fā)到PC機(jī)上顯示。非常有利于程序調(diào)試。
3 設(shè)置轉(zhuǎn)發(fā)緩沖區(qū)——先緩存應(yīng)答信息
實(shí)時(shí)編程的一個(gè)主要原則是中斷服務(wù)子程序的執(zhí)行過(guò)程應(yīng)盡量短而快,單獨(dú)調(diào)試PTC08攝像頭時(shí),圖1中的單片機(jī)沒(méi)接別的東西,上述“用中斷服務(wù)子程序轉(zhuǎn)發(fā)數(shù)據(jù)”的方法很有效。但是,如果系統(tǒng)并不像圖1那么簡(jiǎn)單,如還接了WIFI模塊等裝置,或是開(kāi)啟了別的中斷,那么,系統(tǒng)實(shí)時(shí)性肯定會(huì)受影響,或造成某些數(shù)據(jù)丟失。此時(shí),可以考慮中斷服務(wù)子程序保持如圖3所示不變,而設(shè)置緩沖區(qū)來(lái)進(jìn)行數(shù)據(jù)轉(zhuǎn)發(fā)。這樣的緩沖區(qū)稱為轉(zhuǎn)發(fā)緩沖區(qū)。
仍以圖1、圖2和圖3為例,所謂設(shè)置轉(zhuǎn)發(fā)緩沖區(qū),就是在接收數(shù)據(jù)中斷服務(wù)子程序中,只將攝像頭通過(guò)USART2發(fā)給STM32單片機(jī)的應(yīng)答信息先緩存起來(lái),隨即退出該子程序,以后在適當(dāng)?shù)臅r(shí)候再通過(guò)USART1發(fā)向PC機(jī)顯示。這一緩沖區(qū)采用循環(huán)結(jié)構(gòu),即如果放滿了,再?gòu)念^開(kāi)始,那么,新數(shù)據(jù)會(huì)把老數(shù)據(jù)覆蓋掉。緩沖區(qū)會(huì)耗費(fèi)寶貴的內(nèi)存,但如果設(shè)得太小,丟失的信息會(huì)過(guò)多。對(duì)于程序的調(diào)試信息,顯示稍微慢一點(diǎn)也沒(méi)關(guān)系。攝像頭的應(yīng)答信息,個(gè)別的沒(méi)有顯示出來(lái),但關(guān)鍵信息顯示成功的話,也是可以接受的。如PTC08初始化時(shí),應(yīng)答信息除了“0x76 0x00 0x26 0x00”外還有一些版本信息,只要前者能正確在PC機(jī)上顯示,我們就基本認(rèn)為初始化是成功的,版本信息在送往PC機(jī)的過(guò)程中丟了一些關(guān)系也不大。
實(shí)驗(yàn)中采用過(guò)256~1024字節(jié)的轉(zhuǎn)發(fā)緩沖區(qū)。下面以256字節(jié)為例來(lái)加以說(shuō)明:
定義作為轉(zhuǎn)發(fā)緩沖區(qū)的數(shù)組R2Buff[256];
設(shè)一個(gè)循環(huán)計(jì)數(shù)變量R2num,用于指示R2Buff[ ]接收的字節(jié)數(shù);
設(shè)一個(gè)指針TRpointer1,用于指示USART1發(fā)向PC機(jī)的字節(jié)數(shù)。
在USART2的接收數(shù)據(jù)中斷服務(wù)子程序中,接收的字節(jié)存入R2Buff[ ],每存一個(gè),R2num加1,加到256時(shí)R2num清“0”。
主程序在適當(dāng)?shù)臅r(shí)候安排向PC機(jī)轉(zhuǎn)發(fā)數(shù)據(jù)的指令,每轉(zhuǎn)發(fā)一個(gè),TRpointer1加1,加到256時(shí)TRpointer1清“0”。
圖4是轉(zhuǎn)發(fā)緩沖區(qū)及其指示變量示意圖。初始化時(shí)TRpointer1和R2num均指向R2Buff[0]。如果TRpointer1小于R2num,說(shuō)明有新數(shù)據(jù)要發(fā)送;如果TRpointer1等于R2num,看作沒(méi)有新數(shù)據(jù),無(wú)需發(fā)送。如果R2num的值從小到大趕上了TRpointer1,說(shuō)明發(fā)送慢了,丟失了部分該顯示的應(yīng)答信息。
4 簡(jiǎn)化應(yīng)答信息的正確性判斷——用延時(shí)來(lái)暫代
為了方便連接和編程,USART串口是很多功能模塊配備的接口之一,如上面談到的Gainspan GS1011和PTC08模塊。為了完成某類操作(下面以拍一張JPG照片為例),STM32單片機(jī)往往需要向這樣的一個(gè)模塊發(fā)幾個(gè)命令,對(duì)應(yīng)每一個(gè)命令,模塊一般都有一串應(yīng)答信息。較正規(guī)的編程方式是:向模塊發(fā)一個(gè)命令,等待模塊對(duì)該命令的應(yīng)答,判斷該應(yīng)答信息是否正確,如果正確的話可繼續(xù)發(fā)下一命令,……直至完成該類操作(如讀到一張完整的JPG圖片)。
調(diào)試過(guò)程中,為了快速得到結(jié)果,有時(shí)沒(méi)有必要對(duì)每一個(gè)命令的應(yīng)答信息做出正確與否的判斷,直接用延時(shí)子程序延時(shí)一定時(shí)間即可,因而可節(jié)省部分編程時(shí)間。因?yàn)橐话隳K產(chǎn)品都已經(jīng)過(guò)較完備的設(shè)計(jì),應(yīng)答信息一般都是正確的,所以在調(diào)試階段,這樣用“延時(shí)”暫時(shí)代替“應(yīng)答信息的判斷”往往簡(jiǎn)單而可行。
例如,發(fā)往PTC08的拍照命令是“0x56 0x00 0x36 0x01 0x00”,PTC08返回的應(yīng)答信息是“0x76 0x00 0x36 0x00 0x00”,如果正確收到了這樣的應(yīng)答信息,便可接著發(fā)下一個(gè)命令—“讀圖片長(zhǎng)度”。調(diào)試中我們暫不去編程判斷這一串應(yīng)答信息,而是在發(fā)出拍照命令后,簡(jiǎn)單地延時(shí)0.5秒,也收到了滿意的效果,后續(xù)命令均得以正確執(zhí)行,可以完整收到JPG照片。當(dāng)然,這種方法在最終設(shè)計(jì)中最好不用。延時(shí)短了模塊沒(méi)準(zhǔn)備好導(dǎo)致無(wú)法繼續(xù)下去,延時(shí)長(zhǎng)了將影響響應(yīng)速度。另外,模塊發(fā)出應(yīng)答信息的時(shí)間隨自身的狀態(tài)也可能會(huì)有所改變。不過(guò),調(diào)試過(guò)程中這仍然是一個(gè)好的手段。
5 結(jié)束語(yǔ)
STM32單片機(jī)提供了許多串口,方便了產(chǎn)品開(kāi)發(fā)的同時(shí),調(diào)試過(guò)程也可極大地受益。用別的接口連接模塊時(shí),采用類似的思路應(yīng)該也是可以的。不過(guò),一般最好還是通過(guò)串口(或USB轉(zhuǎn)串口)連接PC機(jī)來(lái)顯示應(yīng)答信息。如果直接用STM32單片機(jī)的USB接口與PC機(jī)的USB接口相連,程序結(jié)構(gòu)將復(fù)雜許多。
參考文獻(xiàn):
[1] RM0008: STM32F101xx, STM32F102xx、STM32F103xx、STM32F105xx 和STM32F107xx,ARM內(nèi)核32位高性能微控制器. http://www.st.com/
[2] GainSpan. GS1011M_Datasheet_rev_1_6. 2013.
[3] PTC08 串口攝像頭使用說(shuō)明書. 譜泰通信科技,Revision 1.06. 2012. http://www.putal.com.cn/.