资讯详情

51单片机软件用定时器模拟串口程序

模拟串口用定时器完成,每一个串口要占用一个定时器,发送很好办,每次定时器中断(1BIT的时间)传送一个Bit,接收就要你好好处理了,这个我模拟的一个串口,用的W77E58,实际工作时只用到了半双工。 //使用硬件:定时器0,定时器0中断,定时器1中断,外中断5 //波特率 9600 4800 2400 1200 600 300 //每BIT周期数9696*2 96*4 96*8 96*16 96*32 //以96为单位不同的波特率选用不同的倍率 //如果对方在每位的1/2处采样,则发送中断的响应时间最多是48个时钟周期 //也许可以置发送中断以较高的优先级来解决,实验表明发送可以工作于9600 //但若有其它中断,并且串口工作于全双工,则晶体频率最好是22.1184以上 //!!实测表明当用11.0592时钟,标准51,收发同时,最高只能到2400波特。 //但单发可以工作于9600 #define BAUD_R 300 //#define BAUD_RA 600 //#define BAUD_RATE 1200 //#define BAUD_RATE 2400 //#define BAUD_RATE 4800 //#define BAUD_RATE 9600 #define clock 110592 //#define clock 221184 #define RELOAD(MER,SLUE) TIMER+=SVALUE+1 bit tTI; bit rRI; unsigned char rSBUF; unsigned char tSBUF; unsigned char rSBUF0; unsigned char RxdCnt; unsigned char rSmpCnt; unsigned char TxdCnt; unsigned char tSmpCnt; unsigned char multiple; //----------------------------------------------------------- void SimuUARTinit(void) { #if BAUD_RATE==300 if(clock==110592) multiple=32; else if(clock==221184) multiple=64; #endif #if BAUD_RATE==600 if(clock==110592) multiple=16; else if(clock==221184) multiple=32; #endif #if BAUD_RATE==1200 if(clock==110592) multiple=8; else if(clock==221184) multiple=16; #endif #if BAUD_RATE==2400 if(clock==110592) multiple=4; else if(clock==221184) multiple=8; #endif #if BAUD_RATE==4800 if(clock==110592) multiple=2; else if(clock==221184) multiple=4; #endif #if BAUD_RATE==9600 if(clock==110592) multiple=1; else if(clock==221184) multiple=2; #endif tTI=1; tT=1; rRXD=1; TMOD&=0xf0; TMOD|=0x03; ET0=1; ET1=1; TR0=1; IT0=1; EX0=1; TR1=1; PT1=1; //置串口发送为高优先级 EA=1; } //----------------------------------------------------------- //模拟串口发送中断,原定时器1中断 void IntTH0(void) interrupt 3 { RELOAD(TH0,-96); if(--tSmpCnt == 0) { tSmpCnt=multiple; if(tTI) return; switch(TxdCnt++) { case 0: tTXD=0; break; case 9: tTXD=1; tTI=1; TxdCnt=0; break; default: tTXD=tSBUF&0x01; tSBUF>>=1; break; } } } //----------------------------------------------------------- void RxdInt0(void) interrupt 0 { TL0=-96+4; //The time of inter interrup ET0=1; TF0=0; rSmpCnt=multiple/2; } //---------------------------------------------------------- //模拟串口接收中断,原定时器0中断 void IntTL0(void) interrupt 1 { RELOAD(TL0,-96); if(--rSmpCnt == 0) { rSmpCnt=multiple; switch(RxdCnt++) { case 0: if(rRXD==1){RxdCnt=0;}//ET0=0 added,no start bit found then stop interrup break; case 9: RxdCnt=0; if(rRXD==0) return; rSBUF=rSBUF0; rRI=1; break; default: if(RxdCnt>9){ RxdCnt=0;return;} rSBUF0>>=1; rSBUF0|=rRXD?0x80:0; break; } } } //-----------------------------------------------------------

-电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台