//使用硬件:定时器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_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;
 }
 }
}
//-----------------------------------------------------------