STM32串口通信程序模拟超市打印机工作-使用接收中断、空闲中断、校验中断
項(xiàng)目代碼資料請移步:https://download.csdn.net/download/lishan132/12420086
Gitee 項(xiàng)目資料? ??https://gitee.com/lishan666/Usart
1 項(xiàng)目簡介
? ? ? ? 超市的收銀臺一般都會放置一臺小型打印機(jī),其任務(wù)是將顧客的消費(fèi)金額等信息打印在一張小票上。那么打印機(jī)又是如何知道自己該打印那些內(nèi)容呢?本文以經(jīng)典的RS232串口通信來模擬收銀臺電腦與打印機(jī)之間的通信工作流程。
????值得一提的是,超市收銀臺電腦與打印機(jī)之間的通信方式不止RS232串口一種,常見的還有USB通信、LPT并口通信、WiFi通信等方式。它們本質(zhì)上都是一種數(shù)據(jù)傳輸手段,只不過其工作方式、成本、實(shí)現(xiàn)復(fù)雜度等有所區(qū)別。
? ? ? ?為了將所學(xué)的串口通信知識與實(shí)踐相結(jié)合,現(xiàn)在通過開發(fā)一個實(shí)際的項(xiàng)目來掌握串口通信的核心要點(diǎn)及開發(fā)流程,實(shí)現(xiàn)由理論知識到實(shí)際應(yīng)用的轉(zhuǎn)變,本文對超市微型打印機(jī)的通信部分進(jìn)行研究設(shè)計(jì)。設(shè)計(jì)目標(biāo)是:
(1)搭建電腦到打印機(jī)之間的RS232串口通信電路;
(2)設(shè)計(jì)串口通信程序,程序運(yùn)行在打印機(jī)控制器STM32F103C8T6中;
(3)通過串口調(diào)試助手對通信效果進(jìn)行演示。
2 設(shè)計(jì)要求
基礎(chǔ)部分
串口通信的具體設(shè)計(jì)要求如下:
(1)波特率4800bps,一位起始位,八位有效數(shù)據(jù)位,一位奇偶校驗(yàn)位;
(2)使用串口調(diào)試助手發(fā)送一個數(shù)據(jù)打印命令“@PrintData12345678900#”;
(3)單片機(jī)收到命令后,解析命令,輸出數(shù)據(jù)“1234567890”,然后給上位機(jī)發(fā)送“數(shù)據(jù)已成功打印”。
擴(kuò)展部分
為了加深對串口通信知識的理解和運(yùn)用,本文提出以下擴(kuò)展要求并進(jìn)行實(shí)現(xiàn):
(1)每次輸出打印信息及提示信息結(jié)束后都進(jìn)行換行顯示;
(2)系統(tǒng)上電工作時,通過串口通信助手顯示系統(tǒng)正常工作的提示信息;
(3)當(dāng)打印指令錯誤時,輸出“instruction error”進(jìn)行提示;
(4)當(dāng)接收的字符數(shù)大于設(shè)定的緩沖區(qū)大小時,輸出“Overflow error”;
(5)當(dāng)出現(xiàn)校驗(yàn)錯誤時,輸出“校驗(yàn)錯誤,請重新發(fā)送命令”。
3 總體設(shè)計(jì)方案
? ? ? ?使用筆記本電腦與STM32單片機(jī)進(jìn)行數(shù)據(jù)交互,模擬超市電腦與打印機(jī)之間的通信過程。筆記本電腦上安裝有串口調(diào)試助手軟件,串口調(diào)試助手作為上位機(jī)可以實(shí)現(xiàn)人機(jī)界面交互的功能,同時也是檢驗(yàn)串口通信是否正常的工具。
? ? ? 筆記本電腦一般沒有串口,但至少有一個USB口。單片機(jī)的串口是映射到GPIO上的,本文只需要用到接收、發(fā)送引腳,也就是2個GPIO,再加上電源和地,一共4個單片機(jī)引腳。筆記本的USB口和單片機(jī)串口之間不能直接相連,因?yàn)閮烧叩墓ぷ麟娖竭壿嫴灰恢?#xff0c;需要通過一個USB轉(zhuǎn)TTL模塊進(jìn)行電平轉(zhuǎn)換,同時筆記本電腦上需要安裝配套的USB轉(zhuǎn)串口驅(qū)動程序。
?
系統(tǒng)設(shè)計(jì)方案4 設(shè)計(jì)前的思考和準(zhǔn)備
思考:
1、串口的參數(shù)設(shè)置中有一位校驗(yàn)位,如何實(shí)現(xiàn),又如何體現(xiàn)校驗(yàn)的作用;
2、如何判斷串口數(shù)據(jù)傳輸?shù)拈_始、結(jié)束;
3、如何判斷命令是否符合要求,并取出中間的數(shù)據(jù)部分;
4、能否直接輸出中文。
準(zhǔn)備:
? ? ? ? 在開發(fā)過程中,本文還連接了ST-Link調(diào)試器,使用調(diào)試器可以讓程序下載更快,同時能進(jìn)行硬件仿真調(diào)試,可以提高開發(fā)效率,當(dāng)然也可以直接使用串口下載程序。項(xiàng)目完成后,實(shí)際運(yùn)行時不需要再連接調(diào)試器。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
硬件連接? ? ? 2.安裝USB轉(zhuǎn)串口驅(qū)動程序
? ? ? ? 本文用到的USB轉(zhuǎn)TTL模塊芯片為PL2303HX,驅(qū)動程序可在網(wǎng)上進(jìn)行下載,雙擊驅(qū)動程序按提示完成驅(qū)動安裝。其他芯片的驅(qū)動安裝方法類似。
安裝USB轉(zhuǎn)串口驅(qū)動? ? ? ? 驅(qū)動安裝完成后,插上USB轉(zhuǎn)TTL模塊,在設(shè)備管理器中選擇端口,如果能夠看到識別到的驅(qū)動程序和端口號,表示驅(qū)動安裝成功。否則,右鍵選擇更新驅(qū)動程序,從我的計(jì)算機(jī)驅(qū)動程序中選擇2009年的版本,當(dāng)出現(xiàn)下圖界面,能分配到一個端口號即表示安裝成功。其它的芯片模塊可能在驅(qū)動程序安裝完后就能看到端口號,此時不需要進(jìn)行驅(qū)動程序的更新操作。
驅(qū)動安裝成功示意圖? ? ?3.下載串口調(diào)試助手軟件、Keil-MDk軟件
? ? ? 串口調(diào)試助手網(wǎng)上非常多,可以自行選擇,但是要注意,一定要知道這款串口助手對中文字符的編碼采用什么格式,網(wǎng)上資源以GB2313居多,也有部分是采用UTF-8格式的,本文選擇GB2313編碼方式的串口調(diào)試助手。
? ? ? Keil-MDK軟件是開發(fā)嵌入式的IDE,可從網(wǎng)上下載,建議下載5.28版本,破解操作也可從網(wǎng)上參考,本文不贅述。Keil-MDK編程的編碼格式設(shè)置一定要與串口調(diào)試助手一致,這樣才不會出現(xiàn)中文亂碼的問題,建議選擇GB2313。
MDK-keil編碼設(shè)置? ??4.準(zhǔn)備一份STM32中文參考手冊,便于開發(fā)過程中查詢串口的使用方法以及相關(guān)寄存器的設(shè)置。
? ? 5.準(zhǔn)備一份STM32固件庫手冊,便于開發(fā)程序時查詢標(biāo)準(zhǔn)固件庫函數(shù)使用方法,加快開發(fā)效率。
? ? 6.找到一份STM32工程模板文件,可以直接從固件庫文件中復(fù)制,也可以自己創(chuàng)建,省去工程的創(chuàng)建、文件的添加等機(jī)械工作。
準(zhǔn)備資料5 本文設(shè)計(jì)的關(guān)鍵點(diǎn)
5.1 校驗(yàn)位設(shè)置
通過查閱STM32中文手冊發(fā)現(xiàn),USART_CR1寄存器中的PCE位可以使能奇偶校驗(yàn)位的產(chǎn)生,M位可以設(shè)置數(shù)據(jù)字的長度,如下圖所示:
?
USART_CR1寄存器PCE位-決定是否產(chǎn)生校驗(yàn)位 USART_CR1寄存器M位-決定數(shù)據(jù)字長度? ? ? ?M位和PCE位的值兩者共同決定USART幀的格式,一共四種,如下圖所示。根據(jù)設(shè)計(jì)要求,本文設(shè)置為M位為1,PCE位為1,即字長為9,校驗(yàn)位選擇奇校驗(yàn)(也可選擇偶校驗(yàn))。
?
校驗(yàn)控制串口幀格式? ? ? ? 通過查閱STM32固件庫手冊,復(fù)制串口參數(shù)設(shè)置代碼示例,并進(jìn)行修改,下面展示關(guān)鍵部分的參數(shù)設(shè)置。
?
串口初始化參數(shù)設(shè)置5.2 串口中斷設(shè)置
? ? ? 串口通信的數(shù)據(jù)接收、發(fā)送程序一般有中斷和查詢(也叫輪詢)兩種方式,相對來說,中斷方式對CUP的資源占用較少,響應(yīng)也更及時,本文使用中斷方式接收來自上位機(jī)電腦的數(shù)據(jù)。
? ? ? 翻閱STM32中文手冊發(fā)現(xiàn),STM32單片機(jī)的串口中斷請求事件有以下幾種,當(dāng)表中事件發(fā)生時,只要設(shè)置了相應(yīng)的中斷使能,都會通過嵌套中斷向量(NVIC)的向量表進(jìn)入到串口中斷服務(wù)程序中,可以在服務(wù)程序中查詢相應(yīng)事件的標(biāo)志位判斷當(dāng)前是那一種事件發(fā)生。為了檢測數(shù)據(jù)的接收、接收完成、奇偶校驗(yàn)出錯這三種情況,本文設(shè)置的三個串口中斷事件,下圖中用紅框標(biāo)注。
①接收數(shù)據(jù)就緒可讀表示對方已經(jīng)發(fā)送了一個字節(jié)數(shù)據(jù),這個數(shù)據(jù)現(xiàn)在在硬件接收緩沖區(qū)中,并且現(xiàn)在可以讀出數(shù)據(jù)。當(dāng)?shù)谝淮伟l(fā)生此事件時代表數(shù)據(jù)傳輸?shù)拈_始。
②檢測到空閑線路表示在對方傳輸上一字節(jié)數(shù)據(jù)后,又過了一個字節(jié)的傳輸時長,單片機(jī)仍然沒有接收到數(shù)據(jù),可以代表數(shù)據(jù)發(fā)送的結(jié)束,也就是完成了一次數(shù)據(jù)的傳輸。
③奇偶校驗(yàn)錯表示按照約定的校驗(yàn)規(guī)則,當(dāng)前字節(jié)的數(shù)據(jù)發(fā)生了錯誤。
STM32串口中斷事件 (注:表中的TXNE標(biāo)志應(yīng)為RXNE)?
根據(jù)固件庫手冊和庫函數(shù)注釋,使能上述三個串口中斷事件的代碼如下:
使能串口中斷事件?
5.3 串口中斷服務(wù)程序
? ? ? ? 根據(jù)STM32中文手冊,串口中斷事件相應(yīng)的標(biāo)志位在狀態(tài)寄存器SR中,在串口中斷服務(wù)程序中查詢這幾個標(biāo)志位的值就可知道發(fā)生了什么事件。SR寄存器中的三個標(biāo)志位介紹如下所示:
?
串口中斷標(biāo)志位及清除方法? ? ? ? 從上表看出,標(biāo)志位置1時,表示該事件發(fā)送,此時單片機(jī)可以進(jìn)行相應(yīng)操作。但要注意,一定要及時清除標(biāo)志位(清0操作),否則程序會一直進(jìn)入中斷服務(wù)程序。對于RXNE位,當(dāng)讀出DR寄存器中的數(shù)據(jù)后,硬件自動清0,不用再單獨(dú)寫清0的代碼。對于PE位和IDLE為,需由軟件進(jìn)行清0,清0操作為先讀SR寄存器,再讀DR寄存器。串口1軟件清除PE、IDLE標(biāo)志位代碼為:
USART1->SR; ?//先讀狀態(tài)寄存器
USART1->DR; ?//再讀數(shù)據(jù)寄存器
? ? ? ? ?串口1的中斷服務(wù)程序名為void USART1_IRQHandler(void),位于stm32f10x_it.c文件中,當(dāng)然,也可以寫在其他位置,但程序名不要改變,同時要處理好各c文件之間依賴關(guān)系。
串口中斷服務(wù)程序?
6 程序設(shè)計(jì)
在本文的程序設(shè)計(jì)中,要注意以下幾個要點(diǎn)。
整個程序有四個關(guān)鍵部分,分別是主函數(shù)、串口中斷處理、數(shù)據(jù)解析、串口輸出,下面分別對它們的流程做簡單介紹。串口輸出和數(shù)據(jù)解析函數(shù)放在附錄中。
6.1 主函數(shù)
主函數(shù)流程圖?
主函數(shù)程序展示圖?
6.2 串口中斷處理函數(shù)
串口中斷處理函數(shù)流程圖?
接收中斷回調(diào)函數(shù)?
空閑中斷回調(diào)函數(shù)?
校驗(yàn)出錯中斷回調(diào)函數(shù)6.3 數(shù)據(jù)解析函數(shù)
數(shù)據(jù)解析函數(shù)流程6.4 串口輸出函數(shù)
?
串口輸出函數(shù)流程7 結(jié)果演示
? ? ?打開串口調(diào)試助手,設(shè)置好串口參數(shù),按各種情況進(jìn)行測試,演示效果如下
演示效果圖?
8?課堂問題解答
?
第19組第一個問題:開始和結(jié)束錯誤標(biāo)志都設(shè)置為2會不會分不清?
答:因?yàn)橹噶畹拈_始和結(jié)束部分出現(xiàn)錯誤時都表示這是一個錯誤的指令,所以程序中將其錯誤類型都設(shè)置為2,這樣做確實(shí)是無法分清到底是指令的開始部分發(fā)生了錯誤還是結(jié)束部分發(fā)送錯誤。如果確實(shí)有必要將這兩種錯誤分開,可以考慮在程序中將這兩種情況設(shè)置不同的錯誤標(biāo)志號。
?
第12組第一個問題:為啥選奇校驗(yàn)和偶校驗(yàn)?zāi)膫€都對?
答:尚不清楚您說的對是什么意思,但是不管在串口助手中選哪一種校驗(yàn)方式,發(fā)送指令后單片機(jī)都會返回一段信息,可能是成功打印的信息,也可能是錯誤的提示信息。在演示中出現(xiàn)了一個細(xì)節(jié)可能與您的提問相關(guān),因?yàn)楫?dāng)時發(fā)送的是一個錯誤的指令,所以不管選擇奇校驗(yàn)還是偶校驗(yàn)方式,單片機(jī)返回的信息都是“instruction error”,這是由于程序中必須對數(shù)據(jù)進(jìn)行解析,當(dāng)解析結(jié)果為指令錯誤時,其錯誤碼為2,也就是輸出“instruction error”。換句話說,當(dāng)出現(xiàn)多種錯誤時,優(yōu)先考慮指令是否錯誤。當(dāng)發(fā)送一個正確的指令時,在串口助手中選擇與程序設(shè)計(jì)中不同的校驗(yàn)方式,就會輸出“校驗(yàn)錯誤,請重新發(fā)送命令”。
?
第2組第一個問題:自己設(shè)定的三個中斷有優(yōu)先級的考慮嗎?
答:程序中設(shè)置有接收中斷、空閑中斷、奇偶校驗(yàn)出錯中斷,但這三個中斷本質(zhì)上都屬于串口中斷,只不過這是引起串口中斷的三種不同事件,當(dāng)任意一件事件發(fā)生時,都會進(jìn)入同一個串口中斷服務(wù)函數(shù),可以在中斷服務(wù)函數(shù)中判斷對應(yīng)的標(biāo)志位是否置1,進(jìn)而確定是哪一個事件的發(fā)生導(dǎo)致進(jìn)入了串口中斷服務(wù)函數(shù)。因?yàn)椴豢赡苡袃蓚€及以上的事件同時發(fā)生,所以這三個中斷事件之間不存在優(yōu)先級的問題。另外,因?yàn)檎麄€程序只用到了一個串口中斷,不存在其它外設(shè)中斷源,所以也可以不用對中斷優(yōu)先級進(jìn)行設(shè)置。
?
第5組第一個問題:可以詳細(xì)講解一下中斷的過程嗎,比如各個中斷的優(yōu)先級,以及如果在主函數(shù)解析時中斷關(guān)閉的方式等
答:一個外設(shè)(比如定時器、串口)要發(fā)生中斷有三個條件,一是使能了外設(shè),可類比為電路中的干路總開關(guān);二是打開了中斷使能位,可類比為支路的第一個開關(guān)(有多種事件可觸發(fā)串口中斷,可看成是多條支路);三是對應(yīng)事件的中斷標(biāo)志位置1(一般是硬件自動置1),可類比為支路第二個開關(guān),只有三個開關(guān)全部合上,才會進(jìn)入中斷服務(wù)函數(shù)。
當(dāng)發(fā)生中斷時,程序會保存當(dāng)前的數(shù)據(jù)和指令執(zhí)行位置等信息到堆棧,稱為現(xiàn)場保護(hù)。這個堆??臻g是硬件自動開辟的,數(shù)據(jù)的保存也是自動完成的,不需要在程序中再進(jìn)行任何操作。保存完畢后,程序會查詢中斷向量表,向量表上保存的是各個中斷的服務(wù)程序的起始地址,通過此地址可跳轉(zhuǎn)到中斷服務(wù)中執(zhí)行中斷服務(wù)體內(nèi)的程序,當(dāng)離開中斷服務(wù)程序時,程序會從堆棧中彈出數(shù)據(jù),返回到進(jìn)入中斷前的指令位置,繼續(xù)執(zhí)行當(dāng)前程序。
中斷的優(yōu)先級一般指的是不同中斷源之間的優(yōu)先級別高低,比如程序中存在定時器中斷和串口中斷,那么這兩個中斷可能會同時觸發(fā),或者正在串口中斷服務(wù)程序中執(zhí)行時,定時器中斷又被觸發(fā)。當(dāng)發(fā)生這些情況時,如果沒有相應(yīng)的處理機(jī)制,系統(tǒng)將會陷入混亂。由此引入的中斷優(yōu)先級的概念,即將每個中斷源都設(shè)置一個優(yōu)先級別,這樣,遇到上述情況時,就可以根據(jù)優(yōu)先級的高低來決定當(dāng)前去處理那一部分的程序。如果優(yōu)先級一樣,或者在程序中沒有設(shè)置中斷優(yōu)先級,那么系統(tǒng)會根據(jù)向量表中默認(rèn)的優(yōu)先級進(jìn)行處理。
STM32中文手冊中的第9章可以查看中斷的相關(guān)信息,串口1中斷的默認(rèn)優(yōu)先級為44。
? ? ? ?STM32通過4位數(shù)據(jù)對優(yōu)先級進(jìn)行編程設(shè)置,在程序中設(shè)置中斷優(yōu)先級時,有優(yōu)先級分組、搶占優(yōu)先級和響應(yīng)優(yōu)先級三個參數(shù)設(shè)置,系統(tǒng)復(fù)位后默認(rèn)的中斷優(yōu)先級優(yōu)先級分組設(shè)置為0,即全部用于響應(yīng)優(yōu)先級,不存在搶占優(yōu)先級。詳情見STM32固件庫手冊,本文不再贅述。在本文程序的主函數(shù)中解析數(shù)據(jù)時,如果要關(guān)閉中斷,只需要關(guān)閉上面提到的三個開關(guān)中任意一個即可,最簡單的就是直接失能串口外設(shè),其代碼為:
USART_Cmd(USART1, DISABLE); ???/* 失能USART1 */當(dāng)輸出數(shù)據(jù)后,可以再次開啟串口,進(jìn)行下一次的接收。
第9組第一個問題:如何編寫中斷服務(wù)函數(shù)
答:進(jìn)入中斷服務(wù)函數(shù)后,首先是對標(biāo)志位進(jìn)行判斷,確認(rèn)中斷事件,然后是標(biāo)志位的清除,避免一直進(jìn)入中斷服務(wù)函數(shù)。接下來有兩種思路,一是將發(fā)生該中斷事件時需要處理的邏輯代碼全部放在該程序中,比如數(shù)據(jù)的保存、LED等的亮滅等等,執(zhí)行完畢后退出中斷服務(wù)函數(shù);二是設(shè)置一個標(biāo)志位,然后在主函數(shù)的while循環(huán)中判斷此外部變量標(biāo)志位的值,進(jìn)而進(jìn)行相關(guān)操作。
?
第21組第一個問題:解析數(shù)據(jù)時關(guān)閉中斷這樣會不會有后續(xù)數(shù)據(jù)的丟失?
答:分兩種情況,如果在解析數(shù)據(jù)時,又從上位機(jī)發(fā)送了數(shù)據(jù)到單片機(jī),那么這部分?jǐn)?shù)據(jù)會丟失,因?yàn)橹袛嘁呀?jīng)關(guān)閉,無法進(jìn)入中斷服務(wù)函數(shù),數(shù)據(jù)根本無法接收,只會在硬件緩沖區(qū)一次又一次的被覆蓋。如果在解析數(shù)據(jù)時沒有新的數(shù)據(jù)傳輸?shù)絾纹瑱C(jī),等解析完畢后,中斷再次打開時,才有數(shù)據(jù)傳輸過來,那么對數(shù)據(jù)是沒有任何影響的。當(dāng)然,單片機(jī)處理數(shù)據(jù)的數(shù)據(jù)還是比較快的,如果上一次傳輸?shù)臄?shù)據(jù)比較少,解析數(shù)據(jù)的時間花費(fèi)少,中斷可以很快再次打開,那么是感覺不到什么影響的,如果一次傳輸大量數(shù)據(jù),在下一次傳輸時就可能存在丟失數(shù)據(jù)的情況,也就是丟包。
?
第4組第一個問題:當(dāng)數(shù)據(jù)進(jìn)入中斷的時候,主函數(shù)是在等待嗎?如果是的話中斷函數(shù)比較多,怎么保證當(dāng)中斷結(jié)束時主函數(shù)能從原來的位置直接運(yùn)行?
答:當(dāng)進(jìn)入中斷時,主函數(shù)的確是處于等待狀態(tài),但第二個問題不需要擔(dān)心,每一次進(jìn)入中斷時,硬件會自動進(jìn)行現(xiàn)場保護(hù),也就是開辟堆??臻g,保存當(dāng)前的狀態(tài)信息,當(dāng)然也包括當(dāng)前指令執(zhí)行的位置,中斷服務(wù)函數(shù)結(jié)束后,數(shù)據(jù)從堆棧中彈出,程序回到進(jìn)入中斷前的現(xiàn)場,繼續(xù)執(zhí)行。整個過程都是硬件自動完成,程序員不用做任何操作。
?
第5組第二個問題:如果傳輸數(shù)據(jù)中,出現(xiàn)終止符怎么辦?
答:一般不會在串口助手中發(fā)送終止符,字符串終止符(也就是空字符)的Ascii碼為0x00,在本文程序中,如果出現(xiàn)終止符,后續(xù)數(shù)據(jù)也是能夠接收的,即能夠保存在數(shù)組中。但是在單片機(jī)的串口發(fā)送函數(shù)中,遇到空字符就會認(rèn)為數(shù)據(jù)已經(jīng)結(jié)束,后續(xù)的數(shù)據(jù)不會被發(fā)送。遇到這種問題,暫時沒有一個好的解決方案,可以考慮修改串口發(fā)送函數(shù),不再以是否為空字符為結(jié)束標(biāo)志,而是確定一個明確的數(shù)據(jù)長度。
?
第18組第一個問題:程序中字符串的發(fā)送是怎么實(shí)現(xiàn)的?
答:程序中的字符串發(fā)送沒有用到任何中斷,當(dāng)然也可以使用中斷,在中斷服務(wù)函數(shù)中再調(diào)用數(shù)據(jù)發(fā)送函數(shù)。庫函數(shù)void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)可以實(shí)現(xiàn)通過串口發(fā)送引腳TX,發(fā)送1字節(jié)數(shù)據(jù)的功能,第一個參數(shù)為串口號,第二個參數(shù)為發(fā)送的數(shù)據(jù),因?yàn)镾TM32中的串口發(fā)送數(shù)據(jù)的字長有8位和9位兩種,所以此參數(shù)類型為uint16_t,即16位。但是一般8位最常用,因?yàn)閯偤靡粋€字節(jié),9位的用得較少。發(fā)送數(shù)據(jù)后需要等待當(dāng)前數(shù)據(jù)發(fā)送完成才能進(jìn)行下一次的發(fā)送,也就是等待發(fā)送完成標(biāo)志位TC置1,代碼為:
while(USART_GetFlagStatus(USART1,USART_FLAG_TC )==RESET);為了實(shí)現(xiàn)字符串的發(fā)送,也就是多個字節(jié)連續(xù)發(fā)送,可定義一個函數(shù),如下:
void Send_data(uint8_t *data) {while(*data!='\0'){while(USART_GetFlagStatus(USART1,USART_FLAG_TC )==RESET);USART_SendData(USART1,*data);data++;} }當(dāng)沒有到達(dá)字符串的結(jié)束標(biāo)志’\0’之前,循環(huán)調(diào)用數(shù)據(jù)發(fā)送函數(shù),同時指針移到下一位。值得注意的是,如果使用了串口發(fā)送功能,那么最好在串口初始化函數(shù)usart1_init()中最后加一句清除發(fā)送完成標(biāo)志的代碼,如下:
USART_ClearFlag(USART1,USART_FLAG_TC); ???//清除發(fā)送完成標(biāo)志位第2組第二個問題:除了數(shù)字還可以發(fā)送其他信息嗎?
答:可以的,傳輸?shù)臄?shù)據(jù)在傳輸線上就是一個個的高低電平,在單片機(jī)內(nèi)部就是01...這種的二進(jìn)制數(shù),將其用不同的譯碼規(guī)則翻譯就是不同的信息。一般將其保存到字符數(shù)組中,也就是字符類型,符合Ascii碼規(guī)則,包含了數(shù)字、字母、特殊字符等信息。
?
第24組第一個問題:一次發(fā)送數(shù)據(jù)的上限是多少?
答:理論上是沒有限制的,也就是單片機(jī)的串口可以連續(xù)工作,一直發(fā)送、接收數(shù)據(jù),實(shí)際使用時通常在軟件中定義一個緩沖數(shù)組,數(shù)組的大小就決定了一次發(fā)送數(shù)據(jù)的上限。本程序中定義大小為100。
?
第5組第三個問題:@printdata12345678900#多次與@printdata12345678901234567890...12345678900#數(shù)據(jù)傳輸?shù)牟顒e可以說一下么?
答:@printdata12345678900#多次,例如發(fā)送@printdata12345678900#@printdata12345678900#@printdata12345678900#時,按照本文程序的設(shè)計(jì)思路,依次檢查首尾指令,符合要求,將會正確打印中間數(shù)據(jù)部分,即打印12345678900#@printdata12345678900#@printdata1234567890
???發(fā)送@printdata12345678901234567890...12345678900#時,同樣檢查首尾指令,符合要求,將會正確打印中間數(shù)據(jù)部分,即打印12345678901234567890...1234567890
?
第24組第二個問題:在stm32端奇偶校驗(yàn)位要算在數(shù)據(jù)位中,在PC端奇偶校驗(yàn)位是否要算在數(shù)據(jù)位中?
答:這個與PC端串口調(diào)試助手開發(fā)的源碼有關(guān)系,但是大部分軟件都是如果在軟件界面的數(shù)據(jù)位選擇為8位,校驗(yàn)位選擇奇檢驗(yàn)或偶校驗(yàn),那么調(diào)試助手會將接收到的數(shù)據(jù)的低8位作為數(shù)據(jù)位,最高位單獨(dú)取出作為校驗(yàn)位。所以一般來說,PC端奇偶校驗(yàn)位不算在數(shù)據(jù)位中。
總結(jié)
以上是生活随笔為你收集整理的STM32串口通信程序模拟超市打印机工作-使用接收中断、空闲中断、校验中断的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: markdown语法补充和todo制作
- 下一篇: 无限循环小数与分数的对应关系证明
