STM32L0的自动波特率检测

Fly*_*man 5 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);


}
Run Code Online (Sandbox Code Playgroud)

我通过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   __________
   ¦______¦
...
Run Code Online (Sandbox Code Playgroud)

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

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);
    }
  }
Run Code Online (Sandbox Code Playgroud)

  /* 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);
  }
Run Code Online (Sandbox Code Playgroud)

不做任何事.

以下似乎很好:

时钟源频率必须与预期的通信速度兼容(当过采样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
Run Code Online (Sandbox Code Playgroud)

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

sif*_*man 4

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

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

  • 在接收多个字符的任意间隔期间,可以假设位序列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
Run Code Online (Sandbox Code Playgroud)

您可以将计时器设置为输入捕捉模式,并让它计算两个相邻边沿转换之间的时钟数。对相对较多的样本(例如 100)执行此操作。其中许多样本将表示两个或多个相邻零或两个或多个相邻零的宽度。但您正在寻找最短的样本。如果您发现一个计数值在 831 到 835 之间,那么您可以合理地确信波特率为 19200。在 100 个样本之后,如果您发现的最短计数值在 1665 到 1669 之间,那么您可以假设波特率为9600。以此类推。

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