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.
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:
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:
- static void MX_LPUART1_UART_Init(void)
- {
- /* USER CODE BEGIN LPUART1_Init 0 */
- /* USER CODE END LPUART1_Init 0 */
- /* USER CODE BEGIN LPUART1_Init 1 */
- /* USER CODE END LPUART1_Init 1 */
- hlpuart1.Instance = LPUART1;
- hlpuart1.Init.BaudRate = 9600;
- hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
- hlpuart1.Init.StopBits = UART_STOPBITS_1;
- hlpuart1.Init.Parity = UART_PARITY_NONE;
- hlpuart1.Init.Mode = UART_MODE_TX_RX;
- hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
- hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
- hlpuart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
- hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
- hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;
- if (HAL_UART_Init(&hlpuart1) != HAL_OK) { Error_Handler(); }
- if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); }
- if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); }
- if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK) { Error_Handler(); }
- /* USER CODE BEGIN LPUART1_Init 2 */
- /* USER CODE END LPUART1_Init 2 */
- }
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:
- PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_LSE;
Dane można przesłać w standardowy sposób:
- void LPUART_SendString(char* strPtr)
- {
- HAL_UART_Transmit(&hlpuart1, (uint8_t*)strPtr, strlen(strPtr), 1000);
- }
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.