使用開發(fā)板的USART作為UART通信,在前調(diào)用BSP_Init()函數(shù)初始化開發(fā)板,串口上傳輸?shù)臄?shù)據(jù)出錯:‘a(chǎn)’變成0xfa或0xfe;
【在這個問題解決之后,回頭總結(jié)下,在解決問題時:
1.預(yù)計有可能造成出錯的原因(這個可能需要一些經(jīng)驗(yàn),但是思維方式需要這樣的猜測,從系統(tǒng)內(nèi)外,可以先羅列出盡可能有的原因,后面再一一排除)
2.盡可能的定位出錯的地方(比如這里通過在線調(diào)試,確定在修改時鐘后,可以解決數(shù)據(jù)發(fā)送的不正確)
3.推測并排除次因,找出主因,往深一步探測 】
1:猜測原因。
外因:串口接收的過程受干擾
內(nèi)因:A.端口設(shè)置有問題 B.USART的波特率設(shè)置有問題
2:定位錯誤
在剛開始時通過屏蔽BSP_Init()發(fā)現(xiàn)功能正常,再具體定位到BSP_Init()里面的SYSCLK_Frequency時鐘設(shè)置,發(fā)現(xiàn)例程中默認(rèn)的是72M,但是改為36M,就沒有問題,應(yīng)該是時鐘方面的設(shè)置問題,具體的問題做何解析?
3:推測排除,深究
外因內(nèi)因很好排除,數(shù)據(jù)既然在波特率低時能正常通信,可能不是端口設(shè)置的問題,應(yīng)該是波特率的問題,??从脩羰謨栽摴?jié)的資料:
注:
1.CPU 的時鐘頻率越低,則某一特定波特率的誤差也越低??梢赃_(dá)到的波特率上限可以由這組數(shù)據(jù)得到。
2.只有USART1 使用PCLK2(最高72MHz)。其它USART使用PCLK1(最高36MHz)。
USART的波特率的計算公式:
USARTDIV是一個無符號的定點(diǎn)數(shù)。這12位的值設(shè)置在USART_BRR寄存器。那么USARTDIV與USART_BRR的關(guān)系又是怎么樣的?
加入USARTDIV=27.75;那么USART_BRR=0x1B(27)+0XC(0.75*16)=0X1BC;同理可以從USART_BRR推出USARTDIV的值;
假設(shè)fck=36000000;Tx=115200;=》USARTDIV=19.53125;所以0x13+(0.53125*16=8.5)=》0x13+0x9=0x139;所以實(shí)際上是0x139產(chǎn)生的波特率:115015.97(誤差率為0.15%);
===》理論最大波特率:36000000/(16*1.0)=2.25M(USARTDIV最小為1.0)
繼續(xù)往下查,對于SYSCLK_Frequency最高72M,運(yùn)行應(yīng)該沒有問題,但是目前有問題;順藤摸瓜,查看各個時鐘控制器,發(fā)現(xiàn)時鐘設(shè)置路徑:HSE--》PREDIV2--》PLL2--》PREDIV1--》PLL--》SYSCLK;
發(fā)現(xiàn)其中有問題:HSE(25M),PREDIV2(源代碼設(shè)置是2分頻),PLL2(8倍頻),PREDIV1(9倍頻),SYSCLK是算不出72M的,這時72M的算法其實(shí)已經(jīng)超過72M,所以給USART2時,波特率計算時會出現(xiàn)問題;將PREDIV2(改為5分頻就對了);
這就是為什么調(diào)用BSP_Init()或者SystemInit會出問題,他們都調(diào)用SetSysClock(),再調(diào)用SetSysClockTo72()【宏定義72M】,同時將系統(tǒng)時鐘改為36M時不會出問題,因?yàn)榇藭r調(diào)用的不是出問題的SetSysClockTo72(),而在之前用的是出錯的SetSysClockTo72()卻沒有發(fā)現(xiàn)問題,是因?yàn)橄到y(tǒng)時鐘雖沒有在預(yù)設(shè)值,但是系統(tǒng)還足以正常工作,但是一旦添加串口,波特率設(shè)置就會有很大的偏差,數(shù)據(jù)傳輸就出錯。
1:參考代碼其實(shí)里面是有很多問題的
2:我們應(yīng)該盡可能的多閱讀參考代碼,利用其中的資源,避免重復(fù)造輪子。
2:用串口終端軟件顯示字符串,連續(xù)發(fā)送幾個字符串時,“xxxx/n”,包含了換行轉(zhuǎn)義字符,但是就是不會換行?
通過調(diào)試,發(fā)現(xiàn)在存儲空間,轉(zhuǎn)義字符‘/n’是正確的0x0a,
USART_SendString(USART2,Menu[0]);
USART_SendString(USART2,Menu[1]);
USART_SendString(USART2,Menu[2]);
USART_SendString(USART2,Menu[3]);
但是不連續(xù)發(fā)送就不會出現(xiàn)這種現(xiàn)象,或者一句句調(diào)試打印也不會出現(xiàn)不換行的現(xiàn)象,斷定是連續(xù)發(fā)送的時間間隔太短,軟件還沒來得及換行,就又重新顯示新數(shù)據(jù),那么就在USART_SendString的尾部加了延時,就解決問題了。
來源:http://www.51hei.com/stm32/4117.html
審核編輯:何安
-
開發(fā)板
+關(guān)注
關(guān)注
26文章
6288瀏覽量
117968 -
STM32F
+關(guān)注
關(guān)注
1文章
42瀏覽量
18780 -
學(xué)習(xí)筆記
+關(guān)注
關(guān)注
1文章
28瀏覽量
7930
發(fā)布評論請先 登錄
碩博電子IO模塊修改波特率和節(jié)點(diǎn)ID操作步驟
FDCAN 數(shù)據(jù)段波特率增加后發(fā)送失敗的問題分析
支持小數(shù)波特率的意義是什么
串行時鐘發(fā)生器的計算公式
UART波特率計算及UART收發(fā)回顯實(shí)驗(yàn)
115200的波特率,為啥實(shí)際速度只有11KB/s?
波特率是什么
可編程電源的通信波特率應(yīng)如何設(shè)置?
基于瑞薩64位MPU RZ/G2L的uboot串口多波特率支持介紹
第十四章 USART——串口通訊
如何選擇合適的水位流量計算公式?
USART的波特率的計算公式
評論