32单片机串口异步通信HAL库开发步骤

一 配置串口工作参数

HAL_UART_Init()

此函数初始化时需要传入形参,形参为用户定义的句柄,对句柄结构体成员设置之后作为形参传入HAL库串口初始化函数即可完成配置串口工作参数过程。

句柄中需要设置的成员主要如下

①寄存器基地址    USART_TypeDef     *Instance

②异步通信参数   UART_InitTypeDef    Init

主要有波特率,字长,停止位,校检位,UART模式

代码示例如下:


UART_HandleTypeDef g_uart1_handle;                                   /* UART句柄 */

void usart_init(uint32_t baudrate)
{
    /*UART 初始化设置*/
    g_uart1_handle.Instance = USART1;                                
    g_uart1_handle.Init.BaudRate = baudrate;                         /* 波特率 */
    g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B;             /* 字长为8位数据格式 */
    g_uart1_handle.Init.StopBits = UART_STOPBITS_1;                  /* 一个停止位 */
    g_uart1_handle.Init.Parity = UART_PARITY_NONE;                   /* 无奇偶校验位 */
    g_uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;             /* 无硬件流控 */
    g_uart1_handle.Init.Mode = UART_MODE_TX_RX;                      /* 收发模式 */
    HAL_UART_Init(&g_uart1_handle); 
}                    

二 串口底层初始化

HAL_UART_Msplnit()

此函数为串口的MSP回调函数,用于配置串口所用到的外设硬件包括GPIO,中断,时钟。

首先此函数形参依然定义为一个串口句柄UART_HandleTypeDef *xxx,之后对传入形参进行判断是否传入的形参为所用串口基地址,如果是接下来按照如下步骤

①使能串口与所对应IO口时钟

②初始化IO口

③使能串口中断,设置优先级

代码示例如下:

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    GPIO_InitTypeDef gpio_init_struct;

    if (huart->Instance == USART_UX)                   /* 如果是串口1,进行串口1 MSP初始化 */
    {
        USART_TX_GPIO_CLK_ENABLE();                             /* 使能串口TX脚时钟 */
        USART_RX_GPIO_CLK_ENABLE();                             /* 使能串口RX脚时钟 */
        USART_UX_CLK_ENABLE();                                  /* 使能串口时钟 */

        gpio_init_struct.Pin = USART_TX_GPIO_PIN;               /* 串口发送引脚号 */
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;                /* 复用推挽输出 */
        gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* IO速度设置为高速 */
        HAL_GPIO_Init(USART_TX_GPIO_PORT, &gpio_init_struct);
                
        gpio_init_struct.Pin = USART_RX_GPIO_PIN;               /* 串口RX脚 模式设置 */
        gpio_init_struct.Mode = GPIO_MODE_AF_INPUT;    
        HAL_GPIO_Init(USART_RX_GPIO_PORT, &gpio_init_struct);   /* 串口RX脚 必须设置成输入模式 */
        
#if     USART_EN_RX                                             /*已宏定义为真*/
        HAL_NVIC_EnableIRQ(USART_UX_IRQn);                      /* 使能USART1中断通道 */
        HAL_NVIC_SetPriority(USART_UX_IRQn, 3, 3);/* 组2,最低优先级:抢占优先级3,子优先级3 */
#endif
    }
}

三 开启串口异步接收中断

HAL_UART_Receive_IT()

此函数放在串口初始化函数当中,作用是以中断方式接收指定字节数据

含有三个参数

①用户定义句柄

②接收数据缓冲区        需要另外定义缓冲区,以发送一个字节示例定义:      char g_rx_buffer[1] 

另外需要对类型进行强制转换为函数形参要求类型

③要接收的数据大小

代码示例如下:

 HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, 1)

四 设置优先级,使能中断

HAL_NVIC_SetPriority()

HAL_NVIC_EnableIRQ()

已在串口底层初始化函数中完成编写

五 编写中断服务函数

USARTx_IRQHandler()/UARTx_IRQHandler

首先中断服务函数中调用HAL库中断共用处理函数  HAL_UART_IRQHandler(),形参为之前用户定义句柄。此函数会失能中断需要再次使能中断,即开启串口异步接收中断。下一步,调用中断回调函数,重新定义此函数。

HAL_UART_RxCpltCallback()   形参为句柄,接收完成回调函数

若用到多个串口需要判断是否为所需要串口接收到数据,另外定义接收到数据的标志,通过查询该标志来确定是否完成了数据的接收。

代码示例如下:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART_UX)                    /* 如果是串口1 */
    {
        if ((g_usart_rx_sta & 0x8000) == 0)             /* 接收未完成 */
        {
            if (g_usart_rx_sta & 0x4000)                /* 接收到了0x0d(即回车键) */
            {
                if (g_rx_buffer[0] != 0x0a)             /* 接收到的不是0x0a(即不是换行键) */
                {
                    g_usart_rx_sta = 0;                 /* 接收错误,重新开始 */
                }
                else                                    /* 接收到的是0x0a(即换行键) */
                {
                    g_usart_rx_sta |= 0x8000;           /* 接收完成了 */
                }
            }
            else                                        /* 还没收到0X0d(即回车键) */
            {
                if (g_rx_buffer[0] == 0x0d)
                    g_usart_rx_sta |= 0x4000;
                else
                {
                    g_usart_rx_buf[g_usart_rx_sta & 0X3FFF] = g_rx_buffer[0];
                    g_usart_rx_sta++;

                    if (g_usart_rx_sta > (USART_REC_LEN - 1))
                    {
                        g_usart_rx_sta = 0;             /* 接收数据错误,重新开始接收 */
                    }
                }
            }
        }

        HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
    }
}

六 串口数据发送

HAL_UART_Transmit()

在主函数中编写串口数据发送,首先判断接收数据标志位,如果确定接受则进行数据的发送。

此函数有4个形参

①用户定义句柄

②要发送的数据地址            即定义的缓冲区

③要发送的数据大小

④设置发送时间

接着等待发送完成,利用函数__HAL_UART_GET_FLAG()

此函数有两个形参

①用户定义句柄

②获取SR寄存器TC位状态若为1则发送完成

最后将接收标志复原

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值