一、简介
半双工即Half duplex Communication,是指在通信过程的任意时刻,信息既可由A传到B,又能由B传A,但同时只有一个方向上的传输存在。由于这种方式要频繁变换信道方向,故效率低,但可以节约传输线路。半双工方式适用于终端与终端之间的会话式通信。
二、实际操作(以CW32L083为例)
设置 UARTx_CR2.SIGNAL 为 1 使 UART 工作于单线半双工工作模式。在该模式下,使用 UARTx_TXD 引脚进行数据的发送和接收,不占用 UARTx_RXD 引脚(UARTx_RXD 可作通用 IO 使用)。写数据到 UARTx_TDR 寄存器后,UARTx_TXD 引脚立即进入发送状态,输出 UARTx_TDR 寄存器中的数据。数据 发送完成后,UARTx_TXD 引脚恢复到常态的接收状态。没有发送数据时,UARTx_TXD 引脚处于接收状态,数据接收完成后,接收完成标志位 UARTx_ISR.RC 会被硬件置 位,此时应尽快读取 UARTx_RDR 寄存器,并清除 UARTx_ISR.RC 标志位。

UART工作在单线半双工模式时,UARTx_TXD引脚需要配置为开漏输出。另外用户应采取适当的应用层保护机制,以确保不会出现多主机同时向总线发送数据。
三、UART单线半双工通信示例
硬件采用CW32L083VxTx StartKit单板,用杜邦线连接PA08和PA06引脚。
UARTy查询方式发送TxBuffer1缓冲区中的数据,UARTz查询方式接收数据,并存储到RxBuffer2缓冲区。
UARTz查询方式发送TxBuffer2缓冲区中的数据,UARTy查询方式接收数据,并存储到RxBuffer1缓冲区。
比较TxBuffer1和RxBuffer2、TxBuffer2和RxBuffer1,如果数据一致,则LED1亮,否则LED2亮。
1、配置RCC
voidRCC_Configuration(void) { RCC_HSI_Enable(RCC_HSIOSC_DIV6);//SYSCLK=HSI=8MHz=HCLK=PCLK RCC_AHBPeriphClk_Enable(UARTy_GPIO_CLK|UARTz_GPIO_CLK| RCC_AHB_PERIPH_GPIOC,ENABLE);//外设时钟使能 UARTy_APBClkENx(UARTy_CLK,ENABLE); UARTz_APBClkENx(UARTz_CLK,ENABLE); }
2、配置GPIO
voidGPIO_Configuration(void)
{
GPIO_InitTypeDefGPIO_InitStructure={0};
UARTy_AFTX;//UARTTX复用
UARTz_AFTX;U
ARTy_TXPUR;//UARTTXPUR
UARTz_TXPUR;
GPIO_InitStructure.Pins=UARTy_TxPin;
GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_OD;//开漏输出
GPIO_Init(UARTy_GPIO, GPIO_InitStructure);
GPIO_InitStructure.Pins=UARTz_TxPin;
GPIO_Init(UARTz_GPIO, GPIO_InitStructure);
GPIO_InitStructure.Pins=GPIO_PIN_3|GPIO_PIN_2;//PC3LED1/PC2LED2
GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_PP;
GPIO_Init(CW_GPIOC, GPIO_InitStructure);P
C03_SETLOW();//LED灭
PC02_SETLOW();
}
3、配置UART
voidUART_Configuration(void)
{
UART_InitTypeDefUART_InitStructure={0};
UART_InitStructure.UART_BaudRate=UARTyz_BaudRate;//波特率
UART_InitStructure.UART_Over=UART_Over_16;//采样方式
UART_InitStructure.UART_Source=UART_Source_PCLK;//传输时钟源
UCLKUART_InitStructure.UART_UclkFreq=UARTyz_UclkFreq;//传输时钟UCLK频率
UART_InitStructure.UART_StartBit=UART_StartBit_FE;//起始位判定方式
UART_InitStructure.UART_StopBits=UART_StopBits_1;//停止位长度
UART_InitStructure.UART_Parity=UART_Parity_No;//校验方式
UART_InitStructure.UART_HardwareFlowControl=UART_HardwareFlowControl_None;
UART_InitStructure.UART_Mode=UART_Mode_Rx|UART_Mode_Tx;//发送/接收使能
UART_Init(UARTy, UART_InitStructure);
UART_Init(UARTz, UART_InitStructure);
}
4、定义变量
//UARTy #defineUARTyCW_UART1 #defineUARTy_CLKRCC_APB2_PERIPH_UART1 #defineUARTy_APBClkENxRCC_APBPeriphClk_Enable2 #defineUARTy_GPIO_CLKRCC_AHB_PERIPH_GPIOA #defineUARTy_GPIOCW_GPIOA #defineUARTy_TxPinGPIO_PIN_8 #defineUARTy_AFTXPA08_AFx_UART1TXD() #defineUARTy_TXPURPA08_PUR_ENABLE(); //UARTz #defineUARTzCW_UART2 #defineUARTz_CLKRCC_APB1_PERIPH_UART2 #defineUARTz_APBClkENxRCC_APBPeriphClk_Enable1 #defineUARTz_GPIO_CLKRCC_AHB_PERIPH_GPIOA #defineUARTz_GPIOCW_GPIOA #defineUARTz_TxPinGPIO_PIN_6 #defineUARTz_AFTXPA06_AFx_UART2TXD() #defineUARTz_TXPURPA06_PUR_ENABLE() #defineUARTyz_BaudRate9600 #defineUARTyz_UclkFreq8000000 #defineTxBufferSize1(ARRAY_SZ(TxBuffer1)-1) #defineTxBufferSize2(ARRAY_SZ(TxBuffer2)-1) typedefenum{FAILED=0,PASSED=!FAILED}TestStatus; TestStatusBuffercmp(uint8_t*pBuffer1,uint8_t*pBuffer2,uint16_tBufferLength); uint8_tTxBuffer1[]="rnCW32L083UARTHalfDuplex:UARTy->UARTzrn"; uint8_tTxBuffer2[]="rnCW32L083UARTHalfDuplex:UARTz->UARTyrn"; uint8_tRxBuffer1[TxBufferSize2];uint8_tRxBuffer2[TxBufferSize1]; uint32_tNbrOfDataToRead1=TxBufferSize2; uint32_tNbrOfDataToRead2=TxBufferSize1; uint8_tTxCounter1=0,RxCounter1=0; uint8_tTxCounter2=0,RxCounter2=0; volatileTestStatusTransferStatus1=FAILED,TransferStatus2=FAILED;
5、主程序
int32_tmain(void)
{
RCC_Configuration();//配置RCC
GPIO_Configuration();//配置GPIO
UART_Configuration();//配置UART
UART_HalfDuplexCmd(UARTy,ENABLE);//单线半双工UARTy
UART_HalfDuplexCmd(UARTz,ENABLE);//单线半双工UARTz
while(NbrOfDataToRead2--)//UARTy->UARTz
{
//UARTy发送一个字节数据
UART_SendData_8bit(UARTy,TxBuffer1[TxCounter1++]);
while(UART_GetFlagStatus(UARTy,UART_FLAG_TXE)==RESET);
//UARTz等待RC
while(UART_GetFlagStatus(UARTz,UART_FLAG_RC)==RESET);
UART_ClearFlag(UARTz,UART_FLAG_RC);
RxBuffer2[RxCounter2++]=UART_ReceiveData_8bit(UARTz);
}
while(NbrOfDataToRead1--)//UARTz->UARTy
{
//UARTz发送一个字节数据
UART_SendData_8bit(UARTz,TxBuffer2[TxCounter2++]);
while(UART_GetFlagStatus(UARTz,UART_FLAG_TXE)==RESET);
//UARTy等待RC
while(UART_GetFlagStatus(UARTy,UART_FLAG_RC)==RESET);
UART_ClearFlag(UARTy,UART_FLAG_RC);
RxBuffer1[RxCounter1++]=UART_ReceiveData_8bit(UARTy);
}
//检查收发数据一致性
TransferStatus1=Buffercmp(TxBuffer1,RxBuffer2,TxBufferSize1);
TransferStatus2=Buffercmp(TxBuffer2,RxBuffer1,TxBufferSize2);
if(TransferStatus1==PASSED TransferStatus2==PASSED)//PASSED
{
//LED1亮
PC03_SETHIGH();
}
else//FAILED
{
PC02_SETHIGH();//LED2亮
}
while(1)
{
}
}
6、测试结果:UART半双工通信方式工作正常, LED1亮。
来源:武汉芯源半导体
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理
审核编辑 黄宇
-
半双工
+关注
关注
0文章
21浏览量
9320 -
uart
+关注
关注
22文章
1304浏览量
106112 -
单线
+关注
关注
0文章
7浏览量
9129
发布评论请先 登录

CW32L083的UART单线半双工模式介绍
评论