STM32 HAL庫 UART

HAL庫

HAL庫的使用節省了開發時間,省去了繁瑣的芯片初始化流程,並且每個文件都有詳細的功能說明,整合了不少代碼。HAL庫使用雖然簡便,但實際上讓開發沒能得心應手,瞭解庫函數的使用,只是能讓程序能用,但並不一定好用,真正的開發還得需要去了解每一個庫函數的代碼。提供給用戶最多的就是回調函數,可能還要去了解什麼情況下才會回調。

HAL庫 UART

本文HAL庫基於芯片STM32L0中使用,在庫中提供了stm32l0xx_hal_uart.c與stm32l0xx_hal_usart.c,在這裏說明一下這兩個文件的使用,比如USART1是同步異步收發器,一般情況下都是使用stm32l0xx_hal_uart.c,而這兩個文件使用哪一個是由設備收發類型決定,常用設備都是異步收發。
在HAL_UART_Init(UART_HandleTypeDef *huart)初始化後,需要調用HAL_UART_Receive_IT開啓接收中斷功能(UART中斷優先級設置以及具體初始化請讀者自行配置)。

/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* Enable the UART Parity Error and Data Register not empty Interrupts */
SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);

UART在接收中斷完成時會關閉接收中斷,如需重新開啓接收中斷還需再調用HAL_UART_Receive_IT。可在回調函數中進行開啓:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
 int index;

 if(USART1 == huart->Instance) index = UART1_INDEX;
 else if (USART1 == huart->Instance) index = UART2_INDEX;
 else return;

 uart_rbuf[index][g_rx_inidx[index]] = UartRxval[index];
 g_rx_inidx[index] = (g_rx_inidx[index] + 1) % uart_rbuf_max[index];
 HAL_UART_Receive_IT(huart, &UartRxval[index], 1);
}

UART接收中斷數據保存在接收緩衝區,應用層根據接收索引取數據,應用層接收處理:

int bsp_uart_recv(uart_index_t index, uint8_t *buf, int maxlen)
{
 int i = 0;
 if(index >= UART_MAX_INDEX) return -1;
 if(maxlen > uart_rbuf_max[index]) return -1;
 
 while(g_rx_inidx[index] != g_rx_rdidx[index]){
  buf[i++]=uart_rbuf[index][g_rx_rdidx[index]];
  g_rx_rdidx[index] = (g_rx_rdidx[index] + 1) % uart_rbuf_max[index];
  if(i >= maxlen) break;
 }
  return i;
}

UART發送中斷會在中斷完成時關閉,應用層發送數據只需網底層發送緩衝區存數據,應用層發送處理:

int bsp_uart_send(uart_index_t index, const uint8_t *buf, int len)
{
 uint16_t slen;
 if(index >= UART_MAX_INDEX) return 1;
 while(len--){
  uart_tbuf[index][g_tx_sendidx[index]] = *buf++;
  g_tx_sendidx[index] = (g_tx_sendidx[index] + 1) % uart_tbuf_max[index]; 
 }
 if((0 == g_tx_status[index]) && (g_tx_sendidx[index] != g_tx_outidx[index])) {   
  g_tx_status[index] = 1; 
  if(g_tx_outidx[index] < g_tx_sendidx[index])
   slen = g_tx_sendidx[index] - g_tx_outidx[index];   
  else
   slen = uart_tbuf_max[index] - g_tx_outidx[index];
  
  HAL_UART_Transmit_IT(&Huart[index], &(uart_tbuf[index][g_tx_outidx[index]]), slen);
  g_tx_outidx[index] = (g_tx_outidx[index] + slen) % uart_tbuf_max[index];
 }
 return 0;
}

在UART發送回調函數中置位發送完成狀態,以便下次打開發送。

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
 int index;
 uint16_t slen;
 
 if(USART1 == huart->Instance) index = UART1_INDEX;
 else if (USART1 == huart->Instance) index = UART2_INDEX;
 else return;
 if(g_tx_outidx[index] == g_tx_sendidx[index]) {
  g_tx_status[index] = 0;
 } else { 
  if(g_tx_outidx[index] < g_tx_sendidx[index] 
     slen = g_tx_sendidx[index] - g_tx_outidx[index];   
  else
     slen = uart_tbuf_max[index] - g_tx_outidx[index];
  HAL_UART_Transmit_IT(huart, &(uart_tbuf[index][g_tx_outidx[index]]), slen); 
  g_tx_outidx[index] = (g_tx_outidx[index] + slen) % uart_tbuf_max[index];
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章