謝謝這位同窗首先作的筆記,讓我明白了不少:http://www.cnblogs.com/freesblog/p/5040474.htmlhtml
剛開始也是一直亂碼,直到昨天我才解決了亂碼的問題,原來這一切都是晶振頻率惹的禍,今天開始不會亂碼了。能夠發送單個字符了。可是又出現了一個新的問題,一個很長的字符串怎麼辦?
不少人想,那好辦啊,下面這個程序就能夠:函數
/*發送一個字符串*/ void send_string(uchar *p){ while(*p!= '\0'){ send_byte(*p); p++; } }
這樣不就能夠實現字符串的發送了嗎?是的,沒錯,可是在send_byte()這個函數裏面該怎麼寫?其實這個函數寫很差很容易和中斷函數衝突。
固然,你能夠這樣寫:ui
/*發送一個字符*/ void send_byte(uchar by){ SBUF = by; while(!TI);//等待發送完畢 TI = 0; }
若是你這樣寫了,那麼你要麼不要打開串口中斷,要麼就在串口中斷裏面什麼都不寫(若是你只是發送,不接收的話),這裏只是講發送,接收是一個道理的。若是你在中斷函數裏面寫了下面這樣的程序:spa
void uart_interrupt() interrupt 4{ if(RI==1)RI = 0; if(TI==1)TI = 0; }
那麼,恭喜你,你不會在電腦端收到任何數據的(不對,你能收到字符串的第一個字符)。緣由很簡單:code
當一個字符發送/接收完畢的時候 ,發送/接收標誌位TI/RI會自動置1,若是你在初始化裏面打開了串口中斷的話,程序必定進入中斷函數裏面去執行:if(TI==1)TI = 0;而不是先執行while(!TI);//等待發送完畢
,因此,在中斷裏面TI又置了0,而後回到while(!TI);這樣,就陷入了一個死循環。你的程序就卡在這裏了。htm
總結:
當你發現沒法發送字符串的 時候,首先檢查本身的比特率是否對,就是檢查能不能發送單個字符,若是單個字符發送沒有問題,那麼必定能發送字符串。
接下來檢查你的初始化程序中有沒有打開 串口中斷。若是打開,看中斷函數 有沒有和單個字符發送函數衝突。
固然,當你只是發送數據的話,不接受,不打開串口中斷也是能夠的,就是本身手動清零中斷標誌。blog
下面附上源程序(親測可用):字符串
#include "reg52.h" #include "stdio.h" #define uchar unsigned char #define uint unsigned int void uart_cfg(); void send_byte(uchar by); void send_string(uchar *p); void delayms(uchar i); uchar str[] = "yes,you aer good!"; void main(){ uart_cfg(); //波特率4800 ,0xf9 while(1){ send_string(str); delayms(100); } } void uart_cfg(){ SCON = 0X50;//MODE 1 TMOD&= 0X0F;//清除T1的控制位 TMOD|= 0X20;//T1的工做模式2 PCON|= 0X80;//倍頻 TH1 = 0xf3; //4800 TL1 = TH1; ET1 = 0;//禁止T1中斷 // EA = 1; TR1 = 1; // ES = 1;//使能串口中斷 ,不管是TI/RI出現,只要中斷打開,單片機就進入中斷函數。 } /*中斷處理函數*/,如上面所說,寫不寫都同樣。這裏我屏蔽掉了 // void uart_interrupt() interrupt 4{ // // if(RI==1)RI = 0; // // if(TI==1); // //TI = 0; // } /*發送一個 字符*/ void send_byte(uchar by){ SBUF = by; while(!TI);//當寫下這句的時候,就不要在中斷函數裏面在寫TI = 0;這句了,否則進入中斷函數將TI清零以後,程序就會一直卡在這裏 TI = 0; //在這裏將TI清零 } /*發送一個字符串*/ void send_string(uchar *p){ while(*p!= '\0'){ send_byte(*p); p++; } } /*簡單延時*/ void delayms(uchar i) { uint j; while(i--) { for(j = 0; j < 150; j++); } }
發送成功:get