STM32
直播中

juju宇哥

8年用户 1400经验值
擅长:479809
私信 关注
[问答]

如何获取到STM32的波特率?

如何获取到STM32的波特率?

回帖(1)

乔亚楠

2021-12-16 10:04:42
    笔者在做毕业设计的时候遇到一个问题:
要通过与USART2相连的串口屏设置单片机USART1的波特率,在串口屏载入该页面的时候,需要呈现当前USART1的波特率,那么如何获取到波特率呢?
很容易想到的办法就是:根据串口初始化的函数顺藤摸瓜,找到写波特率的寄存器,然后把寄存器读出来就好了
然鹅:

/*---------------------------- USART BRR Configuration -----------------------*/
  /* Configure the USART Baud Rate -------------------------------------------*/
  RCC_GetClocksFreq(&RCC_ClocksStatus);
  if (usartxbase == USART1_BASE)
  {
    apbclock = RCC_ClocksStatus.PCLK2_Frequency;
  }
  else
  {
    apbclock = RCC_ClocksStatus.PCLK1_Frequency;
  }
  
  /* Determine the integer part */
  if ((USARTx->CR1 & CR1_OVER8_Set) != 0)
  {
    /* Integer part computing in case Oversampling mode is 8 Samples */
    integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate)));   
  }
  else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 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 & CR1_OVER8_Set) != 0)
  {
    tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07);
  }
  else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
  {
    tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);
  }
  
  /* Write to USART BRR */
  USARTx->BRR = (uint16_t)tmpreg;


虽然这里貌似计算方法很复杂的样子,其实也是能看出一些端倪的,不过,我们还是看手册吧。
    资料1:
  25.6.3 波特比率寄存器(USART_BRR)

  注意: 如果 TE 或 RE 被分别禁止,波特计数器停止计数
地址偏移:0x08
复位值:0x0000
  [tr][/tr]

31302928272625242322212019181716
保留














1514131211109876543210
DIV_Mantissa[11:0]DIV_Fraction[3:0]













rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw
  
位31:16保留位,硬件强制为0
位15:4DIV_Mantissa[11:0]:USARTDIV的整数部分  位15:4
这12位定义了USART分频器除法因子(USARTDIV)的整数部分。
位3:0DIV_Fraction[3:0]:USARTDIV的小数部分  位3:0
这4位定义了USART分频器除法因子(USARTDIV)的小数部分。
      资料2:
表176 设置波特率时的误差计算
  
波特率fPCLK=36MHzfPCLK=72MHz




序号Kbps实际置于波特率
寄存器中的值
误差%实际置于波特率
寄存器中的值
误差%
12.42.4937.50%2.418750%
29.69.6234.3750%9.6468.750%
319.219.2117.18750%19.2234.3750%
457.657.639.06250%57.678.1250%
5115.2115.38419.50.15%115.239.06250%
6230.4230.7699.750.16%230.76919.50.16%
7460.8461.5384.8750.16%461.5389.750.16%
8921.6923.0762.43750.16%923.0764.8750.16%
92250225010%225020%
104500------450010%
      资料3:
  25.3.4 分数波特率的产生(节选)

  接收器和发送器的波特率在USARTDIV的整数和小数寄存器中的值应设置成相同。
      
这里的 f CK 是给外设的时钟 (PCLK1 用于 USART2 、 3 、 4 、 5 , PCLK2 用于 USART1)
USARTDIV是一个无符号的定点数。这12位的值设置在USART_BRR寄存器
    好了资料码完了
下面是计算过程:
  首先,根据资料1,得到USARTDIV的整数部分,
   
DIV_Mantissa = (int)((USART1->BRR&0x0000ffff)>>4)
由于我要获取的是USART1的波特率,根据资料3可知,
                 
则,根据资料2中表格第三栏 fPCLK=72MHz 中的 置于波特率寄存器中的值 与算得的 DIV_Mantissa 作比较,即可获得对应的波特率。
比如,算得 DIV_Mantissa=468,查表可知波特率为9.6Kbps即9600。
  以上。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分