STM32CubeMx使用教程(三)——串口通信、串口协议

发布于:2022-12-17 ⋅ 阅读:(398) ⋅ 点赞:(0)

前言

上一章节讲解了如何通过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;
}

重定向c库函数getchar,scanf

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

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

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

本文含有隐藏内容,请 开通VIP 后查看