UART半双工通讯原理与设计实现 - 以航顺HK32F0301MxxxxC系列MCU为例

UART通讯协议简要说明

UART,即通用异步串行收发传输器(Universal Asynchronous Receiver/Transmitter),一般按照单片机的支持,可以配置为全双工或半双工通讯:
全双工会使用两条信号线,RX和TX,对于指定的一个全双工设备,TX为该设备的数据发送线,RX为数据接收线,一般需要交叉连接另一设备的TX和RX(也就是自己的发送线连接到对方的接收线,自己的接收线连接到对方的发送线)。
半双工只需要一条数据线,进行通讯的双方按照指定的一定标准,交替发送数据等,可以实现一条线上完成数据发送与接收的任务。

UART协议数据帧结构

一般UART的一帧数据包含以下几部分

  • 启动位(Start Bit):一个低电平的比特,用于标识数据传输的开始;
  • 数据位(Data Bits):包含要传输的数据的比特数,通常是5、6、7或8个比特;
  • 奇偶校验位(Parity Bit):可选,用于验证数据的正确性。奇偶校验位的值可以是奇校验或偶校验,它们根据数据位中1的个数确定;
  • 停止位(Stop Bit):一个时钟高电平的比特,用于标识数据传输的结束;

如下图展示了航顺MCU数据手册中的UART协议数据帧结构配图,注意这里面把奇偶校验位视为数据位的一部分。

在这里插入图片描述

UART半双工通讯的实现

这里简要展示一下UART通讯的几种情况,如下图所示:
(a)为单工通讯,规定好一方发送,另一方接收;
(b)为半双工通讯,双方都可以进行发送和接收,不过为了避免冲突,不能同步收发;
(c)为全双工通讯,双方通过两条信号线连接,可以同时收发。

在这里插入图片描述
如果希望使用UART进行半双工通讯,一般双方都使用TX引脚进行连接,此时一方需要使用上拉电阻置高电平(UART通讯默认情况下是高电平,拉低电平表示数据传输的开始)。
这时在软件中规定好双方的收发顺序等,正确配置通讯双方的发送、接收状态的切换,即可实现在一条数据线上完成双方的数据发送与接收。

半双工通讯设计

这里以航顺HK32F0301MxxxxC系列MCU为例进行半双工通讯的代码设计。

MCU硬件条件确认

首先我们需要确定MCU支持半双工通信,通过翻阅数据手册我们可以了解到航顺的该类型MCU支持UART的单线半双工通信。

在这里插入图片描述

另外,数据手册中有对UART单线半双工通信的进一步说明,需要仔细阅读。我们可以看到数据手册中明确说明TX需要配置为复用功能、开漏输出,并在外部接上拉电阻以拉高电平,这在最开始的硬件原理图设计中就要注意。

在这里插入图片描述

通讯设计思路

由于我们这里使用单线半双工通讯,双方的硬件条件都支持数据的接收与发送,那么如果软件上未做好设计,将可能出现双方同时准备发送数据的情况,也就是发生了抢占冲突的问题。

此时将会导致信号线电平不正确,通讯双方将无法接收到正确数据,我们有必要设计好双方的一个收发流程,保证数据传输的正确性。

这里简单提两种通讯设计思路:

  1. 主从设备:令一台设备作为主设备,另一台为从设备;从设备只有接收到主设备发送的数据后,才会开始传递数据给主设备,主设备在规定时间内收到后,可以按照需求继续发送数据或暂停等。此外主设备设计超时重发机制,在发送完数据后,若规定时间内未收到数据,判定为超时,重新进行发送以尝试建立通讯。
  2. 交替发送:通讯双方各自设定一个定时器,例如规定5ms进行一次定时器中断,在定时器中断触发时,进行数据发送,并在发送完毕之后切换回接收状态,这里要注意收发状态的修改,避免自发自收的情况出现。

此外,为了进一步保证收发数据的正确性,可以指定通讯协议帧头、帧尾,以及配合校验字节等确保完整接收。

代码实现

这里我们以主从设备模式为例,简要展示一下代码的实现。

首先是航顺UART的配置,我们需要使能UART外设的时钟,并设置好波特率、校验方式、停止位、数据位等,并且要注意我们这里需要打开UART的接收和发送,并使能半双工(UART_HalfDuplexCmd(UART1,ENABLE);),最后使能接收中断。

这里还需要配置要复用为UART数据发送的引脚,并配置为开漏输出,这里不做展示。

void UART_Configurature(void){
   
	UART_InitTypeDef m_usart;

	RCC_APBPeriph2ClockCmd(RCC_APBPeriph2_UART1, ENABLE);	// 使能UART1时钟
	m_usart.UART_BaudRate = 9600;							// 波特率9600
	m_usart.UART_Mode = UART_Mode_Rx| UART_Mode_Tx;			// 使能接收和发送
	m_usart.UART_Parity = UART_Parity_Even;					// 偶校验
	m_usart.UART_StopBits = UART_StopBits_1;				// 1位停止位
	m_usart.UART_WordLength = UART_WordLength_9b;			// 9位数据位

	UART_Init(UART1, &m_usart);

	UART_HalfDuplexCmd(UART1,ENABLE);						// 半双工
	UART_Cmd(UART1, ENABLE);								// 使能UART1

	UART_ITConfig(UART1, UART_IT_RXNE, ENABLE);				// 配置接收中断
	NVIC_SetPriority(UART1_IRQn,0);							// 设置优先级
	NVIC_EnableIRQ(UART1_IRQn);								// 使能中断
}

这里我们简单来看一下UART_HalfDuplexCmd(UART1,ENABLE);函数的含义,找到航顺官方提供的库函数源文件中该函数的实现,可以看到在使能半双工时,将会把UART对应寄存器CR3HDSEL位置1,与前面数据手册中所提到的UART单线半双工通信一致。

/**
  * @brief  Enables or disables the UART's Half Duplex communication.
  * @param  UARTx: Select the UART or the UART peripheral.  
	*   This 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

关岭风尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值