środa, 26 maja 2021

STM32 - H723ZG - LPUART

W tym poście chciałbym opisać sposób interfejs LPUART (ang. Low power UART). Został on umieszczony w nowszych mikrokontrolerach jak np. H7, G0, L4.

[Źródło: https://www.st.com/en/evaluation-tools/nucleo-h723zg.html]

LPUART jest właściwie taki sam jak zwykły UART. Główna różnica polega na większej możliwość wyboru źródła taktowania interfejsu oraz ograniczeniu funkcjonalności.

Poniżej lista różnic pomiędzy zwykłym interfejsem a interfejsem niskoprądowym:

[Źródło: AN4635]

Jednym z ciekawszych możliwości interfejsu jest możliwość pracy z zegarem LSE (32,768kHz) przy prędkości transmisji 9600. Ta prędkość pozwala uzyskać bardzo niskie zużycie prądu połączone z małą szansą na wystąpienie błędów transmisji. Przydatne dla rozwiązań wykorzystujących zasilanie bateryjne.

W przypadku taktowania LPUART z zegara LSE lub HSI, możliwe jest wybudzenie mikrokontrolera trybów oszczędzania energii (Stop oraz Sleep mode).

Źródłem wybudzenia mogą być np. odczytanie przerwanie, wykrycie bitu startowego.

Konfiguracja w CubeMx:


Ustawienie w CubeMx jest dosyć proste. Najważniejszym elementem jest ustawienie odpowiedniej wartości zegara:


Możliwe wybory sposobu działania układu:


Ustawienia do wyboru:


Prędkość transmisji jest bardzo elastyczna i zależy oczywiście od rodzaju zegara jaki zostanie wybrany. 

CubeMx dosyć dobrze pozwala na określenie poprawnego źródła zegara oraz dobranie do niego prędkości transmisji.

Przykładowy program:


Po przygotowaniu programu przez CubeMx zostaje wygenerowana następująca funkcja inicjalizacyjna:

  1. static void MX_LPUART1_UART_Init(void)
  2. {
  3.   /* USER CODE BEGIN LPUART1_Init 0 */
  4.   /* USER CODE END LPUART1_Init 0 */
  5.   /* USER CODE BEGIN LPUART1_Init 1 */
  6.   /* USER CODE END LPUART1_Init 1 */
  7.   hlpuart1.Instance = LPUART1;
  8.   hlpuart1.Init.BaudRate = 9600;
  9.   hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
  10.   hlpuart1.Init.StopBits = UART_STOPBITS_1;
  11.   hlpuart1.Init.Parity = UART_PARITY_NONE;
  12.   hlpuart1.Init.Mode = UART_MODE_TX_RX;
  13.   hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  14.   hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  15.   hlpuart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  16.   hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  17.   hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;
  18.   if (HAL_UART_Init(&hlpuart1) != HAL_OK) { Error_Handler(); }
  19.   if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); }
  20.   if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); }
  21.   if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK) { Error_Handler(); }
  22.   /* USER CODE BEGIN LPUART1_Init 2 */
  23.   /* USER CODE END LPUART1_Init 2 */
  24. }

Co jest identyczne z procedurą inicjalizacji zwykłego układu UART. Ponieważ oba układy są obsługiwane z struktury UART_HandleTypeDef.

Wybranie źródła taktującego LPUART jest umieszczone w funkcji SystemClock_Config:

  1. PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_LSE;

Dane można przesłać w standardowy sposób:

  1. void LPUART_SendString(char* strPtr)
  2. {
  3.     HAL_UART_Transmit(&hlpuart1, (uint8_t*)strPtr, strlen(strPtr), 1000);
  4. }

Oczywiście największą korzyścią tego układu jest możliwość wybudzenia go ze stanu uśpienia.

W przypadku braku otrzymanej wiadomości należy sprawdzić podłączenie przewodów RX oraz TX. Jeśli jest ono poprawne to należy zweryfikować poprawność wprowadzonej prędkości transmisji do ustawionej prędkości zegara. 

Źródła: