近期白嫖君在使用GD32這款芯片時(shí)候,發(fā)現(xiàn)了一個(gè)大概率是芯片設(shè)計(jì)上的BUG,貼出來(lái)和大家分享一下。
我們?cè)谑褂么诎l(fā)送數(shù)據(jù)時(shí),無(wú)非是使用兩種方法,一種是逐字節(jié)發(fā)送,另一種是DMA發(fā)送。

一般串口發(fā)送數(shù)據(jù)前,我們需要先查看TBE標(biāo)志位,判斷緩存區(qū)內(nèi)是不是已經(jīng)空了,如果空了我們才會(huì)往里填數(shù)據(jù)。
但是當(dāng)發(fā)送緩存區(qū)為空時(shí),并不代表我們的數(shù)據(jù)已經(jīng)實(shí)際發(fā)完了,只是代表緩存區(qū)內(nèi)的數(shù)據(jù)空了,這時(shí)物理意義上的發(fā)送可能還在進(jìn)行中,如果你使用RS485器件,這時(shí)候把發(fā)送使能關(guān)斷的話,就會(huì)丟失一個(gè)字節(jié)的數(shù)據(jù)。
因此,一般發(fā)送完成后,需要檢查TC標(biāo)志是不是已經(jīng)被拉高了,以此來(lái)判斷數(shù)據(jù)線上的數(shù)據(jù)是不是確實(shí)已經(jīng)發(fā)結(jié)束了。
void usart_sendbuf(uint32_t usart_periph, uint8_t *Buffer , uint16_t ucSend_num)
{
unsigned int i;
usart_flag_clear(usart_periph, USART_FLAG_TC); //在發(fā)送前要先清除TC
for(i = 0; i < ucSend_num; i++)
{
while(usart_flag_get(usart_periph, USART_FLAG_TBE) == RESET);
usart_data_transmit(usart_periph, Buffer[i]);
}
while(usart_flag_get(usart_periph,USART_FLAG_TC)==RESET);
}
這次白嫖君的程序就是還按照這個(gè)套路來(lái)寫的,串口發(fā)送數(shù)據(jù)量比較大,在運(yùn)行一段時(shí)間后,程序突然就死機(jī)了,查看一下,是死在了最后一行等待TC標(biāo)志位這里。查看寄存器列表,TC始終為0。
下面是官方庫(kù)函數(shù)手冊(cè)上給出的說(shuō)明:
TC標(biāo)識(shí)是受單片機(jī)硬件控制的,并不受程序影響,這里無(wú)法拉高九成九就是芯片BUG了,于是白嫖君谷歌了一下,發(fā)現(xiàn)也有人遇到類似問(wèn)題:
針對(duì)這種情況,硬件上無(wú)法做出改善,只能從軟件上規(guī)避了:
void usart_sendbuf(uint32_t usart_periph, uint8_t *Buffer , uint16_t ucSend_num)
{
uint32_t i;
uint32_t j = 0;
usart_flag_clear(usart_periph, USART_FLAG_TC); //為了使用TC,在發(fā)送前要先清除TC
for(i = 0; i< ucSend_num; i++)
{
while(usart_flag_get(usart_periph, USART_FLAG_TBE) == RESET);
usart_data_transmit(usart_periph, Buffer[i]);
}
while(usart_flag_get(usart_periph, USART_FLAG_TC) == RESET)
{
if(j++ >= 0xFFFF) //在這里加超時(shí)機(jī)制
{
break;
}
}
}
引入超時(shí)機(jī)制,當(dāng)?shù)却龝r(shí)間超過(guò)設(shè)定閾值,則不再等待TC置位,以此來(lái)避免程序阻塞假死。
特別注意:出現(xiàn)這種情況目前來(lái)說(shuō)可能GD全系都有可能存在這個(gè)問(wèn)題,且不區(qū)分是USART0還是USARTx,同時(shí)似乎只在數(shù)據(jù)量較大時(shí)會(huì)出現(xiàn)此種情況。我以前用GD的片子也不少,從沒(méi)遇見(jiàn)過(guò)這種情況。特此說(shuō)明,避免抬杠嘛~
審核編輯 :李倩
-
芯片
+關(guān)注
關(guān)注
459文章
52505瀏覽量
440772 -
單片機(jī)
+關(guān)注
關(guān)注
6067文章
44991瀏覽量
650397
原文標(biāo)題:國(guó)產(chǎn)單片機(jī)GD32 串口發(fā)送再現(xiàn)BUG?
文章出處:【微信號(hào):嵌入式電子創(chuàng)客街,微信公眾號(hào):嵌入式電子創(chuàng)客街】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
如何在Android設(shè)備上安裝Cyusb3014芯片驅(qū)動(dòng)?
芯片流片失敗都有哪些原因

Gui Guiderv1.9.0使用下拉框控件問(wèn)題,出現(xiàn)bug不顯示list選項(xiàng)怎么解決?
AI在芯片上的應(yīng)用:革新設(shè)計(jì)與功能
移動(dòng)端設(shè)備上稀奇古怪的前端問(wèn)題收集(一)
使用SIGMA STUDIO PLUS對(duì)連接在ADAU1452 SPI上的FLASH進(jìn)行編程時(shí),程序并不能成功的寫入flash怎么解決?
KiCon 演講回顧(十五):提交 Kicad Bug



eeprom芯片用在什么上
TAS5630B芯片的12V和地短路了,芯片不在板子上,為什么?怎么解除?
引腳封裝HotRod和FC-SOT上倒裝芯片的降額和壽命計(jì)算

一般ram芯片上的引腳有哪些
stm32H7 HAL庫(kù)中存在的bug
底部填充工藝在倒裝芯片上的應(yīng)用

評(píng)論