????項目中使用STM32 UART連接SN75176與外界實現(xiàn)485通訊,通過一個單獨GPIO管腳控制485 傳輸方向(DE/RE),UART設(shè)置為波特率9600,數(shù)據(jù)位8,停止位1,校驗位0。
????通訊過程中發(fā)現(xiàn)向串口輸出一組數(shù)據(jù)后,UART中斷總會接收到一個字節(jié)0x00,而上位機并未發(fā)送任何數(shù)據(jù)。
????示波器追蹤信號發(fā)現(xiàn)當(dāng)SN75176發(fā)送數(shù)據(jù)時,即DE(PIN3)有效時,R(PIN1)端為低電平,當(dāng)發(fā)送完成切換為RE(PIN2)有效時,同時R(PIN1)由低電平轉(zhuǎn)換為高電平。

????根據(jù)UART傳輸協(xié)議,空閑時保持高電平,如果傳輸一個字節(jié)0x00,在上述設(shè)置下,波形表現(xiàn)為9個bit的低電平。

????根據(jù)波形猜測UART將R(PIN1)端的最后一部分識別為一個字節(jié)0x00。
????解決辦法:由于RS485本來就是半雙工通訊,在發(fā)送時不可能有數(shù)據(jù)接收,因此需要在發(fā)送數(shù)據(jù)時關(guān)閉UART接收中斷,直到發(fā)送完成,DE切換為RE有效,做一次讀數(shù)操作以清除中斷標(biāo)志位(該數(shù)據(jù)舍棄),然后打開UART接收中斷。程序示意如下:
void USART3_send(uint8_t *p,uint32_t len)
{
???????? uint32_t i;
???????? uint8_t Giveup;????????????????????????????????? //讀數(shù)緩沖
???????? USART_ITConfig(USART3, USART_IT_RXNE,DISABLE);?? //關(guān)閉中斷
???????? GPIO_SetBits(GPIOB , GPIO_Pin_12);??????????????? //切換DE有效
???????? ……
????????發(fā)送數(shù)據(jù)
????????……
???????? GPIO_ResetBits(GPIOB , GPIO_Pin_12);????????????? //切換RE有效
???????? Giveup=USART3->DR;??????????????????????????? //被舍棄的讀數(shù)
???????? Giveup=Giveup;???????????????????????????????? //避免編譯器報警
???????? USART_ITConfig(USART3, USART_IT_RXNE,ENABLE);?? //打開中斷
}