前言:平時我們進(jìn)行c語言編程的時候會經(jīng)常用到printf函數(shù)進(jìn)行打印輸出,來調(diào)試代碼??墒沁@個printf函數(shù)C庫已經(jīng)幫我們實(shí)現(xiàn)好了,通常只需要直接調(diào)用即可,但是如果在一個新的開發(fā)平臺,如果庫沒有幫我們實(shí)現(xiàn)好,比如STM32開發(fā)板,那么我們怎么實(shí)現(xiàn)printf打印輸出呢?
首先我們來了解一下串口通信!
1、什么是串口通信?
串口通信(Serial Communication),是指外設(shè)和計(jì)算機(jī)間,通過數(shù)據(jù)信號線、地線等,按位進(jìn)行傳輸數(shù)據(jù)的一種通訊方式。
串口是一種接口標(biāo)準(zhǔn),它規(guī)定了接口的電氣標(biāo)準(zhǔn),沒有規(guī)定接口插件電纜以及使用的協(xié)議。
2、串口通信協(xié)議
在串口通信中,常用的協(xié)議包括RS-232、RS-422和RS-485。
?RS-232:標(biāo)準(zhǔn)串口,最常用的一種串行通訊接口。有三種類型(A,B和C),它們分別采用不同的電壓來表示on和off。最被廣泛使用的是RS-232C,它將mark(on)比特的電壓定義為-3V到-12V之間,而將space(off)的電壓定義到+3V到+12V之間。傳送距離最大為約15米,最高速率為20kb/s。RS-232是為點(diǎn)對點(diǎn)(即只用一對收、發(fā)設(shè)備)通訊而設(shè)計(jì)的,其驅(qū)動器負(fù)載為3~7kΩ。所以RS-232適合本地設(shè)備之間的通信。
?RS-422:最大傳輸距離為1219米,最大傳輸速率為10Mb/s。其平衡雙絞線的長度與傳輸速率成反比,在100kb/s速率以下,才可能達(dá)到最大傳輸距離。只有在很短的距離下才能獲得最高速率傳輸。一般100米長的雙絞線上所能獲得的最大傳輸速率僅為1Mb/s。
?RS-485:從RS-422基礎(chǔ)上發(fā)展而來的,最大傳輸距離約為1219米,最大傳輸速率為10Mb/s。平衡雙絞線的長度與傳輸速率成反比,在100kb/s速率以下,才可能使用規(guī)定最長的電纜長度。只有在很短的距離下才能獲得最高速率傳輸。一般100米長雙絞線最大傳輸速率僅為1Mb/s。
3、同步通信?異步通信?
同步通信:是一種比特同步通信技術(shù),要求發(fā)收雙方具有同頻同相的同步時鐘信號,只需在傳送報(bào)文的最前面附加特定的同步字符,使發(fā)收雙方建立同步,此后便在同步時鐘的控制下逐位發(fā)送/接收。如:SPI總線,I2C總線。
異步通信:指兩個互不同步的設(shè)備通過計(jì)時機(jī)制或其他技術(shù)進(jìn)行數(shù)據(jù)傳輸。也就是說,雙方不需要共同的時鐘。發(fā)送方可以隨時傳輸數(shù)據(jù),而接收方必須在信息到達(dá)時準(zhǔn)備好接收。如:串口(USART)
4、通信方式
?單工模式(Simplex Communication):單向的數(shù)據(jù)傳輸。通信雙方中,一方為發(fā)送端,一方則為接收端。信息只能沿一個方向傳輸,使用一根傳輸線。雙方是固定的。
?半雙工模式(Half Duplex):通信使用同一根傳輸線,既可以發(fā)送數(shù)據(jù)又可以接收數(shù)據(jù),但不能同時進(jìn)行發(fā)送和接收。數(shù)據(jù)傳輸允許數(shù)據(jù)在兩個方向上傳輸,但是,在任何時刻只能由其中的一方發(fā)送數(shù)據(jù),另一方接收數(shù)據(jù)。
?全雙工模式(Full Duplex)通信允許數(shù)據(jù)同時在兩個方向上傳輸。因此,全雙工通信是兩個單工通信方式的結(jié)合,它要求發(fā)送設(shè)備和接收設(shè)備都有獨(dú)立的接收和發(fā)送能力。在全雙工模式中,每一端都有發(fā)送器和接收器,有兩條傳輸線,信息傳輸效率高。
5、數(shù)據(jù)格式
(1)起始位:起始位必須是持續(xù)一個比特時間的“0”,標(biāo)志傳輸一個字符的開始。
?。?)數(shù)據(jù)位:數(shù)據(jù)位緊跟在起始位之后,是通信中的真正有效信息。數(shù)據(jù)位的位數(shù)可以由通信雙方共同約定,一般可以是5位、7位或8位。傳輸數(shù)據(jù)時先傳送字符的低位,后傳送字符的高位。
(3)奇偶校驗(yàn)位:奇偶校驗(yàn)位僅占一位,用于進(jìn)行奇校驗(yàn)或偶校驗(yàn),奇偶檢驗(yàn)位不是必須有的。如果是奇校驗(yàn),需要保證傳輸?shù)臄?shù)據(jù)總共有奇數(shù)個“1”;如果是偶校驗(yàn),需要保證傳輸?shù)臄?shù)據(jù)總共有偶數(shù)個“1”
?。?)停止位:停止位可以是是1位、1.5位或2位,可以由軟件設(shè)定。它一定是“1”,標(biāo)志著傳輸一個字符的結(jié)束。
?。?)空閑位:空閑位是指從一個字符的停止位結(jié)束到下一個字符的起始位開始,表示線路處于空閑狀態(tài),必須由高電平來填充。
了解了串口通信的基礎(chǔ)知識之后,我們再來看看STM32開發(fā)板上是如何實(shí)現(xiàn)串口通信的,我以實(shí)現(xiàn)printf重定向?yàn)槔齺磉M(jìn)行分析!
先看代碼:
main.c:
printf.c:
printf.h:
代碼分析:
1.串口初始化配置
學(xué)了STM串口通信之后,我們知道配置串口通信至少要配置:字長(一次傳送的數(shù)據(jù)長度),波特率(每秒傳輸?shù)臄?shù)據(jù)位數(shù)),奇偶校驗(yàn)位,還有停止位。當(dāng)然我在
配置過程中把他們分別設(shè)為8,115200,No ,1。
串口的配置主要與USART_InitTypeDef這個結(jié)構(gòu)體有關(guān),里面存放了控制參數(shù)成員:
其實(shí)在學(xué)習(xí)32的時候,一般如果要用到32的內(nèi)設(shè)或者外設(shè),都要進(jìn)行相應(yīng)的初始化,也就是相應(yīng)的結(jié)構(gòu)體成員進(jìn)行配置,而我們本次要實(shí)現(xiàn)的printf重定向,也
就用到了串口,所以也要對串口進(jìn)行初始化!而我是用的USART2,所以要對其進(jìn)行相應(yīng)的配置。
查看STM32硬件原理圖:
由原理圖可知,這個串口是支持TTL電平的,接收數(shù)據(jù)RX是接在PA3管腳上的,發(fā)送數(shù)據(jù)是接在PA2上的。由于我是要輸出到PC上的串口終端,所以PA2要
設(shè)為復(fù)用推挽輸出模式,PA3設(shè)為復(fù)用開漏輸入模式。
查看stm32f10x_it.c這個代碼可知USART2是掛接在APB1總線上的,GPIO是掛在APB2總線上的,如下所示:
所以我們在進(jìn)行時鐘初始化的時候要特別注意。
2.printf重定向
其實(shí)printf重定向就是我們將printf重新定向到串口,也就是我們可以自己重寫C的庫函數(shù),當(dāng)連接器檢查到用戶編寫了與C庫函數(shù)相同的名字,優(yōu)先采用
用戶編寫的函數(shù)這樣用戶就可以實(shí)現(xiàn)對庫的修改了。
printf函數(shù)實(shí)際是一個宏,最終調(diào)用的是 fputc(int ch,F(xiàn)ILE *f)這個函數(shù),所以我們需要修改這個函數(shù)。
下面我們著重分析一下fputc函數(shù):
這個庫函數(shù)調(diào)用了兩個ST庫函數(shù),分別是:USART_GetFlagStatus()與USART_SendData(),形參ch表示串口將要發(fā)送的數(shù)據(jù),也就是說。當(dāng)使用printf()時,它先調(diào)用fpuc()函數(shù),然后使用ST庫的串口發(fā)送函數(shù)USART_SendData(),把數(shù)據(jù)轉(zhuǎn)移到發(fā)送數(shù)據(jù)寄存器TDR.觸發(fā)我們的串口向PC發(fā)送一個相應(yīng)的數(shù)據(jù),調(diào)用完USART_SendData()之后,
使用 while(USART_GetFlagStatus(USART2,USART_FLAG_TC) != SET)語句不停的檢查串口的數(shù)據(jù)是否發(fā)送完成的標(biāo)志位TC,一直檢查到標(biāo)志為“完成”,才進(jìn)行下一步操作,
要注意的是USART_SendData()每次只發(fā)送一個字節(jié)的數(shù)據(jù)!
注意:由于fputc()函數(shù)的形參調(diào)用了C庫的FILE,所以在程序中加入stdio.h這個頭文件,便且在keil的編譯器的設(shè)置中勾選Use MicroLIB(使用微庫)
3.硬件連接
首先硬件上我們將USB轉(zhuǎn)串口線的TXD,RXD,GND,分別接在32開發(fā)板USART2上的RXD,TXD,GND。
由于USART2是TTL電平,所以我們用的usb轉(zhuǎn)串口線一定要是支持TTL電平的,否則串口通信不上!
4.效果圖
串口調(diào)試助手顯示:
評論
查看更多