模拟串口用定时器完成,每一个串口要占用一个定时器,发送很好办,每次定时器中断(1BIT的时间)传送一个Bit,接收就要你好好处理了 这个我模拟的一个串口,用的W77E58,实际工作时只用到了半双工
//使用硬件:定时器0,定时器0中断,定时器1中断,外中断5 //波特率 9600 4800 2400 1200 600 300 //每BIT周期数 96 96*2 96*4 96*8 96*16 96*32 //以96为单位不同的波特率选用不同的倍率 //如果对方在每位的1/2处采样,则发送中断的响应时间最多是48个时钟周期 //也许可以置发送中断以较高的优先级来解决,实验表明发送可以工作于9600 //但若有其它中断,并且串口工作于全双工,则晶体频率最好是22.1184以上 //!!实测表明当用11.0592时钟,标准51,收发同时,最高只能到2400波特。 //但单发可以工作于9600 //----------------------------------------------------------- #define BAUD_RATE 300 //#define BAUD_RATE 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(TIMER,SVALUE) 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; tTXD=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; } } } //-----------------------------------------------------------
|