??
字號:
關于串口發送程序的BUG修正
asdjf@163.com 2004/04/09
網友windysons在2004-3-24 14:12:02來信詢問如下問題:
-------------------------------------------------------------------------------
你好~我看到你寫的serial.c的文件中,有一個問題有點不明白
我把你的serial.c單獨拿出來用,沒有使用UCOS2,只想輸出一個字符PrintChar('b');
但是怎么也出不來,但是我連續調用兩次這個函數,就能輸出兩個b,
但是調用一次,什么也沒有顯示,這是為什么樣?還是你這個文件中的小BUG,謝謝!
-------------------------------------------------------------------------------
2004-3-26 11:33:20網友windysons修改程序如下:
-------------------------------------------------------------------------------
問題我已經解決,稍微改動了一下你的子程序
你的原程序是:
void PrintChar(unsigned char ch) reentrant//顯示字符
{
unsigned char *t;
//ES=0;
if( TIflag){
TIflag=0;
TI=1;
}
t=inTxBuf;t++;
if(t==TxBuf+LenTxBuf) t=TxBuf;
if(t==outTxBuf) {/*ES=1;*/return;} //TxBuf Full
*inTxBuf=ch;
inTxBuf=t;
//ES=1;
}
我改動后好使的現程序,只是把標志位判斷調到子程序最后就OK了
void PrintChar(unsigned char ch) reentrant//顯示字符
{
unsigned char *t;
//ES=0;
t=inTxBuf;t++;
if(t==TxBuf+LenTxBuf) t=TxBuf;
if(t==outTxBuf) {/*ES=1;*/return;} //TxBuf Full
*inTxBuf=ch;
inTxBuf=t;
//ES=1;
if( TIflag){
TIflag=0;
TI=1;
}
}
-------------------------------------------------------------------------------
2004-3-27 21:14:14我發現這是一個BUG
-------------------------------------------------------------------------------
在執行到PrintChar函數里TI=1一句時立即引發串口中斷發送過程,若此時顯示緩沖區為空,則串口發送中斷立即返回,導致自動連續發送過程結束,除非再次被啟動。第一次發送時,還沒有在顯示緩沖區里準備好數據就啟動發送過程,導致發送過程停止,即使隨后緩沖區里寫入數據,也要等下次啟動時才能被發出。第二次發送時,顯示緩沖區里有數據,發送中斷程序被啟動后將發出字符,發送完畢后再次引發TI中斷,因為串口速率比CPU慢,所以在下次中斷到來前CPU有時間把第二個字符寫入緩沖區。只要緩沖區里有數據,一經PrintChar首次啟動,發送中斷就能自己維持連續發送過程,直到緩沖區空。這樣,第一次發送時什么也不顯示,而第二次發送時顯示兩個字符。
在ucos51shell程序里也存在這個問題。在人機界面下,輸入help,敲入h將不顯示,繼續敲入e,顯示he,接著敲入l不顯示,再敲入p,接著顯示lp。當時百思不得其解(2002年12月),以為是任務切換導致的錯誤,又不知道如何寫內嵌匯編,就放下了。2004/02/20我在PrintChar里加入關中斷的內嵌匯編,同樣解決了這個問題。這更使我誤以為是任務切換不當造成的。現在看來,這是因為在TI=1前關中斷保證了在緩沖區里沒有存入數據前,發送中斷程序不會被執行,從而避免了中斷連續發送過程被打斷,自持過程停止需要重新啟動的問題。按你所說的方法修改serial.c,shell將正常回顯鍵盤輸入字符。
總之,在顯示緩沖區為空時不應啟動發送過程,要在準備好顯示數據后再啟動自持發送過程。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -