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];
}