日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

STM32 USART 波特率计算

發布時間:2023/12/24 综合教程 39 生活家
生活随笔 收集整理的這篇文章主要介紹了 STM32 USART 波特率计算 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

The baud rate for the receiver and transmitter (Rx and Tx) are both set to the same value

asprogrammed in the Mantissa and Fraction values of USARTDIV.

從上圖可以看出,該寄存器高 16 位無效,最低 4 位為小數部分,其余部分為整數部分。

這樣的設計可以使波特率更加精確。關于波特率的產生,有這么一段話來解釋:

分數波特率的產生: 接收器和發送器(RX和TX)都是設置成為 USARTDIV 整數和小數寄存器中配置的值。

This give the following equation for baud rate:

Tx/Rx baud = CK_APB1 / (8 x (2 - OVER8) x USARTDIV)

Where USARTDIV is an unsigned fixed point number that is coded on the USART_BRR register.

When OVER8=0, the fractional part is coded on 4 bits and programmed by the DIV_fraction[3:0] bits in the USART_BRR register
Tx/Rx baud = CK_APB1 / (16 x USARTDIV)

When OVER8=1, the fractional part is coded on 3 bits and programmed by the DIV_fraction[2:0] bits in the USART_BRR register,
and bit DIV_fraction[3]must be kept cleared.
Tx/Rx baud = CK_APB1 / (8 x USARTDIV)

The baud counters are updated to the new value in the baud registers after a write operationto USART_BRR.

Hence the baud rate register value should not be changed duringcommunication.

The USARTs are on the APB1 bus, Figure 12 in the reference manual is the clock tree,
which shows how the APB1 clock is derived from the PLL clock.
The maximum APB1 clock is 32MHz.

OVER8=1 is required for higher speeds, giving:baud = 32000000/ (USARTDIV x 8).

So USARTDIV = 32000000/ (baud x 8)

For 4Mbps therefore, USARTDIV=1 (see table 138 S.No.12 for details).

For 2Mps, USARTDIV=2.

To achieve 3Mbps you will have to reduce the APB1 clock to 24MHz and set USARTDIV=1 (see table 131).

But note that the clock rate changes for all other APB1 peripherals too.

The simplest way to correctly program the USART baud rate is via theSTM32L1xx standard peripheral library.

Also to determine the correct peripheral clock settings (and more), and generate initialisation code,

you can use STM'sMicroXplorertool.

Fpclk = 12 MHz, Baud = 460800 Bps :OVER8 = 0

DIV = 12000000 / ( 16 * 460800 ) = 1.6276

DIV_Mantissa = 1

DIV_Fraction = 0.6276 * 16 = 10

USARTDIV = ( 1 << 4 ) | 10 = 0x001A = 1.625

12000000 / ( 16 * 1.625 ) = 12000000 / 26 =461538.5 Bps

Fpclk = 12 MHz, Baud = 460800 Bps :OVER8 = 1

DIV = 12000000 / ( 8 * 460800 ) =3.255

DIV_Mantissa = 3

DIV_Fraction =0.255 * 8 =2.04

USARTDIV = ( 3 << 4 ) | 2 = 0x0032 = 3.25

12000000 / ( 8 * 3.25 ) = 12000000 / 26 =461538.5 Bps

stm32波特率設置,在115200時候,實際是115384,會有0.15%的誤差, 不過還是可以接受的。

其實stm32的uart還是蠻簡單的,初始化4個寄存器完事,就是波特率方面需要算算。原文:

stm32 中文資料中有如下計算公式 :

Tx / Rx 波特率 =fPCLKx/(16*USARTDIV);

這里的fPCLKx(x=1、2)是給外設的時鐘(PCLK1用于USART2、3、4、5,PCLK2用于USART1)

USARTDIV是一個無符號的定點數。這12位的值設置在USART_BRR寄存器。

如果使用USART1,系統時鐘為72MHZ,USART1使用PCLK2時鐘,也定義為72MHz.

定義波特率=9600,fPCLK2=72MHz,則: 計算USARTDIV=72MHz/9600/16=468.75

取整數468=0x1D4.小數0.75*16=12=0x0C.所以寫入寄存器USART_BRR中的值為:USART_BRR=0x1D4C.

如果使用USART2,USART2使用PCLK1時鐘,PCLK1時鐘為36MHz.

定義波特率=9600,fPCLK1=36MHz,則: 計算USARTDIV=36MHz/9600/16=234.375

取整數234=0xEA.小數0.375*16=6=0x06.所以寫入寄存器USART_BRR中的值為:USART_BRR=0xEA6.

24000000 / 19200 = 1250 = 0x4E2 --> 78 + 2/16 = 78.125

24000000 / ( 16 * 19200 ) = 78.125

24000000 / 921600 = 26 = 0x1A --> 1 + 10/16 = 1.625

