通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter)是一个全双工的串行通信设备;UART(Universal Asynchronous Receiver and Transmitter)是在USART基础上裁掉了同步通信功能,只有异步通信。

USART满足外部设备对工业标准NRZ异步串行数据格式的要求,并且使用了小数波特率发生器,可以提供多种波特率。USART支持同步单向通信和半双工单线通信;还支持局域互连网络、智能卡协议与LrDA SIR ENDEC规范;还支持DMA,可实现高速数据通信。


如下图是USART功能框图,我们将对此框图进行分析。

1.功能引脚

TX:发送数据输出引脚

RX:接收数据输入引脚

SW_RX:数据接收引脚,内部引脚,只用于单线和智能卡模式

nRTS:发送请求输出端,n表示低电平有效。如果是能RTS流控制,当USART接收器准备好接收新的数据时会将nRTS编程低电平;当接收寄存器已满时,nRTS将会被设置为高电平,该引脚至适用于硬件流控制。

nCTS:请求发送输入端,n表示低电平有效。如果使能CTS流控制,发送器在发送下一帧数据之前会检测nCTS引脚,如果为低电平则发送数据,如果为高电平则在发送完当前数据之后停止发送,该引脚只适用于硬件流控制。

SCLK:发送器时钟输出引脚,仅适用于同步模式。

注意:UART只有异步传输功能,故没有SCLK、nRTS和nCTS引脚。

2.数据寄存器

USART数据寄存器(USART_DR)包含TDR和RDR,两者是介于系统总线和移位寄存器之间,只有低9位或低8有效,两者选择取决于USART控制寄存器1(USART_CR1)的M位,M=0为8位数据字长,M=1为9位数据字长。

3.控制器

USART有专门的控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等。使用USART之前,需要将USART_CR1的UE置1,使能串口时钟供给。

发送器:

USART_CR1的TE置1,启动数据发送,发送移位寄存器的数据会以低位在前、高位在后的形式从TX引脚输出,如果是同步模式SCLK也将输出时钟信号。

如下,字符发送时序图所示,一个字符帧发送需要三个部分:起始位+数据帧+停止位。起始位是一个位周期的低电平;数据帧是我们发送的8位或9位数据;停止位是一定时间周期的高电平,可以设置为0.5、1、1.5、2个停止位,默认使用1个停止位,2个停止位适用于USART模式、单线模式和调制解调器模式,0.5和1.5适用于智能卡模式。

发送数据重要的标志位

名称 描述
TE 使能发送器
TXE
发送寄存器为空,发送单个字节的时候使用
TC
发送完成,发送多个字节数据的时候使用
TXIE
使能发送完成中断

接收器

如果USART_CR1的RE置位,使能USART接受,使得接收器在RX线开始搜索起始位。接收数据时,几个比较重要的标志位如下

名称 描述
RE 接收使能
RXNE 读数据寄存器非空
RXNEIE 接收完成中断使能

4.小波特率生成

波特率指数据信号对载波的调制速率,它用单位时间内载波调制状态改变次数来表示,单位为波特。比特率指单位时间内传播的比特数。对于USART波特率与比特率相等。

USART的发送器和接收器使用相同的波特率,计算公式如下

其中,f为USART时钟,USARTDIV是一个放在波特率寄存器(USART_BRR)的一个无符号定点数。其中 DIV_Mantissa[11:0]位定义USARTDIV的整数部分,DIV_Fraction[3:0]位定义USARTDIV 的小数部分。

5.校验控制

USART支持奇偶校验。使用校验位时,串口传输的数据长度将是在8位的数据帧基础上加上1位,此时需要将USART_CR1的M为置1,然后将USART_CR1的PCE置1启动奇偶校验。

奇偶校验在发送和接收都是由硬件自动完成,如果在接收出现奇偶校验失败,会将USART_SR的PE置1,并可以产生奇偶校验中断。

6.中断控制

USART有多个中断请求事件,如下

中断事件 事件标志 使能控制位
发送数据寄存器为空 TXE TXEIE
CTS标志 CTS CTSIE
发送完成 TC TCIE
准备好读取接收到的数据 RXNE RXNEIE
检测到上溢错误 ORE
检测到空闲线路 IDLE IDLEIE
奇偶校验错误 PE PEIE
断路标志 LBD LBDIE
多缓冲通信中的噪声标志、上溢错误和帧错误 NF/ORE/FE EIE

7.USART初始化结构体详解

HAL库函数对每个外设都建立了一个初始化结构体和初始化配置函数,如USART_InitTypeDef和USART_Init(),USART_InitTypeDef用于配置外设工作参数,USART_Init()则将参数配置到相应的寄存器。

