5

我无法在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

4

3 回答 3

4

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

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

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

  • 该器件有一个可用的通用定时器外设,可以映射到与 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 外设功能。

于 2016-01-25T16:51:52.580 回答
3

由于您使用的是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 参考手册

这些模式是:

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

  • 模式 1:任何以 10xx 位模式开头的字符。在这种情况下,USART 测量开始的持续时间和第一个数据位的持续时间。测量是在下降沿到下降沿进行的,以确保在信号斜率较慢的情况下获得更好的精度。

  • 模式 2:一个 0x7F 字符帧(它可能是 LSB 优先模式中的 0x7F 字符或 MSB 优先模式中的 0xFE)。在这种情况下,波特率首先在起始位 (BR) 的末尾更新,然后在位 6 的末尾更新(基于从下降沿到下降沿进行的测量:BR6)。位 0 到位 6 在 BR 处采样,而字符的其他位在 BR6 处采样。

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

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

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

于 2016-01-23T12:10:29.127 回答
2

来自数据表(这个,第 759 页)。“在激活自动波特率检测之前,必须选择自动波特率检测模式”。--> 尝试将您的线路切换为:

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);。但值得一试。您也可以检查您的时钟源频率。

于 2016-01-19T11:23:03.113 回答