Arm 使用HSE的STM32L152 UART波特率halfes

Arm 使用HSE的STM32L152 UART波特率halfes,arm,embedded,stm32,cortex-m3,Arm,Embedded,Stm32,Cortex M3,我试图在STM32L152上配置USART1的波特率。使用外部时钟时,波特率是我配置的一半(例如57600而不是115200)。然而,当使用内部HSI时,一切都是正确的。内部为16 MHz,外部为8 MHz晶体,用于驱动32 MHz系统时钟的PLL 这是RCC初始化代码,我想这是相当标准的 int-RCC\u配置(无效) { /*在时钟配置之前禁用HSI和目标时钟*/ RCC_HSICmd(禁用); RCC_PLLCmd(禁用); RCC\u HSEConfig(RCC\u HSE\u关闭);

我试图在STM32L152上配置USART1的波特率。使用外部时钟时,波特率是我配置的一半(例如57600而不是115200)。然而,当使用内部HSI时,一切都是正确的。内部为16 MHz,外部为8 MHz晶体,用于驱动32 MHz系统时钟的PLL

这是RCC初始化代码,我想这是相当标准的

int-RCC\u配置(无效)
{
/*在时钟配置之前禁用HSI和目标时钟*/
RCC_HSICmd(禁用);
RCC_PLLCmd(禁用);
RCC\u HSEConfig(RCC\u HSE\u关闭);
/*将HSE设置为系统时钟*/
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);
/*启用ADC和SYSCFG时钟*/
RCC_APB2Periph_SYSCFG,启用);
/*允许访问RTC*/
PWR_RTCASSCMD(启用);
/*重置RTC备份域*/
RCC_RTCRestecmd(启用);
RCC_RTCRestecmd(禁用);
/*用作RTC源时钟的LSI*/
/*RTC时钟可能因LSI频率分散而变化*/
/*启用LSI OSC*/
RCC_LSICmd(启用);
/*等待LSE准备就绪*/
而(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)=重置);
/*选择RTC时钟源*/
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
/*启用RTC*/
RCC_RTCCLKCmd(启用);
/*等待RTC APB寄存器同步*/
RTC_WaitForSynchro();
//启用HSE
RCC_HSEConfig(RCC_HSE_ON);
ErrorStatus HSEStartUpStatus=RCC_WaitForHSEStartUp();
如果(HSEStartUpStatus==成功)
{
/*32Mhz=8Mhz*12/3*/
RCC项目配置(RCC项目资源、HSE、RCC项目12、RCC项目3);
/*启用锁相环*/
RCC_PLLCmd(启用);
/*等待PLL准备就绪*/
同时(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)=重置)
{
}
/*选择PLL作为系统时钟源*/
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/*等待PLL用作系统时钟源*/
而(RCC_GetSYSCLKSource()!=0x0C)//0x0C=PLL
{
}
/*启用PWR时钟*/
RCC_APB1PeriphLockCmd(RCC_APB1Periph_压水堆,启用);
PWR->CR=PWR\U CR\U VOS\U 0;/*选择电压范围1(1.8V)*/
同时((PWR->CSR&PWR_CSR_VOSF)!=0);/*等待调压器准备就绪*/
/*HCLK=SYSCLK*/
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/*PCLK1=HCLK/2*/
RCC_PCLK1配置(RCC_HCLK_分区2);
/*PCLK2=HCLK*/
RCC_PCLK2配置(RCC_HCLK_分区1);
/*启用GPIOs时钟*/
RCC(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOH,启用);
/*启用比较器、LCD和PWR mngt时钟*/
RCC|APB1PeriphLockCmd(RCC|APB1Periph|COMP|RCC|APB1Periph|LCD|RCC|APB1Periph|PWR,启用);
}
返回0;
}
我使用STDperiph来配置UART1,它在这个mcu上将在PCLK2上运行。检查了所有的init方法和寄存器内容。波特率寄存器的尾数和分数计算正确,无论PCLK值是什么,都应产生正确的波特率

这是UART初始化代码:

void usartinit(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitStructure.USART_波特率=115200;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_奇偶校验=USART_奇偶校验号;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl\u None;
USART_InitStructure.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
/*启用GPIO时钟*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,启用);
RCC_APB2PeriphLockCmd(RCC_APB2Periph_USART1,启用);
GPIO_PinAFConfig(USARTx_GPIO、GPIO_PinSource9、GPIO_AF_USART1);
GPIO_PinAFConfig(USARTx_GPIO、GPIO_PinSource10、GPIO_AF_USART1);
/*将USART Tx配置为备用功能推拉*/
GPIO_InitStructure.GPIO_Mode=GPIO_Mode\u AF;
GPIO_InitStructure.GPIO_OType=GPIO_OType\u PP;
GPIO_InitStructure.GPIO_Pin=USARTx_TX;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd\u UP;
GPIO_Init(USARTx_GPIO和GPIO_InitStructure);
/*将USART Rx配置为浮动输入*/
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin=USARTx_RX;
GPIO_Init(USARTx_GPIO和GPIO_InitStructure);
/*USART配置*/
USART_Init(USART1和USART_InitStructure);
/*启用USART*/
USART_Cmd(USART1,启用);
}
我现在能想到的唯一可能性是,晶体只有4兆赫,但这是一个核子板,附加STLink的MCO用于HSE,肯定是8兆赫


我犯了什么明显的错误?

看来时钟搞乱了。检查代码中的HSE_值宏。这可能是使用默认的开发板水晶值。我建议将该值更改为您正在使用的晶体。您可以使用链接设置时钟速度

我认为前面的答案是正确的。使用HSI时,系统时钟为16MHz,而使用HSE时,系统时钟为32MHz

我怀疑HSE值设置为16MHz

您还可以通过将乘法器设置为4,将除法器设置为2来测试这一点,以便在运行HSE时系统时钟为16MHz

HSE值将出现在启动代码的某个地方


USART代码使用该值,以便知道USART的驱动频率,从而计算波特率。

好的,最后计算出来。在默认配置的Nucleo板上,HSE时钟连接到板上STLink编程器的MCO时钟输出。然而,在我的多个电路板上,该时钟信号失真如此之大,以至于目标uC只能看到4 MHz。如果我在目标的MCO上输出HSE,它会产生一个4MHz的方波,占空比为75%。当探测MC时