typedef struct {uint32_t BaudRate; //波特率uint32_t WordLength; //字长uint32_t StopBits; //停止位uint32_t Parity; //校验位uint32_t Mode; //UART 模式uint32_t HwFlowCtl; //硬件流控制uint32_t OverSampling; // 过采样模式uint32_t CLKLastBit; // 最尾位时钟脉冲
} USART_InitTypeDef;
  • BaudRate:波特率设置。一般设置为 2400、9600、19200、115200。HAL 库函数会根据设定值计算得到 UARTDIV 值。
  • WordLength:数据帧字长,可选 8 位或 9 位。
  • StopBits:停止位设置,可选 0.5 个、1 个、1.5 个和 2 个停止位。
  • Parity : 奇 偶 校 验 控 制 选 择 , 可 选 USART_PARITY_NONE ( 无校验 ) 、USART_PARITY_EVEN (偶校验)以及 USART_PARITY_ODD (奇校验)。
  • Mode:UART 模式选择,有 USART_MODE_RX 和 USART_MODE_TX,允许使用逻辑或运算选择两个,它设定 USART_CR1 寄存器的 RE 位和 TE 位。

8.编程要点

1) 使能 RX 和 TX 引脚 GPIO 时钟和 USART 时钟;

2) 初始化 GPIO,并将 GPIO 复用到 USART 上;

3) 配置 USART 参数;

4) 配置中断控制器并使能 USART 接收中断;

5) 使能 USART;

6) 在 USART 接收中断服务函数实现数据接收和发送

9.代码分析

GPIO和USART宏定义

//串口波特率
#define DEBUG_USART_BAUDRATE                    115200//引脚定义
/*******************************************************/
#define DEBUG_USART                             USART1
#define DEBUG_USART_CLK_ENABLE()                __HAL_RCC_USART1_CLK_ENABLE();#define DEBUG_USART_RX_GPIO_PORT                GPIOA
#define DEBUG_USART_RX_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOA_CLK_ENABLE()
#define DEBUG_USART_RX_PIN                      GPIO_PIN_10#define DEBUG_USART_TX_GPIO_PORT                GPIOA
#define DEBUG_USART_TX_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOA_CLK_ENABLE()
#define DEBUG_USART_TX_PIN                      GPIO_PIN_9#define DEBUG_USART_IRQHandler                  USART1_IRQHandler
#define DEBUG_USART_IRQ                             USART1_IRQn
/************************************************************/void Usart_SendString(uint8_t *str);
void DEBUG_USART_Config(void);
int fputc(int ch, FILE *f);
int fgetc(FILE *f);
extern UART_HandleTypeDef UartHandle;

USART初始化配置。函数体中UartHandle 是定义为 UART_HandleTypeDef 结构体类型的全局变量,它管理着串口的所有配置,该函数与硬件无关。

具体的MCU底层硬件相关的配置如引脚、时钟、DMA、中断等等是在HAL_UART_MspInit(UART_HandleTypeDef *huart)中完成,该函数被HAL_UART_Init 函数所调用,所以我们只需要重新定义HAL_UART_MspInit函数即可完成底层硬件的配置。

/*** @brief  DEBUG_USART GPIO 配置,工作模式配置。115200 8-N-1* @param  无* @retval 无*/
void DEBUG_USART_Config(void)
{ UartHandle.Instance          = DEBUG_USART;UartHandle.Init.BaudRate     = DEBUG_USART_BAUDRATE;UartHandle.Init.WordLength   = UART_WORDLENGTH_8B;UartHandle.Init.StopBits     = UART_STOPBITS_1;UartHandle.Init.Parity       = UART_PARITY_NONE;UartHandle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;UartHandle.Init.Mode         = UART_MODE_TX_RX;HAL_UART_Init(&UartHandle);/*使能串口接收断 */__HAL_UART_ENABLE_IT(&UartHandle,UART_IT_RXNE);
}
/*** @brief UART MSP 初始化 * @param huart: UART handle* @retval 无*/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{  GPIO_InitTypeDef  GPIO_InitStruct;DEBUG_USART_CLK_ENABLE();DEBUG_USART_RX_GPIO_CLK_ENABLE();DEBUG_USART_TX_GPIO_CLK_ENABLE();/**USART1 GPIO Configuration    PA9     ------> USART1_TXPA10    ------> USART1_RX *//* 配置Tx引脚为复用功能  */GPIO_InitStruct.Pin = DEBUG_USART_TX_PIN;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed =  GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStruct);/* 配置Rx引脚为复用功能 */GPIO_InitStruct.Pin = DEBUG_USART_RX_PIN;GPIO_InitStruct.Mode=GPIO_MODE_AF_INPUT;    //模式要设置为复用输入模式!  HAL_GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStruct); HAL_NVIC_SetPriority(DEBUG_USART_IRQ ,0,1);  //抢占优先级0,子优先级1HAL_NVIC_EnableIRQ(DEBUG_USART_IRQ );          //使能USART1中断通道
}

字符发送函数

/*****************  发送字符串 **********************/
void Usart_SendString(uint8_t *str)
{unsigned int k=0;do {HAL_UART_Transmit(&UartHandle,(uint8_t *)(str + k) ,1,1000);k++;} while(*(str + k)!='\0');}

中断服务函数

void  DEBUG_USART_IRQHandler(void)
{uint8_t ch=0; if(__HAL_UART_GET_FLAG( &UartHandle, UART_FLAG_RXNE ) != RESET){       ch=( uint16_t)READ_REG(UartHandle.Instance->DR);WRITE_REG(UartHandle.Instance->DR,ch); }
}

在嵌入式中,串口经常用作日志打印工具,下面代码功能是重定向printf和scanf函数,fputc是printf的内部函数,而fgetc是scanf的内部函数。

//重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{/* 发送一个字节数据到串口DEBUG_USART */HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 1000);   return (ch);
}//重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{       int ch;HAL_UART_Receive(&UartHandle, (uint8_t *)&ch, 1, 1000);  return (ch);
}

STM32串口通信-USART全面讲解相关推荐

  1. STM32串口通信USART练习

    文章目录 一.STM32的USART介绍 二.USART串口通信实践 1.任务要求 2.所用器材 3.主要代码 4.代码解析 三.效果展示 四.总结 五.参考资料 一.STM32的USART介绍 通用 ...

  2. STM32串口通信详解以及通信异常或者卡死常见问题分析

    STM32串口通信详解以及通信异常或者卡死常见问题分析 目录 STM32串口通信详解以及通信异常或者卡死常见问题分析 一.常见的异常问题 二.STM32的串口简介 1.串口的通讯方式 ①按数据传输方向 ...

  3. stm32串口通信(初学者对于串口通信的理解)

    stm32串口通信(初学者对于串口通信的理解) 标签: stm32串口通信单片机 2015-01-24 10:12 987人阅读 评论(0) 收藏 举报  分类: stm32 版权声明:本文为博主原创 ...

  4. STM32——串口通信

    STM32--串口通信 宗旨:技术的学习是有限的,分享的精神是无限的. 一.异步串口通信协议 STM32 的串口非常强大,它不仅支持最基本的通用串口同步.异步通信,还具有 LIN 总线功能(局域互联网 ...

  5. openmv和stm32串口通信完成二维码识别

    openmv和stm32串口通信完成二维码识别 文章目录 前言 一.所用的硬件: 二.openmv端 2.stm32端 总结 前言 注:我只是个大一的小白,本文只完成基本功能,希望能帮助有困惑的人(我 ...

  6. 安装STM32CubeMX,stm32串口通信

    目录 一.串口通信和RS-232标准 1.串口通信 波特率 数据位 停止位 奇偶校验 2.RS-232标准 二.安装STM32CubeMX,搭建STM32的开发环境 1.安装jdk 2.安装STM32 ...

  7. 【串口通信】K210与STM32串口通信、K210与OpenMV串口通信

    [串口通信]K210与STM32串口通信.K210与OpenMV串口通信 串口通信 前言 为何需要串口通信 K210如何进行串口通信 K210串口配置 K210串口发送相关定义 K210串口发送测试 ...

  8. STM32串口通信学习总结

                                                                             STM32串口通信学习总结 1.概述 1.1学习目的 ...

  9. STM32串口通信详解(嵌入式学习)

    STM32串口通信 1.通信基础知识 1.1 时钟信号区分 同步通信 异步通信 波特率 总线协议(电气协议) 1.2 通信方式划分 串行通信 并行通信 1.3 通信方向划分 单工通信 半双工通信 全双 ...

最新文章

  1. 【移动开发】安卓Lab2(01)
  2. [Python图像处理] 二十六.图像分类原理及基于KNN、朴素贝叶斯算法的图像分类案例
  3. 基于灰度变换的图像增强
  4. setupUi()引起的麻烦
  5. 你必须了解的基础的 Linux 网络命令
  6. 8. PHP7 安装
  7. CentOS安装NVidia驱动提示kernel source path问题
  8. base64编码规则
  9. 磁共振成像原理-物理基础2(质子在外部磁场的情况)
  10. C++-dllmain介绍
  11. 视频行业创业投资与趋势报告
  12. 新版代挂网站PHP源码+去除授权/支持燃鹅代抽
  13. vue3 出现 Component inside <Transition> renders non-element root node that cannot be animated.
  14. 浏览器如何使用HTTP防止ip限制
  15. SVM中支持向量的通俗解释
  16. 浅谈图片加载:逐行扫描VS交错扫描
  17. 树莓派基于ffmpeg+阿里云流媒体服务器实现视频直播
  18. 【c++图论】【口袋的天空】【部落划分】
  19. Python 使用 twitter API 获取twitter用户信息
  20. r星服务器在那个文件,gta5修改host文件连接r星服务器方法介绍

热门文章

  1. 如何创作一款商业级的安卓独立应用
  2. 【Qt】 Fractal Designer 4.6 - Help(中文版)
  3. 邮政快递与物流行业舆情监测系统方案
  4. Paddle2.0实现中文新闻文本标题分类
  5. 【雅思阅读】王希伟阅读P4(matching2段落信息配对题【困难】)
  6. 细细品味hadoop
  7. (swing读书笔记)Swing Look And Feel(1)
  8. ThreadX最小移植及tx_initialize_low_level.s的简要分析
  9. 通过pyautogui和excel插件方方格子来实现excel图片导入
  10. 快速高效 | iOS银行卡识别