一、簡介
半雙工即Half duplex Communication,是指在通信過程的任意時刻,信息既可由A傳到B,又能由B傳A,但同時只有一個方向上的傳輸存在。由于這種方式要頻繁變換信道方向,故效率低,但可以節(jié)約傳輸線路。半雙工方式適用于終端與終端之間的會話式通信。
二、實際操作(以CW32L083為例)
設(shè)置 UARTx_CR2.SIGNAL 為 1 使 UART 工作于單線半雙工工作模式。在該模式下,使用 UARTx_TXD 引腳進行數(shù)據(jù)的發(fā)送和接收,不占用 UARTx_RXD 引腳(UARTx_RXD 可作通用 IO 使用)。寫數(shù)據(jù)到 UARTx_TDR 寄存器后,UARTx_TXD 引腳立即進入發(fā)送狀態(tài),輸出 UARTx_TDR 寄存器中的數(shù)據(jù)。數(shù)據(jù) 發(fā)送完成后,UARTx_TXD 引腳恢復(fù)到常態(tài)的接收狀態(tài)。沒有發(fā)送數(shù)據(jù)時,UARTx_TXD 引腳處于接收狀態(tài),數(shù)據(jù)接收完成后,接收完成標志位 UARTx_ISR.RC 會被硬件置 位,此時應(yīng)盡快讀取 UARTx_RDR 寄存器,并清除 UARTx_ISR.RC 標志位。
UART工作在單線半雙工模式時,UARTx_TXD引腳需要配置為開漏輸出。另外用戶應(yīng)采取適當?shù)膽?yīng)用層保護機制,以確保不會出現(xiàn)多主機同時向總線發(fā)送數(shù)據(jù)。
三、UART單線半雙工通信示例
硬件采用CW32L083VxTx StartKit單板,用杜邦線連接PA08和PA06引腳。
UARTy查詢方式發(fā)送TxBuffer1緩沖區(qū)中的數(shù)據(jù),UARTz查詢方式接收數(shù)據(jù),并存儲到RxBuffer2緩沖區(qū)。
UARTz查詢方式發(fā)送TxBuffer2緩沖區(qū)中的數(shù)據(jù),UARTy查詢方式接收數(shù)據(jù),并存儲到RxBuffer1緩沖區(qū)。
比較TxBuffer1和RxBuffer2、TxBuffer2和RxBuffer1,如果數(shù)據(jù)一致,則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);//外設(shè)時鐘使能 UARTy_APBClkENx(UARTy_CLK,ENABLE); UARTz_APBClkENx(UARTz_CLK,ENABLE); }
2、配置GPIO
voidGPIO_Configuration(void) { GPIO_InitTypeDefGPIO_InitStructure={0}; UARTy_AFTX;//UARTTX復(fù)用 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;//發(fā)送/接收使能 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發(fā)送一個字節(jié)數(shù)據(jù) 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發(fā)送一個字節(jié)數(shù)據(jù) 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); } //檢查收發(fā)數(shù)據(jù)一致性 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、測試結(jié)果:UART半雙工通信方式工作正常, LED1亮。
來源:武漢芯源半導(dǎo)體
免責聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問題,請聯(lián)系小編進行處理
審核編輯 黃宇
-
半雙工
+關(guān)注
關(guān)注
0文章
13瀏覽量
9038 -
uart
+關(guān)注
關(guān)注
22文章
1235瀏覽量
101350 -
單線
+關(guān)注
關(guān)注
0文章
6瀏覽量
8944
發(fā)布評論請先 登錄
相關(guān)推薦
評論