本文將介紹在MM32F013x上實現(xiàn)UART單線半雙工的功能應(yīng)用。
UART單線半雙工簡介
在使用數(shù)字舵機通訊時所用到的通信方式為UART通信,但舵機只有三根接線,除去VCC和GND,只有一條通信線,也就是說要實現(xiàn)雙向通信,只能使用單線半雙工模式。在單線半雙工模式下,TX 和 RX 引腳在芯片內(nèi)部互連。
01 配置流程
單線半雙工模式是通過設(shè)置UART_SCR寄存器的HDSEL位,在這個模式里UART_SCR 寄存器的SCEN位必須保持清零狀態(tài)。
在單線半雙工模式下,TX和RX引腳在芯片內(nèi)部互聯(lián),使用控制位”HALF DUPLEX SEL”(UART_SCR 中的 HDSEL 位) 選擇半雙工和全雙工通信。
注意
當(dāng)選擇單線半雙工模式時RX 不再被使用,當(dāng)有數(shù)據(jù)需要發(fā)送的時候IO才會被UART驅(qū)動,沒有數(shù)據(jù)傳輸時TX總是被釋放,所以使用單線半雙工需要外部加上拉。
除此之外通訊上和正常的UART模式類似。由于是單線半雙工同一時刻總線上只能有一個節(jié)點發(fā)送,所以需要軟件協(xié)議層去管理線上沖突防止多個設(shè)備同時發(fā)送,當(dāng) TXEN 位被設(shè)置時,只要數(shù)據(jù)一寫到數(shù)據(jù)寄存器上,發(fā)送就繼續(xù)。
02 UART_SCR寄存器描述
配置UART_SCR 的HDSEL為1
UART_SCR 寄存器的SCEN位清零
初始化UART1
從官網(wǎng)上下載MM32F013x例程,里面有UART普通模式的配置,在這個基礎(chǔ)上我們直接調(diào)用UART_HalfDuplexCmd(UART1,ENABLE);函數(shù)接口將串口配置成單線半雙工模式,然后IO口初始化只需要配置PA9 TX即可,如下:
void UART1_NVIC_Init(u32 baudrate)
{
UART_InitTypeDef UART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
//UART1 NVIC
NVIC_InitStructure.NVIC_IRQChannel = UART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//Baud rate
UART_StructInit(&UART_InitStructure);
UART_InitStructure.BaudRate = baudrate;
//The word length is in 8-bit data format.
UART_InitStructure.WordLength = UART_WordLength_8b;
UART_InitStructure.StopBits = UART_StopBits_1;
//No even check bit.
UART_InitStructure.Parity = UART_Parity_No;
//No hardware data flow control.
UART_InitStructure.HWFlowControl = UART_HWFlowControl_None;
UART_InitStructure.Mode = UART_Mode_Rx | UART_Mode_Tx;
UART_Init(UART1, &UART_InitStructure);
UART_HalfDuplexCmd(UART1,ENABLE); //Half Duplex Enable
UART_ITConfig(UART1, UART_IT_RXIEN, ENABLE);
UART_Cmd(UART1, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
//UART1_TX GPIOA.9
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
功能驗證測試
UART單線半雙工功能測試我們現(xiàn)在拿兩個MM32F0133的板子一個做主機一個做從機進行單線收發(fā)測試,主機先發(fā)送一包數(shù)據(jù)給從節(jié)點,當(dāng)從節(jié)點收到這包數(shù)據(jù)后再把這包數(shù)據(jù)發(fā)回給主機,然后主機和從機兩個板子PA9短接到一起,外部在加一個4.7K上拉電阻。
主機函數(shù)處理:
uint8_t txbuff[10]= {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA};
s32 main(void)
{
CONSOLE_Init(115200);//UART2 printf打印
UART1_NVIC_Init(115200);
printf(“UART Half Duplex TX Test /r/n”);
UART1_Send_Group(txbuff,sizeof(txbuff));
printf(“TX Data: ”);
for(index=0;index
主機UART的中斷服務(wù)函數(shù)里面,將接從機發(fā)送的數(shù)據(jù)存放在Rx_buff里面,當(dāng)收到一包數(shù)據(jù)后通過printf打印到串口,和原始發(fā)送的數(shù)據(jù)進行對比。
void UART1_IRQHandler(void)
{
u8 recvbyte;
// Send packet
if (UART_GetITStatus(UART1, UART_IT_TXIEN) != RESET)
{
UART_ClearITPendingBit(UART1, UART_IT_TXIEN);
}
// Recv packet
if (UART_GetITStatus(UART1, UART_ISR_RX) != RESET)
{
UART_ClearITPendingBit(UART1, UART_ISR_RX);
recvbyte = UART_ReceiveData(UART1);
Rx_buff[rx_cnt] = recvbyte;
rx_cnt++;
if(rx_cnt == 10)
{
gUartRxSta = 1;
rx_cnt = 0;
}
}
}
從機函數(shù)處理:
s32 main(void)
{
CONSOLE_Init(115200);//UART2 printf打印
UART1_NVIC_Init(115200);
printf(“UART Half Duplex RX Test/r/n”);
while(1)
{
if(gUartRxSta == 1)//收到一包數(shù)據(jù)
{
gUartRxSta = 0;
UART1_Send_Group(Rx_buff,10);
memset(Rx_buff,0x00,10);
}
}
//return 0;
}
從機UART的中斷服務(wù)函數(shù)里面,將接主機發(fā)送的數(shù)據(jù)存放在Rx_buff里面,當(dāng)收到一包數(shù)據(jù)后通過單線半雙工這個串口發(fā)送回去。
void UART1_IRQHandler(void)
{
u8 recvbyte;
// Send packet
if (UART_GetITStatus(UART1, UART_IT_TXIEN) != RESET)
{
UART_ClearITPendingBit(UART1, UART_IT_TXIEN);
}
// Recv packet
if (UART_GetITStatus(UART1, UART_ISR_RX) != RESET)
{
UART_ClearITPendingBit(UART1, UART_ISR_RX);
recvbyte = UART_ReceiveData(UART1);
Rx_buff[rx_cnt] = recvbyte;
rx_cnt++;
if(rx_cnt == 10)
{
gUartRxSta = 1;
rx_cnt = 0;
}
}
}
觀察測試結(jié)果:
然后我們通過主機UART2 的printf打印可以看到主機TX Data 和從機返回的RX Data數(shù)據(jù)是一樣的。
再看看下圖邏輯分析儀抓取的邏輯波形,可以也可以看到主機發(fā)送的波形和從機返回的波形數(shù)據(jù)是一樣的。
轉(zhuǎn)自:靈動微電子
審核編輯:何安
-
uart
+關(guān)注
關(guān)注
22文章
1245瀏覽量
101812 -
靈動微電子
+關(guān)注
關(guān)注
7文章
122瀏覽量
19706
發(fā)布評論請先 登錄
相關(guān)推薦
在NXP源碼基礎(chǔ)上如何適配ELF 1開發(fā)板的UART功能
![<b class='flag-5'>在</b>NXP源碼基礎(chǔ)<b class='flag-5'>上</b>如何適配ELF 1開發(fā)板的<b class='flag-5'>UART</b><b class='flag-5'>功能</b>](https://file1.elecfans.com//web2/M00/08/8E/wKgZomb4zkiAehupAAB1WkVXQrc743.jpg)
使用TM4C129x 微控制器為 TMP1826實現(xiàn)單線枚舉功能應(yīng)用說明
![使用TM4C129<b class='flag-5'>x</b> 微控制器為 TMP1826<b class='flag-5'>實現(xiàn)</b><b class='flag-5'>單線</b>枚舉<b class='flag-5'>功能</b>應(yīng)用說明](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
ISO308x隔離式5V全雙工和半雙工RS-485收發(fā)器數(shù)據(jù)表
![ISO308<b class='flag-5'>x</b>隔離式5V全<b class='flag-5'>雙工</b>和<b class='flag-5'>半雙工</b>RS-485收發(fā)器數(shù)據(jù)表](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
單工、半雙工和全雙工傳輸模式的區(qū)別
esp32 wroom 32d是半雙工還是全雙工的?
全雙工與半雙工技術(shù)解析
請問如何取消UART的GPIO映射?
PSoC5 UART半雙工模式在UART_LoadTxConfig() 之后傳輸數(shù)據(jù)時的疑問求解
當(dāng)XMC1400配置為半雙工SPI主站時,SPI_MASTER_Receive功能能否正常工作?
全雙工與半雙工技術(shù)解析及其應(yīng)用場景
做一個STM8 UART半雙工,測試發(fā)現(xiàn)數(shù)據(jù)發(fā)送和回發(fā)不穩(wěn)定,怎么解決?
使用STM32F072 USART單線半雙工模式通信,只要打開IDLE中斷就會一直觸發(fā)IDLE中斷怎么解決?
節(jié)省IO的小技巧:GD32 MCU如何使用一個GPIO實現(xiàn)串口半雙工收發(fā)
![節(jié)省IO的小技巧:GD32 MCU如何使用一個GPIO<b class='flag-5'>實現(xiàn)</b>串口<b class='flag-5'>半雙工</b>收發(fā)](https://file1.elecfans.com/web2/M00/C5/5B/wKgaomXzpsiAH5-tAAAqGsdHXv0568.png)
評論