您的位置 首页 电源

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

模拟串口用定时器完成,每一个串口要占用一个定时器,发送很好办,每次定时器中断(1BIT的时间)传送一个Bit,接收就要你好好处理了,这个我模拟

模仿串口定时器完结,每一个串口要占用一个定时器,发送很好办,每次定时器中止(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_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 startbitfound 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;
}
}
}
//———————————————————–

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/dianyuan/318522.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部