我对外部中断0、1和定时器1做中断,用超声波测距,定时器0做计数器用来计时,每测三个是一组,但是每个中断计数前面的一组第一个总是会影响到后面的一组的第一个(如果实际结果是前面的数小于后面的数),下面是程序,麻烦高手指教,谢谢
#include
#include
#define RELOAD_COUNT 0xfd //9600bps
void delay (unsigned int a)
{
for(;a>0;a--)
{;}
}
void defaultset ()
{
P1M1=0;
P1M0=0XFF; //强推挽输出
AUXR = 0X11; //工作在12T模式 独立波特率,T1被解放
AUXR1 = 0X00; //串口输出在P3
PCON=0x00; //SMOD=0;
SCON=0x50; //工作方式1 波特率9600 允许接收
BRT=RELOAD_COUNT; //STC系列单片机设置波特率
IP=0X02; //将T1的中断优先级设为最高
}
void main ()
{
defaultset ();
RI=0;
while(1)
{
if (RI)
{
RI=0;
switch (SBUF)
{
case 'E': {
TMOD=0x02; //计时器工作在方式2
TR1=0; //关毕计时器1
TR0=0; //关闭计时器0
TH0=0; //
TL0=0; // 对计时器0置0
EA=1; //开总中断
IP=0X02; //将计时器0优先级设为最高
EX0=0; //关外中断INT0
EX1=1; //开外中断1
ET1=0; //关定时中断1
ET0=1; //开定时中断0
TH0=0xe9; //产生40KHZ脉冲,故初始数为0XE9
TL0=0xe9;
P1=0x02; //在P11和P12两个管脚上的超声波探头两端置高低电平
TR0=1; //开定时器0
delay(5000);
TMOD=0x02; //计时器工作在方式2
TR1=0; //关毕计时器1
TR0=0; //关闭计时器0
TH0=0; //
TL0=0; // 对计时器0置0
EA=1; //开总中断
IP=0X02; //将计时器0优先级设为最高
EX0=1; //开外部中断INT0
EX1=0; //关外部中断INT1
ET1=0; //关定时中断1
ET0=1; //开定时中断1
TH0=0xe9; //产生40KHZ脉冲,故初始数为0XE9
TL0=0xe9;
P1=0x02; //在P11和P12两个管脚上的超声波探头两端置高低电平
TR0=1; //开定时器0
delay(5000);
TMOD=0x62; //计时器0工作在方式2 计时器1工作方式为2,设为计数模式
TR1=0; //关毕计时器1
TR0=0; //关闭计时器0
TH0=0; //
TL0=0; // 对计时器0置0
EA=1; //开总中断
IP=0X02; //将计时器0优先级设为最高
EX0=0; //关闭外部中断INT0
EX1=0; //关闭外部中断INT1
ET1=1; //开外部中断1
TR1=1; //开定时中断1
ET0=1;
TH1=0xFF; //外部超声波产生一个脉冲即要求单片机中断,故设为0XFF
TL1=0xFF;
TH0=0xe9; //产生40KHZ脉冲,故初始数为0XE9
TL0=0xe9;
P1=0x02; //在P11和P12两个管脚上的超声波探头两端置高低电平
TR0=1; //开定时器0
delay(5000);
break;}
case 'F':
{
TMOD=0x02; //计时器工作在方式2
TR1=0; //关毕计时器1
TR0=0; //关闭计时器0
TH0=0; //
TL0=0; // 对计时器0置0
EA=1; //开总中断
IP=0X02; //将计时器0优先级设为最高
EX0=0; //关外中断INT0
EX1=1; //开外中断1
ET1=0; //关定时中断1
ET0=1; //开定时中断0
TH0=0xe9; //产生40KHZ脉冲,故初始数为0XE9
TL0=0xe9;
P1=0x08; //在P11和P12两个管脚上的超声波探头两端置高低电平
TR0=1; //开定时器0
delay(5000);
TMOD=0x02; //计时器工作在方式2
TR1=0; //关毕计时器1
TR0=0; //关闭计时器0
TH0=0; //
TL0=0; // 对计时器0置0
EA=1; //开总中断
IP=0X02; //将计时器0优先级设为最高
EX0=1; //开外部中断INT0
EX1=0; //关外部中断INT1
ET1=0; //关定时中断1
ET0=1; //开定时中断1
TH0=0xe9; //产生40KHZ脉冲,故初始数为0XE9
TL0=0xe9;
P1=0x08; //在P11和P12两个管脚上的超声波探头两端置高低电平
TR0=1; //开定时器0
delay(5000);
TMOD=0x62; //计时器0工作在方式2 计时器1工作方式为2,设为计数模式
TR1=0; //关毕计时器1
TR0=0; //关闭计时器0
TH0=0; //
TL0=0; // 对计时器0置0
EA=1; //开总中断
IP=0X02; //将计时器0优先级设为最高
EX0=0; //关闭外部中断INT0
EX1=0; //关闭外部中断INT1
ET1=1; //开外部中断1
TR1=1; //开定时中断1
ET0=1;
TH1=0xFF; //外部超声波产生一个脉冲即要求单片机中断,故设为0XFF
TL1=0xFF;
TH0=0xe9; //产生40KHZ脉冲,故初始数为0XE9
TL0=0xe9;
P1=0x08; //在P11和P12两个管脚上的超声波探头两端置高低电平
TR0=1; //开定时器0
delay(5000);
break; }
case 'G':
{
TMOD=0x02; //计时器工作在方式2
TR1=0; //关毕计时器1
TR0=0; //关闭计时器0
TH0=0; //
TL0=0; // 对计时器0置0
EA=1; //开总中断
IP=0X02; //将计时器0优先级设为最高
EX0=0; //关外中断INT0
EX1=1; //开外中断1
ET1=0; //关定时中断1
ET0=1; //开定时中断0
TH0=0xe9; //产生40KHZ脉冲,故初始数为0XE9
TL0=0xe9;
P1=0x20; //在P11和P12两个管脚上的超声波探头两端置高低电平
TR0=1; //开定时器0
delay(5000);
TMOD=0x02; //计时器工作在方式2
TR1=0; //关毕计时器1
TR0=0; //关闭计时器0
TH0=0; //
TL0=0; // 对计时器0置0
EA=1; //开总中断
IP=0X02; //将计时器0优先级设为最高
EX0=1; //开外部中断INT0
EX1=0; //关外部中断INT1
ET1=0; //关定时中断1
ET0=1; //开定时中断1
TH0=0xe9; //产生40KHZ脉冲,故初始数为0XE9
TL0=0xe9;
P1=0x20; //在P11和P12两个管脚上的超声波探头两端置高低电平
TR0=1; //开定时器0
delay(5000);
TMOD=0x62; //计时器0工作在方式2 计时器1工作方式为2,设为计数模式
TR1=0; //关毕计时器1
TR0=0; //关闭计时器0
TH0=0; //
TL0=0; // 对计时器0置0
EA=1; //开总中断
IP=0X02; //将计时器0优先级设为最高
EX0=0; //关闭外部中断INT0
EX1=0; //关闭外部中断INT1
ET1=1; //开外部中断1
TR1=1; //开定时中断1
ET0=1;
TH1=0xFF; //外部超声波产生一个脉冲即要求单片机中断,故设为0XFF
TL1=0xFF;
TH0=0xe9; //产生40KHZ脉冲,故初始数为0XE9
TL0=0xe9;
P1=0x20; //在P11和P12两个管脚上的超声波探头两端置高低电平
TR0=1; //开定时器0
delay(5000);
break; }
// case 'D':
}
}
}
}
void INT0_ (void) interrupt 0 //中断零,对应Y2
{
unsigned int p=0;
unsigned int q=0;
char buff[10],a;
EA=0;
TR0=0;
p=TH0;
q=TL0;
TH0=0;
TL0=0;
p=(p/16)*16*16*16+(p%16)*16*16+(q/16)*16+q%16; //将定时器零上的数转化为一个十进制数
q=0;
while(p>0) //将转化出的十进制 数放到buff这个数组当中
{a=p%10+0x30;
buff[q]=a;
q++;
p=p/10;
}
while(q>0) //将buff中数据依次发送出去
{
SBUF=buff[q-1];
while(TI==0);
TI=0;
q--;
}
SBUF='A';
while(TI==0); //为方便区分每次输出数据后均跟一个相应的字母
TI=0;
SBUF='\n';
while(TI==0);
TI=0;
}
void INT1_ (void) interrupt 2 //中断源2,对应Y1
{
unsigned int p=0;
unsigned int q=0;
char buff[10],a;
EA=0;
TR0=0;
p=TH0;
q=TL0;
p=(p/16)*16*16*16+(p%16)*16*16+(q/16)*16+q%16;
q=0;
while(p>0)
{a=p%10+0x30;
buff[q]=a;
q++;
p=p/10;
}
while(q>0)
{
SBUF=buff[q-1];
while(TI==0);
TI=0;
q--;
}
SBUF='B';
while(TI==0);
TI=0;
SBUF='\n';
while(TI==0);
TI=0;
}
void INTIME1_ (void) interrupt 3 //中断源3,即定时器1,对应Y3
{
unsigned int p=0;
unsigned int q=0;
char buff[10],a;
EA=0;
TR0=0;
p=TH0;
q=TL0;
TR1=0;
TF1=0;
p=(p/16)*16*16*16+(p%16)*16*16+(q/16)*16+q%16;
q=0;
while(p>0)
{a=p%10+0x30;
buff[q]=a;
q++;
p=p/10;
}
while(q>0)
{
SBUF=buff[q-1];
while(TI==0);
TI=0;
q--;
}
SBUF='C';
while(TI==0);
TI=0;
SBUF='\n';
while(TI==0);
TI=0;
}
void INT_TIME0(void) interrupt 1
{
TF0 = 0; //定时器溢出标志清零
TR0=0;
P1 = ~P1; //对单片机管脚取反,从而使每一个探头两端的正负极颠倒,从而触发超声波
TMOD=0x61; //改变定时器0的计数方式,以计算从超声波探头发射超声波到下面的探头接收到超声波的时间
TH0=0; //对计时器0重新清零
TL0=0;
TR0 = 1; //开定时器一,开始计时
}
有兴趣的话可以参看一下http://topic.eeworld.net/u/20090722/15/6009c1d2-93bc-47dc-a646-70bc2968ac49.html中关于定时器多任务复用的实现,也是51系列的。正好我也是在用stc,可以交流一下
ls的ls不是对单片机c程序写法还有格式比较有体会,
lz可以和他交流一下