51單片機(jī)串口程序,字符串/16進(jìn)制發(fā)送與接收
字符串發(fā)送與十六進(jìn)制發(fā)送,參考:http://blog.csdn.net/yibu_refresh/article/details/22695063
本文引用地址:http://m.butianyuan.cn/article/201611/318162.htm程序皆由PC串口工具發(fā)送,由單片機(jī)接收,并返回接收值給PC機(jī)。
一:單個字符的發(fā)送與接收
#include#define uint unsigned int #define uchar unsigned char //定義接收 字符 uchar Buffer; //串口初始化函數(shù) void URATinit( ) { TMOD=0x20; SCON=0x50; EA=1; ES=1; TR1=1; TH1=0xfd; TL1=0xfd; } //中斷函數(shù) void receive() interrupt 4 { if(RI) { Buffer=SBUF; RI=0; } SBUF=Buffer; while(!TI); TI=0; } //主函數(shù) void main() { URATinit( ); }
運(yùn)行效果:
發(fā)送數(shù)據(jù)1,則返回1。
二.字符串接收
(1)
#include#define uint unsigned int #define uchar unsigned char //定義接收 數(shù)組 uchar Buffer[5]={0}; uchar i=0,j=0; //串口初始化函數(shù) void URATinit( ) { TMOD=0x20; SCON=0x50; EA=1; ES=1; TR1=1; TH1=0xfd; TL1=0xfd; } //中斷函數(shù) void receive() interrupt 4 { if(RI) { Buffer[i]=SBUF; RI=0; } SBUF=Buffer[i]; while(!TI) ; TI=0; i++; if(i>=5){ i=0; } } //主函數(shù) void main() { URATinit( ); }
運(yùn)行效果:
(2)
#include#define uint unsigned int #define uchar unsigned char //定義接收 數(shù)組 uchar Buffer[5]; uchar i=0,flag; //延時函數(shù) delay(uint ms) { uchar i; while(ms--) for(i=0;i<123;i++); } //串口初始化函數(shù) void URATinit( ) { TMOD=0x20; SCON=0x50; EA=1; ES=1; TR1=1; TH1=0xfd; TL1=0xfd; } //中斷函數(shù) void receive() interrupt 4 { if(RI) { Buffer[i++]=SBUF; RI=0; if(i>=5){ i=0; } flag=1; } } //主函數(shù) void main() { uchar k=0; for(k;k<5;k++){ Buffer[k]=0; } URATinit( ); while(1){ if(flag) { uchar j=0; for(j;j<5;j++){ SBUF=Buffer[j]; while(!TI) ; TI=0; delay(50); } flag=0; } } }
運(yùn)行效果:
其實(shí)方法(1)優(yōu)于方法(2),現(xiàn)在來發(fā)送字符串"1234"與“123456”來看看效果:
發(fā)送“1234”(發(fā)送3次):
發(fā)送“123456”(發(fā)送3次):
可以看出(1)方法總是可以正確傳輸回并顯示所發(fā)送的字符串,而(2)方法則有一定的局限性,只有當(dāng)傳輸5個字符的字符串時才可以出現(xiàn)想要的顯示效果。
分析發(fā)現(xiàn):(1)中在中斷中直接發(fā)出收到的字符,接收一個發(fā)送一個,為實(shí)時效果。(2)則在主程序中整體發(fā)送接收到的Buffer數(shù)組,例如接收“1234”,當(dāng)“1234”發(fā)過來的時候由于Buffer為5位數(shù)組,因此第一次發(fā)送會給Buffer[0-3]賦值,Buffer[4]未賦值,返回給上位機(jī)第一次輸出為“1234”,但第二次發(fā)送時候會給Buffer[4]賦值,同時溢出把i歸為0。再次輸出Buffer時造成了傳輸字符串的重疊與混亂。其實(shí)(1)也有這個現(xiàn)象,只是(1)的返回為及時返回。
三. 字符串發(fā)送與十六進(jìn)制發(fā)送:
#include#define uchar unsigned char #define uint unsigned int uchar num; sbit dula=P2^6; //申明U1鎖存器的鎖存端 sbit wela=P2^7; //申明U2鎖存器的鎖存端 uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delay(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延時約xms毫秒 for(j=110;j>0;j--); } void display(uint value) //顯示子函數(shù) { uchar wan,qian,bai,shi,ge; //定義萬千百十個位 wan=value/10000; qian=value%10000/1000; bai=value%1000/100; shi=value%100/10; ge=value%10; dula=1; P0=table[wan]; dula=0; P0=0xff; wela=1; P0=0xfe; wela=0; delay(2); dula=1; P0=table[qian]; dula=0; P0=0xff; wela=1; P0=0xfd; wela=0; delay(2); dula=1; P0=table[bai]; dula=0; P0=0xff; wela=1; P0=0xfb; wela=0; delay(2); dula=1; P0=table[shi]; dula=0; P0=0xff; wela=1; P0=0xf7; wela=0; delay(2); dula=1; P0=table[ge]; dula=0; P0=0xff; wela=1; P0=0xef; wela=0; delay(2); } void init() //初始化函數(shù) { TMOD=0x20; //設(shè)置定時器1工作方式 TH1=0xfd; TL1=0xfd; TR1=1; SM0=0; SM1=1; REN=1; EA=1; ES=1; } void main() { init(); while(1) { display(num); } } void ser() interrupt 4 //串口中斷函數(shù) { if(RI){ num=SBUF; RI=0; } //置RI為0以便接收下一個數(shù)據(jù) SBUF=num; while(!TI); TI=0; }
先發(fā)送字符‘a’,即默認(rèn)的字符串發(fā)送方式:
發(fā)送字符‘a’,這時單片機(jī)返回給上位機(jī)的也為‘a’(默認(rèn)的字符串顯示方式)。但是數(shù)碼卻顯示97,為‘a’的ASCII碼。這說明在傳輸過程中,始終為ASCII碼傳輸。數(shù)碼管之所以沒顯示‘a’,因?yàn)閿?shù)碼管為十進(jìn)制顯示方式,故顯示97。(‘a’(ASCII顯示)——>97(十進(jìn)制顯示)——>a(ASCII碼顯示))
發(fā)送字符‘a’,選擇16進(jìn)制發(fā)送,16進(jìn)制顯示:
這時發(fā)送端為16進(jìn)制‘a’,即10進(jìn)制的10。數(shù)碼管顯示10,而返回的值用16制顯示為0A。
由文章開始的參考文章知道16進(jìn)制發(fā)送時每次發(fā)送兩位數(shù)據(jù),如:發(fā)送十進(jìn)制20,即16進(jìn)制的14,這時數(shù)碼管會顯示20。(14(16進(jìn)制顯示)——>20(10進(jìn)制顯示)——>14(16進(jìn)制顯示))。
評論