串口通信 HAL库+cubeMX

一.通信的基本概念

1.串行通信和并行通信

串口通信 HAL库+cubeMX_第1张图片串口通信 HAL库+cubeMX_第2张图片

2.全双工、半双工和单工 

串口通信 HAL库+cubeMX_第3张图片

3.针对串行通信的同步通信和异步通信 

串口通信 HAL库+cubeMX_第4张图片 4.通信速率

串口通信 HAL库+cubeMX_第5张图片

二.UART配置

UART常用HAL库函数 

串口通信 HAL库+cubeMX_第6张图片

//UART_HandleTypeDef *huart是句柄

typedef struct
{
     //初始化看前面两个就可以了
     USART_TypeDef *Instance; /* UART 寄存器基地址 */
     UART_InitTypeDef Init; /* UART 通信参数 */

     uint8_t *pTxBuffPtr; /* 指向 UART 发送缓冲区 */
     uint16_t TxXferSize; /* UART 发送数据的大小 */
     __IO uint16_t TxXferCount; /* UART 发送数据的个数 */
     uint8_t *pRxBuffPtr; /* 指向 UART 接收缓冲区 */
     uint16_t RxXferSize; /* UART 接收数据大小 */
     __IO uint16_t RxXferCount; /* UART 接收数据的个数 */
     DMA_HandleTypeDef *hdmatx; /* UART 发送参数设置(DMA) */
     DMA_HandleTypeDef *hdmarx; /* UART 接收参数设置(DMA) */
     HAL_LockTypeDef Lock; /* 锁定对象 */
     __IO HAL_UART_StateTypeDef gState; /* UART 发送状态结构体 */
     __IO HAL_UART_StateTypeDef RxState; /* UART 接收状态结构体 */
     __IO uint32_t ErrorCode; /* UART 操作错误信息 */
}UART_HandleTypeDef;


typedef struct
{
     uint32_t BaudRate; /* 波特率 */
     uint32_t WordLength; /* 字长 */
     uint32_t StopBits; /* 停止位 */
     uint32_t Parity; /* 校验位 */
     uint32_t Mode; /* UART 模式 */
     uint32_t HwFlowCtl; /* 硬件流设置 */
     uint32_t OverSampling; /* 过采样设置 */
}UART_InitTypeDef;


typedef enum
{
  HAL_OK       = 0x00U,//初始化完成
  HAL_ERROR    = 0x01U,//初始化错误
  HAL_BUSY     = 0x02U,//忙
  HAL_TIMEOUT  = 0x03U //超时
} HAL_StatusTypeDef;

HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);//用于开启以中断(干完了跟我说,中途可以干其他事情)的方式接收指定字节。数据接收在中断处理函数里面实现。

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);//用阻塞(干不完不准出来)的方式发送指定字节数据

void HAL_UART_MspInit(UART_HandleTypeDef *huart)  /* 串口MSP回调函数 */

HAL库对USART的初始化流程 

串口通信 HAL库+cubeMX_第7张图片

uint8_t g_rx_buffer[1];          /* HAL库使用的串口接收数据缓冲区 */
uint8_t g_usart1_rx_flag = 0;    /* 串口接收到数据标志 */

UART_HandleTypeDef g_uart1_handle;  /* UART句柄 */

/* 串口1初始化函数 */
void usart_init(uint32_t baudrate)
{
    g_uart1_handle.Instance = USART1;
    g_uart1_handle.Init.BaudRate = baudrate;
    g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B;
    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_Receive_IT(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1);
}

/* 串口MSP回调函数 HAL_UART_MspInit 函数来完成对串口底层的初始化,包括:串口
及 GPIO 时钟使能、GPIO 模式设置、中断设置等。 */
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    GPIO_InitTypeDef gpio_init_struct;
    if(huart->Instance == USART1)                /* 如果是串口1,进行串口1 MSP初始化 */
    {
        __HAL_RCC_USART1_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();

        gpio_init_struct.Pin = GPIO_PIN_9;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;            /* 推挽式复用输出 */
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;      /* 高速 */
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);            /* 初始化串口1的TX引脚 */
        
        gpio_init_struct.Pin = GPIO_PIN_10;
        gpio_init_struct.Mode = GPIO_MODE_AF_INPUT;         /* 输入 */
        gpio_init_struct.Pull = GPIO_PULLUP;                /* 上拉 */
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);            /* 初始化串口1的RX引脚 */
        
        HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);
        HAL_NVIC_EnableIRQ(USART1_IRQn);
    }
}

/* 串口1中断服务函数 */
void USART1_IRQHandler(void)
{
    HAL_UART_IRQHandler(&g_uart1_handle);//这个函数会清除中断
    HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1);//重新使能
}

/* 串口数据接收完成回调函数 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
        g_usart1_rx_flag = 1;
    }
}
int main(void)
{
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    led_init();                                 /* 初始化LED */
    usart_init(115200);                         /* 波特率设为115200 */
    
    printf("请输入一个英文字符:\r\n\r\n");
    while(1)
    {
        if(g_usart1_rx_flag == 1)//判断串口接收到数据标志
        {
            printf("您输入的字符为:\r\n");
            HAL_UART_Transmit(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1, 1000);
            while(__HAL_UART_GET_FLAG(&g_uart1_handle, UART_FLAG_TC) != 1);
            printf("\r\n");
            g_usart1_rx_flag = 0;
        }
        else
        {
            delay_ms(10);
        }
    }
}

三.cubeMX配置USART

Asynchronous   异步                                                                                                              Synchronous 同步                                                                                                                     single wire 单线                                                                                                                            IrDA 红外数据传输

串口通信 HAL库+cubeMX_第8张图片

参数配置

串口通信 HAL库+cubeMX_第9张图片

使能和配置中断 串口通信 HAL库+cubeMX_第10张图片

串口通信 HAL库+cubeMX_第11张图片

HAL_UART_Transmit();串口发送数据,使用超时管理机制 
HAL_UART_Receive();串口接收数据,使用超时管理机制
HAL_UART_Transmit_IT();串口中断模式发送  
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送
HAL_UART_Transmit_DMA();串口DMA模式接收

发送数据是主观上的,所以用HAL_UART_Transmit();,接收数据是被动的,一般利用中断完成接收。

//stm32f1xx_it.c里面有中断服务函数的代码(可以配置各部分的中断服务函数)
uint8_t StaMessages[] = "Please enter 10 characters:\r\n";
uint8_t RxBuffer[20];
 
int main(void)
{
  /*其余代码省略*/
    MX_GPIO_Init();
    MX_USART1_UART_Init();
 
    HAL_UART_Transmit_IT(&huart1 ,(uint8_t*)StaMessages,sizeof(StaMessages));
    //发送完成产生中断,执行中断回调
    HAL_UART_Receive_IT(&huart1,(uint8_t*)RxBuffer,10);
    while(1){}
}
 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    UNUSED(huart);
    HAL_UART_Transmit(&huart1,(uint8_t*)RxBuffer,10,0xFFFF);
    HAL_UART_Receive_IT(&huart1,(uint8_t*)RxBuffer,10);//重新使能
}

四.制定协议

串口通信 HAL库+cubeMX_第12张图片

 

你可能感兴趣的:(HAL库+CubeMX,网络,单片机,c语言)