簡體   English   中英

STM32L0的自動波特率檢測

[英]Auto baud rate detect for STM32L0

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

如果您無法指定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

您可以在輸入捕捉模式下設置定時器,並計算兩個相鄰邊沿過渡之間的時鍾數。 對相對大量的樣本(例如100)執行此操作。這些樣本中的許多將表示兩個或更多個相鄰零的寬度,或者兩個或更多個相鄰零的寬度。 但是你正在尋找最短的樣本。 如果您發現一個介於831和835之間的數,那么您可以合理地確信波特率是19200.在100個樣本之后,如果找到的最短的一個是1665到1669之間的數,那么您可以假設波特率是9600.依此類推。

在此過程中,在將定時器分配給引腳時禁用USART。 確定要使用的正確波特率后,重新配置該引腳以將其分配給USART Rx外設功能。

從數據表( 這一頁,第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);啟動init進程時,我認為它不會產生很大的不同HAL_UART_Init(&huart1); 無論如何。 但值得一試。 您也可以檢查您的時鍾源頻率。

由於您使用的是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測量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上計算的波特率),則會產生錯誤。

如果您無法確保啟用自動波特率檢測后收到的第一個字節符合上述模式之一,那么我擔心內置的自動波特率檢測功能對您不起作用。

但是,一切都可能不會丟失。 請參閱我對您問題的第二個答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM