秉火429笔记之十四 USART--串口通信

版权声明:专业游手好闲&LoaferPro https://blog.csdn.net/XieWinter/article/details/90176151

目录

1. 串口通讯协议简介

1.1 物理层

1.2 协议层

2  ST USART

2.1 功能引脚

2.2 重要状态

2.3 编程要点

2.4 代码实例


1. 串口通讯协议简介

串口通讯(Serial Communication)是一种设备间常用的串行通讯方式,因为简单便捷,大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试信息。

对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。

扫描二维码关注公众号,回复: 6745164 查看本文章

1.1 物理层

串口通讯的物理层有很多标准及变种,我们主要讲解RS-232标准 ,RS-232标准主要规定了信号的用途、通讯接口以及信号的电平标准。

两个通讯设备的“DB9接口”之间通过串口信号线建立起连接,串口信号线中使用“RS-232标准”传输数据信号。由于RS-232电平标准的信号不能直接被控制器直接识别,所以这些信号会经过一个“电平转换芯片”转换成控制器能识别的“TTL校准”的电平信号,才能实现通讯。

  • 电平标准

根据通讯使用的电平标准不同,串口通讯可分为TTL标准及RS-232标准

常见的电子电路中常使用TTL的电平标准,理想状态下,使用5V表示二进制逻辑1,使用0V表示逻辑0;而为了增加串口通讯的远距离传输及抗干扰能力,它使用-15V表示逻辑1,+15V表示逻辑0。因为控制器一般使用TTL电平标准,所以常常会使用MA3232芯片对TTL及RS-232电平的信号进行互相转换。

  • RS-232信号线

在最初的应用中,RS-232串口标准常用于计算机、路由与调制调解器(MODEN,俗称“猫”)之间的通讯 ,在这种通讯系统中,设备被分为数据终端设备DTE(计算机、路由)和数据通讯设备DCE(调制调解器)。我们以这种通讯模型讲解它们的信号线连接方式及各个信号线的作用。

在旧式的台式计算机中一般会有RS-232标准的COM口(也称DB9接口)

接线口以针式引出信号线的称为公头,以孔式引出信号线的称为母头。在计算机中一般引出公头接口,而在调制调解器设备中引出的一般为母头,使用上图中的串口线即可把它与计算机连接起来。通讯时,串口线中传输的信号就是使用前面讲解的RS-232标准调制的。

信号线说明
序号 名称 符号 数据方向 说明
1 载波侦测 DCD DTE->DCE Data Carrier Detect,数据载波检测,用于DTE告知对方,本机是否收到对方的载波信号
2 接收数据 RXD DET<-DCE Receive Data,数据接收信号,即输入 。
3 发送数据 TXD DTE->DCE Transmit Data,数据发送信号,即输出。两个设备之间的TXD与RXD应交叉相连
4 数据终端 (DTE) 就绪 DTR DTE->DCE Data Terminal Ready,数据终端就绪,用于DTE向对方告知本机是否已准备好
5 信号地 GND -- 地线,两个通讯设备之间的地电位可能不一样,这会影响收发双方的电平信号,所以两个串口设备之间必须要使用地线连接,即共地。
6 数据设备(DCE)就绪 DSR DET<-DCE Data Set Ready,数据发送就绪,用于DCE告知对方本机是否处于待命状态
7 请求发送 RTS DTE->DCE Request To Send,请求发送, DTE 请求 DCE 本设备向DCE端发送数据
8 允许发送 CTS DET<-DCE Clear To Send,允许发送,DCE回应对方的RTS发送请求,告知对方是否可以发送数据
9 响铃指示 RI DET<-DCE Ring Indicator,响铃指示,表示DCE端与线路已接通

串口线中的RTS、CTS、DSR、DTR及DCD信号,使用逻辑 1表示信号有效,逻辑0表示信号无效。例如,当计算机端控制DTR信号线表示为逻辑1时,它是为了告知远端的调制调解器,本机已准备好接收数据,0则表示还没准备就绪。

在目前的其它工业控制使用的串口通讯中,一般只使用RXD、TXD以及GND三条信号线,直接传输数据信号。

1.2 协议层

串口通讯的数据包由发送设备通过自身的TXD接口传输到接收设备的RXD接口。在串口通讯的协议层中,规定了数据包的内容,它由启始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据。

  • 波特率

两个通讯设备之间需要约定好波特率,即每个码元的长度,以便对信号进行解码,图 中用虚线分开的每一格就是代表一个码元。常见的波特率为4800、9600、115200等。

  • 通讯的起始和停止信号

串口通讯的一个数据包从起始信号开始,直到停止信号结束。数据包的起始信号由一个逻辑0的数据位表示,而数据包的停止信号可由0.5、1、1.5或2个逻辑1的数据位表示,只要双方约定一致即可

  • 有效数据

在数据包的起始位之后紧接着的就是要传输的主体数据内容,也称为有效数据,有效数据的长度常被约定为5、6、7或8位长。

  • 数据校验

