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];
}
以下是STM32 HAL库UART中断形式发送的示例代码: ``` #include "stm32f4xx_hal.h" /* UART_HandleTypeDef结构体定义 */ UART_HandleTypeDef huart2; /* 用于存储UART接收数据的缓冲区 */ uint8_t rxBuffer[10]; /* 定义要发送的数据 */ uint8_t txData[] = "Hello, world!\r\n"; int main(void) { /* 初始化HAL库 */ HAL_Init(); /* 初始化UART2 */ __HAL_RCC_USART2_CLK_ENABLE(); huart2.Instance = USART2; huart2.Init.BaudRate = 9600; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart2); /* 开启UART2接收中断 */ HAL_UART_Receive_IT(&huart2, rxBuffer, 10); while (1) { /* 发送数据 */ HAL_UART_Transmit_IT(&huart2, txData, sizeof(txData)); /* 等待发送完成 */ while (huart2.gState != HAL_UART_STATE_READY) {} /* 延时 */ HAL_Delay(1000); } } /* UART接收中断处理函数 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { /* 处理接收到的数据 */ /* ... */ /* 继续开启接收中断 */ HAL_UART_Receive_IT(&huart2, rxBuffer, 10); } /* UART发送中断处理函数 */ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { /* 发送完成 */ } ``` 在上述代码中,使用`HAL_UART_Init`函数初始化UART2,然后使用`HAL_UART_Receive_IT`函数开启UART2接收中断,并指定接收缓冲区和缓冲区长度。 在主循环中,使用`HAL_UART_Transmit_IT`函数发送数据,并在发送完成后等待,直到UART处于就绪状态。 当接收到数据时,将调用`HAL_UART_RxCpltCallback`函数,以处理接收到的数据,并使用`HAL_UART_Receive_IT`函数继续开启接收中断。 当发送完成时,将调用`HAL_UART_TxCpltCallback`函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值