開始我把FIFO看得過於神秘(雖然定義很明確,先入先出緩衝區),外加發送緩衝區和FIFO入口地址一樣。發送緩衝區時16位的,低8位為資料區,而FIFO單位以位元組算起(實際是字元,因為每幀資料有起始位和停止位等等)。搞得我一頭霧水,它的工作機制是怎麼樣的? 本人實在是能力有限,搞一下午才弄明白。FIFO定義說了,先入先出緩衝區,在UART中有什麼用呢。我們可以用它來批量發送資料(而非FIFO模式,只能一位元組一位元組的發,而且發每個位元組都需要等待緩衝區變空才能發送下一位元組),這樣能在一定程度上提高資料發送速度。還有就是避免資料包的的丟失(這個問題,目前還沒體會)。
對於使用,說一下原理,代碼很簡單可用輪詢或中斷模式。
1、再輪詢模式下的FIFO,首先我們需要配置相關寄存器,這個我就不多說了我想大家都知道該怎麼配置。然後對於FIFO我們基本不需要關心什麼,只要保證FIFO緩衝區不溢出就可以了。如何查詢溢出?通過查詢UFSTATn BIT[7:4]即可。或bit【9】。可以在FIFO中資料滿8位元組做一下停頓 (做個小延遲讓FIFO發送,可避免發送溢出,但不適於高速場合) 用 while(rUFSTAT0&0x0010); 來實現,也可以在9位元組,10位元組等等 。當然一位元組也可以(1位元組貌似沒多大意思,跟沒用FIFO一樣了)。喜歡在容納第幾個位元組做停頓都可以,不過要考慮傳輸速度的最佳化。做短暫停頓目的是,避免FIFO溢出。要是不做停頓,會溢出(寫入失敗)遺失資料。
2、在中斷模式下的FIFO原理跟輪詢差不多,在FIFO中資料=UFCON中設定的觸發位元組時,進入中斷,全部資料的傳輸的結束是在中斷中完成的。這樣也是避免了FIFO的溢出,達到觸發時進入中斷服務,在中斷服務內完成如下
void __irq Uart0_TxFifoInt(void)
{
/* 判斷FIFO發送緩衝區是否為滿或字串結束 */
while( !(rUFSTAT0 & 0x200) && (*uart0TxStr !='/0'))//如果緩衝區滿,退出中斷,滿足觸發條件即=觸發位元組時再進入中斷,使FIFO資料量穩定在一個水平,而又不至於溢出(本人片解,不排除理解錯誤)
{
rUTXH0=*uart0TxStr++;
for(i=0;i<700;i++); //延遲,防止FIFO誤寫
}
rI_ISPC=BIT_UTXD0;
if(*uart0TxStr == '/0')
{
rINTMSK |= BIT_UTXD0;
rI_ISPC=BIT_UTXD0;
}
}
用FIFO發送資料時,若所用為輪詢法(用在非高速場合,高速場合最好用BDMA或中斷法,故此輪詢法很少用)需要保證接受FIFO不溢出,類似中斷法,通過軟體來設定觸發條件。例如if(rUFSTAT0&0x000f>0x0008)觸發讀為FIFO內有8位元組資料。但是我們同時還要考慮,不能空讀接收FIFO,例如while((rUFSTAT0&0x000F)>0x0000){ 讀接收FIFO}。這種輪詢法比較山寨,穩定性不咋地,適用低速。不提倡使用。
DIY