版权声明:吴亚彪 https://blog.csdn.net/weixin_44288260/article/details/85793432
程序是CMSIS中的,分析它是怎么实现的?
波特率由整数和分数两部分组成。
RCC_GetClocksFreq(&RCC_ClocksStatus);
if (usartxbase == USART1_BASE)
{
apbclock = RCC_ClocksStatus.PCLK2_Frequency;
}
else
{
apbclock = RCC_ClocksStatus.PCLK1_Frequency;
}
整数部分的实现
USARTDIV *100
eg:USARTDIV = 25.62
则计算得 integerdivider =2562
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)));
}
提取出25,并左移4位,左移是为了和低4位与操作
tmpreg = (integerdivider / 100) << 4;
提取出62
fractionaldivider = integerdivider - (100 * (tmpreg >> 4));
之后62/100*16,它可能是小数,要找到最接近的整数,此时加0.5
最后再与整数部分相与。
/* 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;