首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ARM - STM32 使用11.0592MHz晶振 (3)

ARM - STM32 使用11.0592MHz晶振 (3)

  • void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)  
  • {  
  •   uint32_t tmpreg = 0x00, apbclock = 0x00;  
  •   uint32_t integerdivider = 0x00;  
  •   uint32_t fractionaldivider = 0x00;  
  •   uint32_t usartxbase = 0;  
  •   RCC_ClocksTypeDef RCC_ClocksStatus;  
  •   /* Check the parameters */
  •   assert_param(IS_USART_ALL_PERIPH(USARTx));  
  •   assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate));   
  •   assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->USART_WordLength));  
  •   assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits));  
  •   assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity));  
  •   assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode));  
  •   assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl));  
  •   /* The hardware flow control is available only for USART1, USART2 and USART3 */
  •   if (USART_InitStruct->USART_HardwareFlowControl != USART_HardwareFlowControl_None)  
  •   {  
  •     assert_param(IS_USART_123_PERIPH(USARTx));  
  •   }  

  •   usartxbase = (uint32_t)USARTx;  

  • /*---------------------------- USART CR2 Configuration -----------------------*/
  •   tmpreg = USARTx->CR2;  
  •   /* Clear STOP[13:12] bits */
  •   tmpreg &= CR2_STOP_CLEAR_Mask;  
  •   /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit ------------*/
  •   /* Set STOP[13:12] bits according to USART_StopBits value */
  •   tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits;  

  •   /* Write to USART CR2 */
  •   USARTx->CR2 = (uint16_t)tmpreg;  

  • /*---------------------------- USART CR1 Configuration -----------------------*/
  •   tmpreg = USARTx->CR1;  
  •   /* Clear M, PCE, PS, TE and RE bits */
  •   tmpreg &= CR1_CLEAR_Mask;  
  •   /* Configure the USART Word Length, Parity and mode ----------------------- */
  •   /* Set the M bits according to USART_WordLength value */
  •   /* Set PCE and PS bits according to USART_Parity value */
  •   /* Set TE and RE bits according to USART_Mode value */
  •   tmpreg |= (uint32_t)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity |  
  •             USART_InitStruct->USART_Mode;  
  •   /* Write to USART CR1 */
  •   USARTx->CR1 = (uint16_t)tmpreg;  

  • /*---------------------------- USART CR3 Configuration -----------------------*/
  •   tmpreg = USARTx->CR3;  
  •   /* Clear CTSE and RTSE bits */
  •   tmpreg &= CR3_CLEAR_Mask;  
  •   /* Configure the USART HFC -------------------------------------------------*/
  •   /* Set CTSE and RTSE bits according to USART_HardwareFlowControl value */
  •   tmpreg |= USART_InitStruct->USART_HardwareFlowControl;  
  •   /* Write to USART CR3 */
  •   USARTx->CR3 = (uint16_t)tmpreg;  

  • /*---------------------------- USART BRR Configuration -----------------------*/
  •   /* Configure the USART Baud Rate -------------------------------------------*/
  •   RCC_GetClocksFreq(&RCC_ClocksStatus);  
  •   if (usartxbase == USART1_BASE)  
  •   {  
  •     apbclock = RCC_ClocksStatus.PCLK2_Frequency;  
  •   }  
  •   else
  •   {  
  • <span style="color:#ff0000;">    apbclock = RCC_ClocksStatus.PCLK1_Frequency;</span>  
  •   }  

  •   /* 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 */
  • <span style="color:#ff0000;">    integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate)));  </span><span style="color:#3366ff;">//apbclock=0xA8C000=11059200 </span>
  •   }  
  • <span style="color:#ff0000;">  tmpreg = (integerdivider / 100) << 4;                                             </span><span style="color:#3333ff;">// 得到integerdivider</span><span style="color: rgb(255, 0, 0); "> </span><span style="color:#3333ff;">
  • </span>  

  •   /* Determine the fractional part */
  • <span style="color:#ff0000;">  fractionaldivider = integerdivider - (100 * (tmpreg >> 4));                       </span><span style="color:#3333ff;">//得到fractionaldivider</span><span style="color: rgb(255, 0, 0); "> </span><span style="color:#ff0000;">
  • </span>  

  •   /* 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) */
  •   {  
  • <span style="color:#ff0000;">   tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);</span>  
  •   }  

  •   /* Write to USART BRR */
  •   USARTx->BRR = (uint16_t)tmpreg;  
  • }  



小数波特率发送和接收由一共用的波特率发生器驱动,当发送器和接收器的使能位分别(TE和RE)置位时,分别为其产生时钟。接收器和发送器的波特率应设置成相同。
Tx / Rx 波特率 = PCLKx / (16 * USARTDIV)PCLKx可以是APB1的时钟PCLK1(用于USART1),也可以是APB2的时钟PCLK2(用于USART2、3、4、5) 。

USARTDIV = DIV_Maintissa[11:0] + DIV_Fraction[3:0] / 16USARTDIV是一个无符号的定点数,转换成对应的二进制小数后,整数部分存放在USART_BRR寄存器中的DIV_Maintissa[11:0],小数部分存放在USART_BRR寄存器中的DIV_Fraction[3:0]。
注:在写入USART_BRR之后,波特率计数器会被波特率寄存器的新值替换。因此,不要在通信进行中改变波特率寄存器的数值。
继承事业,薪火相传
返回列表