单片机HAL库使用HAL_UART_Receive_IT

前言

由于本人第一次尝试开发单片机,要实现的功能是信息转发,需要调用HAL库方法,中断接受信息转发给FPGA,这里没有用到DMA方式所以不做赘述,特此记录分享希望帮到你们。

发送信息和中断接受流程

  • 发送

轮询等待方式发送消息Timeout超时返回,调用的这个方法发送数据发现只能发送一个字节8位的数据,发送大于一个字节数数组时会产生问题,拿示波器抓也只有第一个字节有效,其余都是错的,着实被这个浪费了很多时间,后来选择了第二种发送方式

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

中断发送消息,这个就可以发送多个字节数数组

HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

  • 接收

这里也遇到了一些问题,可能是自己经验不足,在此说明下中断接受调用流程。首先先确定你要用到的是哪个串口,我们板子上有两个串口可以接受中断信号,我初始化了两个串口,用UART0去接受UART1的信号肯定是不行的,比如你初始化的UART1口,那么中断发生的时候会调用UART1_IRQHandler,如果是UART0,那么调用UART0_IRQHandler,然后调用HAL_UART_IRQHandler --> UART_Receive_IT(huart) --> HAL_UART_RxCpltCallback(huart)。这里你只需重载UART1_IRQHandler和HAL_UART_RxCpltCallback即可,附上代码

void UART1_IRQHandler(void)
{
  /* USER CODE BEGIN UART1_IRQn 0 */
    HAL_UART_IRQHandler(&sUartxHandle);
  /* USER CODE END UART1_IRQn 0 */
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == UART1)
	{
		Do something...
	}
	else if(huart->Instance == UART0)
	{
		Do something...
	}
}

接受中断有个前提,是你必须要初始化中断,而且是每次调用完HAL_UART_RxCpltCallback以后都要重新初始化一下,用

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

注意Size设置,串口接收满这些个数以后才会触发中断,没有接收满不会触发中断,但是你仍然可以读取到pData里接受到的数据。

下面贴一些我的初始化代码

UART_HandleTypeDef sUartxHandle = {0};
static UINT8 buffer_in[5];
static UINT8 buf_count = 5;

void Init_uchar    
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOD_CLK_ENABLE()

    GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_AF;
    GPIO_InitStruct.OpenDrain = GPIO_PUSHPULL;	
    GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    GPIO_InitStruct.SlewRate = GPIO_SLEW_RATE_HIGH;
    GPIO_InitStruct.DrvStrength = GPIO_AF5_UART1_TXD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Alternate = UARTx_RX_ALTERNATE_AFn;
    HAL_GPIO_Init(UARTx_RX_PORT, &GPIO_InitStruct);
		
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF;
    GPIO_InitStruct.Alternate = GPIO_AF5_UART1_RXD;
    HAL_GPIO_Init(UARTx_TX_PORT, &GPIO_InitStruct);		
    
    /* Peripheral clock enable */
    __HAL_RCC_UART1_CLK_ENABLE()
	
    sUartxHandle.Instance = UARTx;
    sUartxHandle.Init.BaudRate = 115200;
    sUartxHandle.Init.BaudDouble = UART_BAUDDOUBLE_ENABLE;	
    sUartxHandle.Init.WordLength = UART_WORDLENGTH_8B;
    sUartxHandle.Init.Parity = UART_PARITY_NONE;
    sUartxHandle.Init.Mode = UART_MODE_TX_RX;
    HAL_UART_Init(&sUartxHandle);
    
    HAL_UART_Receive_IT(&sUartxHandle, buffer_in, buf_count);
    NVIC_EnableIRQ(UARTx_IRQn);
}

NOTE:sUartxHandle.Init.BaudDouble = UART_BAUDDOUBLE_ENABLE;    我设置的是双缓冲模式,因为我这块板子波特率要求是115200,如果设置为UART_BAUDDOUBLE_DISABLE,则在115200下接受到的数据是不对的。小于115200波特率的可以设置为UART_BAUDDOUBLE_DISABLE,设置为UART_BAUDDOUBLE_ENABLE,HAL_UART_RxCpltCallback会被触发两次注意处理。

  • 9
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值