再次发模拟串口,51自适应波特率
时间:11-29
来源:互联网
点击:
这个是在12T的8051上面用的模拟串口程序,配合22.1184M的晶振,加上6T的双倍速,波特率可以上38400……但是我认为和某些STC的芯片比,还是差了一点,所以说,看官门看注释吧。开启帧请发送没有连续低电平的字符,类似0×55,0xff,0x7f如此等等,如果有连续低电平很容易造成判断失误……这个程序可以用在STC的自动冷启动模块里(STC15F101系列就行,很便宜的,注意是八位装载模式顺便把T1X12关了~然后补偿可以顺便减小一点,顺便说一句,用AT89C51来做也行)。这个在24M/22.1184M/11.0592M均工作正常,11.0592能到9600,24能到38400。不过,我提个醒,如果看官们真拿这个做STC冷启的时候一定要限制波特率小于等于4800。要不然的话。串口正常通讯的时候,这个模块同步上去,把你的电断了,连接掐了,然后估计你会拼命找程序是不是跑飞,浪费很多时间,……
顺便说一句,这个程序也有另外一个用途,在晶振不准的时候仍然可以和电脑以标准波特率通讯。方法就是规定好帧格式,然后上位机不停换波特率找到没有误码率的波特率,然后根据下位机的应答计算出下位机的时钟频率,这个是受了老妖ISP的启发才想到的~大家可以参考我发布的另2篇文章:模拟串口自动测量波特率的单片机程序http://www.51hei.com/mcu/1537.html,下面这个网页是用11.0592兆的晶振模拟串口接收发发送的已经通过本人测试http://www.51hei.com/mcu/1418.html
上代码:
/** 自适应波特率模拟串口程序,* BY 万致远@rwzy.co.cc* CRYSTAL:任意*/#include#include #include #define MIS_0 0#define MIS_2 1#define MIS_4 2#define MIS_8 3 #define MIS_16 4 BYTE min_mode;//减倍模式void WaitTF1(){while(!TF1);TF1=0;if(min_mode==MIS_2){// /2while(!TF1);TF1=0;}else if(min_mode == MIS_4){// /4while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;}else if(min_mode == MIS_8){// /8while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;}else if(min_mode == MIS_16){// /16while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;while(!TF1);TF1=0;}}void WByte(BYTE out){//发送启始位BYTE i=8;BYTE tmp=out;TR1=1;//开定时器TX1=0;WaitTF1();//发送8位数据位while(i--){TX1=(tmp&0x01); //先传低位tmp=tmp>>1;WaitTF1();}//发送校验位(无)//发送结束位TX1=1;WaitTF1();TR1=0;} void putchar(char ch){WByte(ch);}BYTE RByte(){BYTE in=0;BYTE cnt;while(RX1==1);//等待RXD变低,启动定时器,这个是阻塞模式TR1=1;//同步开定时器//这里……//while(!TF1);//TF1=0; WaitTF1();if(min_mode !=0){while(!TF1);//注意这里的周期稍微长。要补偿TF1=0;}for(cnt=0;cnt<8;cnt++){in=in >>1;//从高移到低if(RX1==1) in = in | 0x80;//如果RXD=1,则最高置位WaitTF1();//等待一位过去}while(!TF1);//注意这里的周期稍微长。要补偿TF1=0;TR1=0;//关闭定时器return in;}UINT f_Test(void)//测试脉宽{TMOD=0x10;//设置计数器1为方式一计数器模式TH1=0;TL1=0;//定时器CLRwhile(!RX1);//等待频率脚变高,这个是测低电平的while(RX1);//等待脚变低,更换符号可以测正脉冲TR1=1;//开启定时器while(!RX1);//等待变高TR1=0;//停止计数//cyc=TH0<8;//cyc=cyc+TL0;return (TH1<8)+TL1;}void baud_t(){BYTE k;//复用变量 ULONG frq=0; //周期变量for(k=0;k<5;k++)// 变量复用大法{frq=frq+f_Test();//测试}//测量5次取平均frq=frq/5;if(frq<0xff){k=0x100-(frq&0xff);min_mode=MIS_0;}else{if(frq / 2 < 0xff){//2400baudk=0x100-((frq/2)&0xff); //2分频min_mode=MIS_2;}else if(frq / 4 < 0xff){//1200baudk=0x100-((frq/4)&0xff);//4分频min_mode=MIS_4;}else if(frq / 8 < 0xff){//1200baudk=0x100-((frq/8)&0xff);//8分频min_mode=MIS_8;}else if(frq / 16 < 0xff){//1200baudk=0x100-((frq/16)&0xff);//16分频min_mode=MIS_16;}}if(k > 0x50){k=k+6;//加补偿,因为if语句让机器周期加长//如果对于STC的新MCU,这里要按照情况调整}TMOD=0x20;//设置定时器1为自动装载模式TH1=k;//载入新波特率TL1=k;}void main(){while(1){baud_t();//测量波特率,阻塞模式printf("Hello world!");printf("Here:mode=%d,T1=0x%X",min_mode,TH1);printf("Could you please test another baudrate?");printf("But I think that I couldnt to do.....");}}
模拟串口51自适应波特 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)