2015-10-29 12:44 AM
Hello. The issue: file stm32f4xx_usart.c, function USART_Init, fractional divider calculation code:
/* 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);
}
It does not take into account that the result of
(((fractionaldivider * 8) + 50) / 100)
or
(((fractionaldivider * 16) + 50) / 100)
could become equal to, respectively, 8 or It would be required in that case to increment integer divider part while leaving fractional part equal to 0. And, in general, no masking of muldiv result (either by 0x07 or by 0x0f) is required since that result is in the masked range ''by desing'' — except of the case described.
Needed something like this:
/* Determine the fractional part */
fractionaldivider = integerdivider - (100 * (tmpreg >> 4));
/* Implement the fractional part in the register */
if
((USARTx->CR1 & USART_CR1_OVER8) != 0)
{
fractionaldivider = ((fractionaldivider * 8) + 50) / 100;
tmpreg += (fractionaldivider < 8) ? fractionaldivider : 0x10;
}
else
/* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */
{
tmpreg += ((((fractionaldivider * 16) + 50) / 100));
}
#stm32f4xx-stdperif