Auto data rate for STM32L0

I can’t get automatic transmission rate detection for working with STM32L0 . I use a hardware abstraction layer (HAL).

My initialization code:

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

Bytes that I send via 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 speed not detected? I tried:

UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT and UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE

So, I set up the chronology of setting the mode and turning it on in the driver:

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

It does nothing.

Also looks like this:

The frequency of the clock source must be compatible with the expected data rate (when oversampling at 16, the data rate is between fCK / 65535 and fCK / 16. Oversampling at 8, the exchange rate between fCK / 65535 and fCK / 8).

I am oversampling to 16, so

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

My bodrett of choice: 19200/9600/2400/300

+5
source share
3 answers

If you cannot specify the exact contents of a single byte that should be checked by the STM32L0 automatic baud detection hardware, you can still “spin up your own” automatic baud rate detection scheme if the following assumptions are possible for your system:

  • It is permissible to discard an arbitrary number of adjacent received symbols during the automatic baud detection process.

  • In any arbitrary interval in which several characters are received, it can be assumed that bit sequence 010 or 101 is a relatively common occurrence.

  • The device has an accessible general-purpose peripheral peripheral that can be mapped to the same device pin as the USART Rx signal.

If all of the above is true, then you can create your own scheme for automatically detecting battle speed using the Input Capture function of one of the general-purpose peripherals on the chip. These timers can be configured to use internal 16 MHz clocks as a clock source. Each timer contains a 16-bit counter. At a clock frequency of 16 MHz, the timer has a resolution of measurement of pulses (1/16 000 000 Hz) = 62.5 ns.

The duration of one bit at your preferred speeds is:

  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 the timer in Input Capture mode and count the number of hours between two adjacent edge transitions. Perform this operation for a relatively large number of patterns, say 100. Many of these patterns will represent the width of two or more adjacent zeros or two or more adjacent ones. But you are looking for the shortest sample. If you find that is between 831 and 835 accounts, then you can be sure that the transmission speed is 19200. After 100 samples, if the shortest one was between 1665 and 1669 points, then you can assume that the speed 9600 bauds. And so on.

During this process, USART is disabled when a timer is assigned to a contact. After determining the correct baud rate, reconfigure the pin to assign it to the USART Rx peripheral function.

+3
source

From the table ( This is one , p. 759). "Before activating the automatic detection of the baud rate, you must select the automatic speed registration mode." → 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 much difference since you start the init process with HAL_UART_Init(&huart1); anyway. But worth a try. You can also check the frequency of the clock source.

+2
source

Since you are using ABRMOD[1:0] = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT (automatic baud mode 0), the very first character received after initialization must have a high MSB for the automatic baud mechanism to work correctly. But you say your sequence of data bytes

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

The first byte in this sequence is 0x68 , which has a low MSB. Thus, the automatic baud detection device will write an invalid value to the BRR. Change your first byte to have a high MSB, and this should solve your problem.


Edit

STM32L0 has 4 modes for automatically detecting the transmission rate, allowing you to specify various characteristics of the byte that is being measured. From the RM0367 Reference Guide :

These modes are:

  • Mode 0: Any character starting with a bit in 1. In this case, USART measures the length of the start bit (falling edge to rising edge).

  • Mode 1: Any character starting with bit 10xx. In this case, USART measures the start time and the 1st data bit. Measurement is carried out with a falling edge to a falling edge, providing better accuracy in the case of slow signal tilts.

  • Mode 2: character frame 0x7F (it may be the character 0x7F in the first LSB mode or 0xFE in the first MSB mode). In this case, the baud rate is updated first at the end of the start bit (BR) and then at the end of bit 6 (based on the measurement taken from falling to the edge of the edge: BR6). Bit 0 — Bit 6 is sampled in BR, while the other bits of the character are taken on BR6.

  • Mode 3: Character frame 0x55. In this case, the bit rate is first updated at the end of the start bit (BR), and then at the end of bit 0 (based on the measurement taken from the falling edge to the falling edge: BR0), and finally at the end of bit 6 (BR6). Bit 0 is sampled in BR, bit 1 - bit 6 is selected in BR0, and additional bits of the character are sampled BR6. In parallel, another check is performed for each intermediate transition of the RX line. An error occurs if the transitions to RX are not sufficiently synchronized with the receiver (the receiver is based on the baud rate calculated on bit 0).

If you can’t guarantee that the first byte received after enabling automatic baud detection is suitable for one of the above modes, I’m afraid that the automatic side autobot detection function will not work for you.

All may not be lost. See my second answer to your question.

+2
source

Source: https://habr.com/ru/post/1240909/


All Articles