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];
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章