24000000 / ( 16 * 921600 ) = 1.625

uint32_t tmpreg = 0x00, apbclock = 0x00;
uint64_t integerdivider = 0x00;
uint32_t fractionaldivider = 0x00;

  /* Determine the integer part */
  if ((USARTx->CR1 & USART_CR1_OVER8) != 0)
  {
    /* Integer part computing in case Oversampling mode is 8 Samples */
    integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate)));    

// ( 2^^32 - 1 ) / 25 = 4294967295 / 25 = 171798691.84 = 171.8 MHZ
// STM32F429 MAX 180MHz
} else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */ { /* Integer part computing in case Oversampling mode is 16 Samples */ integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate))); } tmpreg = (integerdivider / 100) << 4; /* Determine the fractional part */ fractionaldivider = integerdivider - (100 * (tmpreg >> 4)); /* Implement the fractional part in the register */ if ((USARTx->CR1 & USART_CR1_OVER8) != 0) { tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07); } else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */ { tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F); } /* Write to USART BRR register */ USARTx->BRR = (uint16_t)tmpreg;

(1)將算出的USARTDIV擴大100倍保留整數部分。

(2)百位以上的送入BRR[15:4],百位以下的換算成16進制值送入[3:0]

也即對于USARTDIV小數部分,只有小數點后兩位保留,兩位以后的全部舍去,

比如理論計算得到 USARTDIV = 234.28125 被處理為 USARTDIV = 234.28,這樣就損失了精度,

造成了最終送入BRR的實際值并不是理論值的四舍五入(5以上的有可能也被舍去)

如想要得到完全符合四舍五入原則的精確結果,則USART至少應該放大 100000 倍,

保留小數點后5位,5位以后的部分全部舍去也仍然落在正確的區間內。新程序如下:

     baudsource = apbclock * 100000 / ( 16 * BaudRate );
     interger = baudsource / 100000;
     fractional = ( baudsource % 100000 + 3125 ) / 6250;
     USART1->BRR = ( interger << 4 ) + fractional;

以一個例子說明:如設置波特率為Baud Rate = 19207 bps

72000000 / ( 16 * 19207 ) = 234.28958192325714583224865934295...

(1) BRR[3:0]理論值:16 * 0.28958192325714583224865934295... = 4.6333107721143333159785494871661...

按四舍五入的原則取 BRR[3:0] = 0x05

(2)官方庫:( 28 * 16 + 50 ) / 100 = 498 / 100 = 4, BRR[3:0] = 0x04 與理論值差1

(3) 新程序:( 28958 + 3125 ) / 6250 = 32173 / 6250 = 5, BRR[3:0] = 0x05,與理論值一致。

STM32的串口速率:APB速度/波特率 =USARTDIV [OVER8 = 0 ]

uint32_t USART_BRR( uint32_t clock, uint32_t baud )
{
  uint64_t clcok_x = clock * 10000ULL;
  uint64_t brr = ( ( clcok_x / baud ) + 5000ULL ) / 10000ULL;
  return brr;
}

72000000 * 10000 / 19207 = 37486333

37486333 + 5000 = 37491333

37491333 / 10000 = 3749 = 0x0EA5 --> 234.3125

72000000 / ( 16 * 234.3125 ) =19205

#define UART_BRR_SAMPLING16(_PCLK_, _BAUD_)     (((_PCLK_)+(_BAUD_)/2)/_BAUD_)
__INLINE static uint16_t UART_BRR_SAMPLING8(uint32_t _PCLK_, uint32_t _BAUD_)
{
    uint16_t Div = (_PCLK_ + _BAUD_/2)/_BAUD_;  
    return ((Div & ~0x7)<<1 | (Div & 0x07));
}  

精度能到多高,由BRR的4bit小數決定了,不管乘多大的數,最終一除還是4bit小數。

理論誤差最大就是正負0.5bit了,也就是分頻系數的1/32。

如果要保證1%的精度,分頻系數>100/32=3.125就夠了,一般系統都可以滿足。

也就是要么分頻系數夠大,要么盡量整除,誤差就可以滿足要求。

如果硬要扯絕對精度,當BAUD為奇數時,除了那0.5bit的誤差,

還有因為BAUD/2除不盡再來的誤差,也就是1/BAUD bit。

那0.5bit的誤差都可以忽略了,1/BAUD bit的誤差就更不用提了吧?

而且有誰的系統里波特率是奇數?

PS:我們用的系統都是有限精度系統,只要精度滿足要求就行了。

STM32庫函數USART波特率計算的奇葩問題

不管乘多大數再除掉,精度不可能超過這個算法:

(PCLK + BAUD/2)/BAUD,

只不過增加運算法。

STM32庫函數USART波特率計算的奇葩問題

總結

以上是生活随笔為你收集整理的STM32 USART 波特率计算的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。