谢谢这位同窗首先作的笔记,让我明白了不少: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