首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用HSE的STM32L152 UART波特率半部

使用HSE的STM32L152 UART波特率半部
EN

Stack Overflow用户
提问于 2018-08-13 15:56:00
回答 3查看 1.3K关注 0票数 1

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

这是RCC init代码,我猜这是相当标准的代码。

代码语言:javascript
复制
int RCC_Configuration(void)
{
  /* DISABLE HSI and target clocks prior to clock config */
  RCC_HSICmd(DISABLE);
  RCC_PLLCmd(DISABLE);
  RCC_HSEConfig(RCC_HSE_OFF);

  /* Set HSE as sys clock*/
  RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);

  /* Enable ADC & SYSCFG clocks */
  RCC_APB2Periph_SYSCFG , ENABLE);

  /* Allow access to the RTC */
  PWR_RTCAccessCmd(ENABLE);

  /* Reset RTC Backup Domain */
  RCC_RTCResetCmd(ENABLE);
  RCC_RTCResetCmd(DISABLE);

  /* LSI used as RTC source clock */
  /* The RTC Clock may varies due to LSI frequency dispersion. */
  /* Enable the LSI OSC */
  RCC_LSICmd(ENABLE);

  /* Wait until LSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);

  /* Select the RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);

  /* Enable the RTC */
  RCC_RTCCLKCmd(ENABLE);

  /* Wait for RTC APB registers synchronisation */
  RTC_WaitForSynchro();

  // ENABLE HSE
  RCC_HSEConfig(RCC_HSE_ON);
  ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if(HSEStartUpStatus == SUCCESS)
  {
      /* 32Mhz = 8Mhz * 12 / 3 */
      RCC_PLLConfig(RCC_PLLSource_HSE, RCC_PLLMul_12, RCC_PLLDiv_3);

      /* Enable PLL */
      RCC_PLLCmd(ENABLE);

      /* Wait till PLL is ready */
      while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
      {
      }

      /* Select PLL as system clock source */
      RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

      /* Wait till PLL is used as system clock source */
      while(RCC_GetSYSCLKSource() != 0x0C)  // 0x0C = PLL
      {
      }

      /* Enable the PWR clock */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
      PWR->CR = PWR_CR_VOS_0;                /* Select the Voltage Range 1 (1.8V) */
      while((PWR->CSR & PWR_CSR_VOSF) != 0); /* Wait for Voltage Regulator Ready  */

      /* HCLK = SYSCLK */
      RCC_HCLKConfig(RCC_SYSCLK_Div1);

      /* PCLK1 = HCLK/2 */
      RCC_PCLK1Config(RCC_HCLK_Div2);

      /* PCLK2 = HCLK */
      RCC_PCLK2Config(RCC_HCLK_Div1);

      /* Enable the GPIOs clocks */
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC| RCC_AHBPeriph_GPIOD| RCC_AHBPeriph_GPIOE| RCC_AHBPeriph_GPIOH, ENABLE);
      /* Enable comparator, LCD and PWR mngt clocks */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP | RCC_APB1Periph_LCD | RCC_APB1Periph_PWR,ENABLE);
  }

  return 0;

}

我使用STDperiph来配置UART1,这个单片机将在PCLK2上运行。检查所有init方法和寄存器内容。正确计算波特率寄存器的尾数和分数,无论PCLK值如何,都应该得到正确的波特率。

这是UART init代码:

代码语言:javascript
复制
void usartinit(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

USART_InitStructure.USART_BaudRate = 115200 ;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

/* Enable GPIO clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

GPIO_PinAFConfig(USARTx_GPIO, GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(USARTx_GPIO, GPIO_PinSource10, GPIO_AF_USART1);

/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = USARTx_TX;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(USARTx_GPIO, &GPIO_InitStructure);

/* Configure USART Rx as input floating */
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 configuration */
USART_Init(USART1, &USART_InitStructure);

/* Enable USART */
USART_Cmd(USART1, ENABLE);
}

我现在唯一能想到的可能性是,晶体只有4 MHz,但这是一个核板,附件STLink中的MCO用于HSE,这绝对是8 MHz。

我犯了什么大错特错?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-08-17 12:23:00

好吧,终于弄明白了。在默认配置的核心板上,HSE时钟连接到板上的STLink程序员的MCO时钟输出。然而,在我的多个板上,这个时钟信号被扭曲得很厉害,以至于目标uC只看到4 MHz。如果我在目标的MCO上输出HSE,它会产生一个4 MHz的方波,其奇异的占空比为75%。在用范围探测MCO输入信号时,探针电容足以产生正确的8 MHz输入。

所以我想我不相信你的评估板..。现在将得到一些水晶,并填充“真正的”外部时钟在这些板上。

票数 1
EN

Stack Overflow用户

发布于 2018-08-14 10:26:06

好像钟坏了。检查代码中的HSE_VALUE宏。它可能使用默认的Dev板水晶值。我建议把这个值改为你正在使用的晶体。您可以使用链接来设置时钟速度。

票数 1
EN

Stack Overflow用户

发布于 2018-08-16 14:20:54

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

我怀疑HSE值被设置为16 set。

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

HSE值将在启动代码中的某个位置。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51826283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档