简体   繁体   English

STM32L0的自动波特率检测

[英]Auto baud rate detect for STM32L0

I can't get auto-baud rate detection to work on the STM32L0 . 我无法在STM32L0上进行自动波特率检测。 I'm using the hardware abstraction layer (HAL). 我正在使用硬件抽象层(HAL)。

My initilization code is: 我的初始化代码是:

/* 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);


}

The bytes I'm sending over the UART1 is : 我通过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   __________
   ¦______¦
...

Why is the baudrate not being detected? 为什么没有检测到波特率? I've tried: 我试过了:

UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT and UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBITUART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE

So I adjusted the chronology of mode setting and the enabling in the driver from: 所以我调整了模式设置的时间顺序和驱动程序中的启用:

  /* 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);
    }
  }

to

  /* 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);
  }

Doesn't do anyhing. 不做任何事。

Also the following seems fine: 以下似乎很好:

The clock source frequency must be compatible with the expected communication speed (when oversampling by 16, the baud rate is between fCK/65535 and fCK/16. when oversampling by 8, the baudrate is between fCK/65535 and fCK/8). 时钟源频率必须与预期的通信速度兼容(当过采样16时,波特率在fCK / 65535和fCK / 16之间。当过采样8时,波特率在fCK / 65535和fCK / 8之间)。

I'm oversampling by 16, so 我是16岁的过采样,所以

fCK= 16000000

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

My Baudrate of choice are : 19200/ 9600 /2400 /300 我选择的波特率是: 19200/ 9600 /2400 /300

If you are unable to specify the precise contents of a single byte to be examined by the STM32L0's auto baud rate detection hardware, you might still be able to "roll your own" auto baud rate detection scheme, if the following assumptions can be made for your system: 如果您无法指定STM32L0的自动波特率检测硬件要检查的单个字节的精确内容,如果可以进行以下假设,您仍可以“自行设置”自动波特率检测方案。你的系统:

  • It is permissible to discard an arbitrary number of contiguous received characters during the auto baud detection process. 在自动波特率检测过程中,允许丢弃任意数量的连续接收字符。

  • During any arbitrary interval where multiple characters are being received, it can be assumed that the bit sequence 010 or 101 is a relatively common occurrence. 在接收多个字符的任意间隔期间,可以假设比特序列010101是相对常见的事件。

  • The device has an available General Purpose Timer peripheral that can be mapped to the same device pin as the USART Rx signal. 该器件具有可用的通用定时器外设,可以映射到与USART Rx信号相同的器件引脚。

If all of the above are true, then you can create your own auto baud rate detection scheme by using the Input Capture feature of one of the General Purpose Timer peripherals on the chip. 如果满足以上所有条件,则可以使用芯片上某个通用定时器外设的输入捕捉功能创建自己的自动波特率检测方案。 These timers can be configured to use the internal 16 MHz clock as their clock source. 这些定时器可配置为使用内部16 MHz时钟作为其时钟源。 Each timer contains a 16-bit counter. 每个定时器都包含一个16位计数器。 With a 16 MHz clock, the timer has a (1/16,000,000 Hz) = 62.5 nS pulse measurement resolution. 使用16 MHz时钟,定时器具有(1 / 16,000,000 Hz)= 62.5 nS脉冲测量分辨率。

The duration of a single bit at your preferred baud rates is as follows: 首选波特率的单个位的持续时间如下:

 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

You would set up the timer in Input Capture mode, and have it count the number of clocks between two adjacent edge transitions. 您可以在输入捕捉模式下设置定时器,并计算两个相邻边沿过渡之间的时钟数。 Perform this operation for a relatively high number of samples, say 100. Many of those samples will represent the width of two or more adjacent zeroes, or two or more adjacent ones. 对相对大量的样本(例如100)执行此操作。这些样本中的许多将表示两个或更多个相邻零的宽度,或者两个或更多个相邻零的宽度。 But you're looking for the shortest sample. 但是你正在寻找最短的样本。 If you find one that is between 831 and 835 counts, then you can be reasonably confident that the baud rate is 19200. After 100 samples, if the shortest one you found was between 1665 and 1669 counts, then you can assume the baud rate is 9600. And so on. 如果您发现一个介于831和835之间的数,那么您可以合理地确信波特率是19200.在100个样本之后,如果找到的最短的一个是1665到1669之间的数,那么您可以假设波特率是9600.依此类推。

During this process, the USART is disabled while the Timer is assigned to the pin. 在此过程中,在将定时器分配给引脚时禁用USART。 After determining the right baud rate to use, re-configure the pin to assign it to the USART Rx peripheral function. 确定要使用的正确波特率后,重新配置该引脚以将其分配给USART Rx外设功能。

From the datasheet ( This one , page 759). 从数据表( 这一页,第759页)。 "Before activating the auto baud rate detection, the auto baud rate detection mode must be chosen" . “在激活自动波特率检测之前,必须选择自动波特率检测模式” --> Try switching your lines to: - >尝试将您的行切换为:

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

I don't think it will make a big difference as you start the init process with HAL_UART_Init(&huart1); 当你用HAL_UART_Init(&huart1);启动init进程时,我认为它不会产生很大的不同HAL_UART_Init(&huart1); anyways. 无论如何。 But it's worth a try. 但值得一试。 You can check your clock source frequency also. 您也可以检查您的时钟源频率。

Since you are using ABRMOD[1:0] = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT (auto baud rate Mode 0), the very first character received after initialization must have a high MSB in order for the auto baud mechanism to work properly. 由于您使用的是ABRMOD[1:0] = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT (自动波特率模式0),因此初始化后收到的第一个字符必须具有高MSB才能使自动波特率机制正常工作。 But you say that your sequence of data bytes is 但是你说你的数据字节序列是

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

The first byte in this sequence is 0x68 , which has a low MSB. 该序列中的第一个字节是0x68 ,具有低MSB。 Therefore, the auto baud detection hardware will write an incorrect value to the BRR. 因此,自动波特率检测硬件将向BRR写入不正确的值。 Change your first byte to have a high MSB, and this should solve your problem. 将您的第一个字节更改为具有高MSB,这应该可以解决您的问题。


Edit 编辑

The STM32L0 has 4 auto baud rate detection modes, allowing you to specify different characteristics of the byte that is measured. STM32L0具有4种自动波特率检测模式,允许您指定测量字节的不同特性。 From the RM0367 Reference manual : RM0367参考手册

These modes are: 这些模式是:

  • Mode 0: Any character starting with a bit at 1. In this case the USART measures the duration of the Start bit (falling edge to rising edge). 模式0:任何以1位开头的字符。在这种情况下,USART测量起始位的持续时间(下降沿到上升沿)。

  • Mode 1: Any character starting with a 10xx bit pattern. 模式1:任何以10xx位模式开头的字符。 In this case, the USART measures the duration of the Start and of the 1st data bit. 在这种情况下,USART测量Start和第1个数据位的持续时间。 The measurement is done falling edge to falling edge, ensuring better accuracy in the case of slow signal slopes. 测量在下降沿到下降沿完成,确保在信号斜率缓慢的情况下具有更好的精度。

  • Mode 2: A 0x7F character frame (it may be a 0x7F character in LSB first mode or a 0xFE in MSB first mode). 模式2:0x7F字符帧(在LSB优先模式下可以是0x7F字符,在MSB优先模式下可以是0xFE)。 In this case, the baudrate is updated first at the end of the start bit (BRs), then at the end of bit 6 (based on the measurement done from falling edge to falling edge: BR6). 在这种情况下,波特率首先在起始位(BRs)结束时更新,然后在第6位结束时更新(基于从下降沿到下降沿的测量:BR6)。 Bit 0 to bit 6 are sampled at BRs while further bits of the character are sampled at BR6. 在BR处对位0到位6进行采样,而在BR6处对字符的其他位进行采样。

  • Mode 3: A 0x55 character frame. 模式3:0x55字符帧。 In this case, the baudrate is updated first at the end of the start bit (BRs), then at the end of bit 0 (based on the measurement done from falling edge to falling edge: BR0), and finally at the end of bit 6 (BR6). 在这种情况下,波特率首先在起始位(BRs)结束时更新,然后在位0结束时更新(基于从下降沿到下降沿的测量:BR0),最后在位结束时更新6(BR6)。 Bit 0 is sampled at BRs, bit 1 to bit 6 are sampled at BR0, and further bits of the character are sampled at BR6. 在BR处对位0进行采样,在BR0处对位1至位6进行采样,并且在BR6处对该字符的其他位进行采样。 In parallel, another check is performed for each intermediate transition of RX line. 并行地,对RX线的每个中间转换执行另一检查。 An error is generated if the transitions on RX are not sufficiently synchronized with the receiver (the receiver being based on the baud rate calculated on bit 0). 如果RX上的转换与接收器没有充分同步(接收器基于在位0上计算的波特率),则会产生错误。

If you can't ensure that the first byte received after enabling auto baud detection fits one of the above modes, then I'm afraid the built-in auto baud detection feature won't work for you. 如果您无法确保启用自动波特率检测后收到的第一个字节符合上述模式之一,那么我担心内置的自动波特率检测功能对您不起作用。

All may not be lost, though. 但是,一切都可能不会丢失。 See my second answer to your question. 请参阅我对您问题的第二个答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM