前言
上一章节讲解了如何通过STM32CubeMx配置LED,本节课将介绍在单片机中常用的串口功能。串口是一种在单片机,传感器,执行模块等诸多设备上常用的通讯接口,在比赛中,可以通过串口读取遥控器发送来的数据,也可以通过串口读取超声波等传感器的数据,也可以使用串口在单片机和运行计算机视觉的电脑之间进行通讯。

通过本节课的学习, 将掌握如何通过 APB 时钟计算串口的波特率,串口在 cubeMX 中的配置方法,串口的接收中断与空闲中断功能,串口的发送函数与发送中断。

准备工具
软件:STM32CubeMx、Keil5 MDK、串口调试助手XCOM

硬件:STM32F103C8T6核心板、下载器ST_LINK、USB转TTL或J-LINK

本章节工程已上传至百度网盘,此链接永久有效

链接:https://pan.baidu.com/s/108QKIltQ-aZ94inuvKylGg?pwd=b8l3
提取码:b8l3

CubeMx配置
打开上一章节建立好的工程模板,配置串口通信模式为异步通信,波特率115200,开启全局中断





最后生成代码,打开工程

HAL库UART函数库介绍
1、串口发送/接收函数

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

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

功能:串口发送指定长度的数据。如果超时没发送完成,则不再发送,返回超时标志(HAL_TIMEOUT)。

参数:

UART_HandleTypeDef _huart huart句柄,如 : UART_HandleTypeDef huart1; 别名就是huart1 _pData 需要发送的数据
Size 发送的字节数
Timeout 最大发送时间,发送数据超过该时间退出发送

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

功能:串口中断接收,以中断方式接收指定长度数据。
大致过程是,设置数据存放位置,接收数据长度,然后使能串口接收中断。接收到数据时,会触发串口中断。
再然后,串口中断函数处理,直到接收到指定长度数据,而后关闭中断,进入中断接收回调函数,不再触发接收中断。(只触发一次中断)

参数:UART_HandleTypeDef _huart huart句柄,如 : UART_HandleTypeDef huart1; 别名就是huart1 _pData 接收到的数据存放地址
Size 接收的字节数

2、串口中断函数

1.HAL_UART_IRQHandler(UART_HandleTypeDef _huart); //串口中断处理函数
2.HAL_UART_TxCpltCallback(UART_HandleTypeDef _huart); //串口发送中断回调函数
3.HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef _huart); //串口发送一中断回调函数(用的较少)
4.HAL_UART_RxCpltCallback(UART_HandleTypeDef _huart); //串口接收中断回调函数
5.HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//串口接收一半回调函数(用的较少)
6.HAL_UART_ErrorCallback();串口接收错误函数

HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);

功能:HAL库的中断进行完之后,并不会直接退出,而是会进入中断回调函数中,用户可以在其中设置代码,串口中断接收完成之后,会进入该函数,该函数为空函数,用户需自行修改,

参数:UART_HandleTypeDef *huart huart句柄,如 : UART_HandleTypeDef huart1; 别名就是huart1

串口收发
函数初始化部分需添加串口接收中断开启函数

  /* USER CODE BEGIN 2 */
    UART_Start_Receive_IT(&huart1,(uint8_t *)&rec_buffer,1);
  /* USER CODE END 2 */

用户自定义串口接收是在中断回调函数中进行,所以需要在工程中添加如下代码

uint8_t rec_buffer;

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//中断回调函数
{
    UNUSED(huart);
    if(huart->Instance == USART1)//判断串口号
    {
        static uint8_t temp;
        temp = rec_buffer;

        if(temp == 0x01)
            HAL_GPIO_WritePin(LEDD_GPIO_Port, LEDD_Pin, GPIO_PIN_SET);
        else if(temp == 0x02)
            HAL_GPIO_WritePin(LEDD_GPIO_Port, LEDD_Pin, GPIO_PIN_RESET);
        HAL_UART_Transmit(&huart1,(uint8_t *)&rec_buffer,1,100); // 将接收到的数据再通过串口发送出去
        HAL_UART_Receive_IT(&huart1, (uint8_t *)&rec_buffer, 1);   //重新使能接收中断
    }
}

将串口CH340上的TXD接到主控上的PA10,RXD接到主控对应的PA9。通过XCOM发送可以0x01或0X02即可看到LED变化。

重定义printf函数
需要包含stdio.h库文件

#include "bsp_usart.h"
#include <stdio.h>

extern UART_HandleTypeDef huart1;

重定向c库函数printf

/**
  * 函数功能: 重定向c库函数printf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}

printf函数用法和c库一样,可输出字符、字符串和变量,如下图所示


通过XCOM可以通过串口发送、接收字符