在使用GD32 108M配置串口的时候出现乱码,于是查找原因。
首先说下108M的时钟配置
根据前人的经验
/* PLL configuration: PLLCLK = HSE/2 * 30 = 120 MHz */
RCC->CFGR |= (uint32_t)(0x08000000 | RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL15);
因为GD32的手册里要配置PLLMULL到30倍,用到了CFGR的第27位,所以上面0x08000000把这位置1。
而在STM32里第27位是保留不用的。GD32使用了这个保留位。
但是在串中初始化的时候计算波特率的时候并没有使用第27位,这就倒置计算时候的时候出现了问题,我们看下串口的初始化函数USART_Init
在这个函数里配置波特率的时候用到RCC_GetClocksFreq 这个函数,在进入到这个函数里看下
发现在计算时钟频率的时候是这样子的
/* Get PLL clock source and multiplication factor ----------------------*/
pllmull = RCC->CFGR & CFGR_PLLMull_Mask; (由于STM32中这里并没有用到第27位)
.
#ifndef STM32F10X_CL
pllmull = ( pllmull >> 18) + 2;
.
.
.
/* HSE selected as PLL clock entry */
if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (uint32_t)RESET)
{/* HSE oscillator clock divided by 2 */
RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE >> 1) * pllmull;
}
else
{
RCC_Clocks->SYSCLK_Frequency = HSE_VALUE * pllmull;
}
在计算SYSCLK的时候用到PLLMULL,而STM32中CFGR的第27位是保留位,不使用。所以导致计算SYSCLK时出错,在STM32中PLLMULL最大只到16,而GD32中最大到32,
所以在GD23中使用PLLMULL超过16就要小心了。
而108M时候配置PLLMULL是30,超过了16。在STM32里其实PLLMULL是15,正好相差了一倍。
所以在使用GD32串口使用的时候有三种解决方案:
1、使用上面的108M的时钟配置,如果我们串口波特率设置为9600,那么我们在上位机打开串口配置的波特率就应该是9600*2。总之上位机的波特率是MCU的2倍。
2、使用120M的时钟配置,修改上面的108M时钟配置为:
/* PLL configuration: PLLCLK = HSE * 15 = 120 MHz */
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE | RCC_CFGR_PLLMULL15);
3、我们使用默认的72M时钟配置,啥也不用修改。
致此解决串口乱码问题。
|