STM32L0的自动波特率检测

时间:2016-01-19 10:14:01

标签: c embedded stm32 baud-rate stm32ldiscovery

我无法使用STM32L0进行自动波特率检测。我正在使用硬件抽象层(HAL)。

我的初始化代码是:

/* USART1 init function */
void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 300;
  huart1.Init.WordLength = UART_WORDLENGTH_9B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_EVEN;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT;
  huart1.AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_ENABLE;
  huart1.AdvancedInit.AutoBaudRateMode = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT;
  HAL_UART_Init(&huart1);


}

我通过UART1发送的字节是:

        0   1   2   3   4   5   6   7   8   
000x    68  0B  0B  68  53  FD  52  FF  FF  .. etc.

0x68 = 0b01101000
0x0B = 0b00001011
0xFD = 0b11111101  <-- Character starting with 1, baudrate should be detected


0xFD : 
     start  1  1 .....
___  bit   __________
   ¦______¦
...

为什么没有检测到波特率?我试过了:

UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBITUART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE

所以我调整了模式设置的时间顺序和驱动程序中的启用:

  /* if required, configure auto Baud rate detection scheme */              
  if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
  {
    assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
    MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
    /* set auto Baudrate detection parameters if detection is enabled */
    if(huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
    {
      assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
      MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
    }
  }

  /* if required, configure auto Baud rate detection scheme */              
  if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
  {
    assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart-
    /* set auto Baudrate detection parameters if detection is enabled */
    if(huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
    {
      assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
      MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
    }
    MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
  }

不做任何事。

以下情况似乎还不错:

  

时钟源频率必须与预期的通信速度兼容   (当过采样16时,波特率介于fCK / 65535和fCK / 16之间   过采样8,波特率介于fCK / 65535和fCK / 8之间。

我过度采样16,所以

fCK= 16000000

fCK >  16000000 / 65535 = 244     = 244  Hz
fCK <  16000000 / 16    = 1000000 = 1   MHz

我选择的波特率是:19200/ 9600 /2400 /300

3 个答案:

答案 0 :(得分:3)

如果您无法指定STM32L0的自动波特率检测硬件要检查的单个字节的精确内容,您可能仍然可以自己滚动自己的&#34;自动波特率检测方案,如果可以为您的系统做出以下假设:

  • 允许在自动波特率检测过程中丢弃任意数量的连续接收字符。

  • 在接收多个字符的任意间隔期间,可以假设比特序列010101是相对常见的事件。

  • 该器件具有可用的通用定时器外设,可以映射到与USART Rx信号相同的器件引脚。

如果满足以上所有条件,则可以使用芯片上某个通用定时器外设的输入捕捉功能创建自己的自动波特率检测方案。这些定时器可配置为使用内部16 MHz时钟作为其时钟源。每个定时器都包含一个16位计数器。使用16 MHz时钟,定时器具有(1 / 16,000,000 Hz)= 62.5 nS脉冲测量分辨率。

首选波特率的单个位的持续时间如下:

 Baud   Microseconds   62.5-nS Clocks
 ----   ------------   --------------
  300      3,333.3         53,333
 2400        416.7          6,667  
 9600        104.2          1,667
19200         52.1            833

您可以在输入捕捉模式下设置定时器,并计算两个相邻边缘过渡之间的时钟数。对相对大量的样本(例如100)执行此操作。这些样本中的许多将表示两个或更多个相邻零的宽度,或者两个或更多个相邻零的宽度。但是您正在寻找最短的样本。如果您发现一个介于831和835之间的数,那么您可以合理地确信波特率是19200.在100个样本之后,如果找到的最短的一个是1665到1669之间的数,那么您可以假设波特率是9600.等等。

在此过程中,当定时器分配给引脚时,USART被禁止。确定要使用的正确波特率后,重新配置引脚以将其分配给USART Rx外设功能。

答案 1 :(得分:2)

从数据表(This one,第759页)。 &#34;在激活自动波特率检测之前,必须选择自动波特率检测模式&#34; 。 - &GT;尝试将您的行切换到:

huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT; huart1.AdvancedInit.AutoBaudRateMode = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT; huart1.AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_ENABLE;`

我认为,无论如何,当您使用HAL_UART_Init(&huart1);启动初始化过程时,它会产生重大影响。但值得一试。 您也可以检查您的时钟源频率。

答案 2 :(得分:2)

由于您使用ABRMOD[1:0] = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT(自动波特率模式0),初始化后收到的第一个字符必须具有高MSB才能使自动波特率机制正常工作。但是你说你的数据字节序列是

68  0B  0B  68  53  FD  52  FF  FF  .. etc.

此序列中的第一个字节为0x68,其MSB较低。因此,自动波特率检测硬件将向BRR写入不正确的值。将您的第一个字节更改为具有高MSB,这应该可以解决您的问题。

<小时/> 的修改

STM32L0具有4种自动波特率检测模式,允许您指定测量字节的不同特性。来自RM0367 Reference manual

  

这些模式是:

     
      
  • 模式0:任何以1位开头的字符。在这种情况下,USART测量起始位的持续时间(下降沿到上升沿)。

  •   
  • 模式1:任何以10xx位模式开头的字符。在这种情况下,USART测量Start和第1个数据位的持续时间。测量是在下降沿到下降沿完成的,确保在信号斜率缓慢的情况下具有更好的精度。

  •   
  • 模式2:0x7F字符帧(在LSB优先模式下可以是0x7F字符,在MSB优先模式下可以是0xFE)。在这种情况下,波特率首先在起始位(BRs)结束时更新,然后在第6位结束时更新(基于从下降沿到下降沿的测量:BR6)。在BR处对位0到位6进行采样,而在BR6处对字符的其他位进行采样。

  •   
  • 模式3:0x55字符帧。在这种情况下,波特率首先在起始位(BRs)结束时更新,然后在位0结束时更新(基于从下降沿到下降沿的测量:BR0),最后在位结束时更新6(BR6)。在BR处对位0进行采样,在BR0处对位1至位6进行采样,并且在BR6处对该字符的其他位进行采样。并行地,对RX线的每个中间转换执行另一检查。如果RX上的转换与接收器没有充分同步(接收器基于在位0上计算的波特率),则会产生错误。

  •   

如果您无法确保启用自动波特率检测后收到的第一个字节符合上述模式之一,那么我担心内置的自动波特率检测功能对您无效。

但是,一切都可能不会丢失。请参阅我对您问题的第二个答案。