在有效数据之后,有一个可选的数据校验位。由于数据通信相对更容易受到外部干扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验(odd)、偶校验(even)、0校验(space)、1校验(mark)以及无校验(noparity)

  1. 奇校验要求有效数据和校验位中“1”的个数为奇数
  2. 偶校验与奇校验要求刚好相反,要求帧数据和校验位中“1”的个数为偶数
  3. 0校验是不管有效数据中的内容是什么,校验位总为“0”,1校验是校验位总为“1”。
  4. 在无校验的情况下,数据包中不包含校验位

2  ST USART

2.1 功能引脚

  • TX:发送数据输出引脚。
  • RX:接收数据输入引脚。
  • SW_RX:数据接收引脚,只用于单线和智能卡模式,属于内部引脚,没有具体外部引脚。
  • nRTS:请求以发送(Request To Send),n表示低电平有效。如果使能RTS流控制,当USART接收器准备好接收新数据时就会将nRTS变成低电平;当接收寄存器已满时,nRTS将被设置为高电平。该引脚只适用于硬件流控制。
  • nCTS:清除以发送(Clear To Send),n表示低电平有效。如果使能CTS流控制,发送器在发送下一帧数据之前会检测nCTS引脚,如果为低电平,表示可以发送数据,如果为高电平则在发送完当前数据帧之后停止发送。该引脚只适用于硬件流控制。
  • SCLK:发送器时钟输出引脚。这个引脚仅适用于同步模式。

STM32F42xxx系统控制器有四个USART和四个UART,其中USART1和USART6的时钟来源于APB2总线时钟,其最大频率为90MHz,其他六个的时钟来源于APB1总线时钟,其最大频率为45MHz

UART只是异步传输功能,所以没有SCLK、nCTS和nRTS功能引脚。

2.2 重要状态

编程重要状态
1 名称 描述
2 TE 发送使能,能力
3 TXE 发送寄存器为空,
4 TC 发送完成
5 TXIE 发送完成中断使能
6 RE 接收使能,能力
7 RXNE 读数据寄存器非空
8 RXNEIE 发送完成中断使能

  •            空闲字符 可理解为整个帧周期内电平均为“1”(停止位的电平也是“1”),该字符后是下一个数据帧的起始位。
  • 停止字符 可理解为在一个帧周期内接收到的电平均为“0”。发送器在中断帧的末尾插入 1 或 2 个停止位(逻辑“1”位)以确认起始位。

2.3 编程要点

常规中断方式:

  • 使能RX和TX引脚GPIO时钟和USART时钟
  • 初始化GPIO,并将GPIO复用到USART上
  • 配置USART参数;
  • 配置中断控制器并使能USART收发中断;
  • 使能USART;
  • 在USART接收中断服务函数实现数据接收和发送

DMA中断方式:

  • 使能RX和TX引脚GPIO时钟和USART时钟
  • 初始化GPIO,并将GPIO复用到USART上
  • 配置USART参数;
  • 配置中断控制器并使能USART DMA 收发中断
  • 配置DMA参数及关联数据BUF并配置传输完成中断
  • 使能USART
  • 通过IDLE空闲中断来标识单帧传输完成,计数数据大小,并配合DMA缓存满中断完成数据接收判断
  • 通过重置DMA计数和使能DMA发送
  • 注意考虑接收超过缓存大小时,关闭DMA传输,进入等待IDLE,然后,处理数据,超出直接丢掉

2.4 代码实例

重定向prinft和scanf函数

在C语言标准库中,fputc函数是printf函数内部的一个函数,功能是将字符ch写入到文件指针f所指向文件的当前写指针位置,简单理解就是把字符写入到特定文件中。我们使用USART函数重新修改fputc函数内容,达到类似“写入”的功能。介于某些情况下,硬件并不一定有UART,亦可以类似方法重定义到RAM来方便调试,后续专门介绍。

fgetc函数与fputc函数非常相似,实现字符读取功能。在使用scanf函数时需要注意字符输入格式。
还有一点需要注意的,使用fput和fgetc函数达到重定向C语言标准库输入输出函数必须在MDK的工程选项把“Use MicroLIB”勾选上,MicoroLIB是缺省C库的备选库,它对标准C库进行了高度优化使代码更少,占用更少资源。当然,维库在某些特殊条件下并不需要,比如RL_FLASH,通过其他方式来实现重定向。

为使用printf、scanf函数需要在文件中包含stdio.h头文件。

///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
		/* 发送一个字节数据到串口 */
		USART_SendData(DEBUG_USART, (uint8_t) ch);
		
		/* 等待发送完毕 */
		while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET);		
	
		return (ch);
}

///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
		/* 等待串口输入数据 */
		while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_RXNE) == RESET);

		return (int)USART_ReceiveData(DEBUG_USART);
}

猜你喜欢

转载自blog.csdn.net/XieWinter/article/details/90176151