如题,用的是stc89c52单片机,本人新手,想做一个超声波测距小车,已实现测距,但连接小车时,小车不动,数码管闪烁。
希望实现功能:小车可以边运动边测距,距离墙50mm时可以左转,当左转四次后停止。
标红出为中断地址重叠出,希望各位大佬可以给出解决代码,谢谢大家
代码如下
- #include"reg52.h"
- #include <intrins.h>
- sbit IN1=P1^0;
- sbit IN2=P1^1;
- sbit IN3=P1^2;
- sbit IN4=P1^3;
- sbit L_PWM=P1^4;
- sbit R_PWM=P1^5;
- sbit RX=P1^7;
- sbit TX=P1^6;
- unsigned int time=0;
unsigned int timer=0;
unsigned char posit=0;
unsigned long S=0;
bit flag =0;
//--定义使用的IO--//
#define GPIO_DIG P0
#define L_go IN1=0;IN2=1
#define L_back IN1=1;IN2=0
#define L_stop IN1=0;IN2=0
#define R_go IN3=0;IN4=1
#define R_back IN3=1;IN4=0
#define R_stop IN3=0;IN4=0 - #define car_go L_go;R_go;
#define car_back L_back;R_back
#define car_left R_go;L_stop
#define car_right L_go;R_stop
#define car_stop L_stop;R_stop
#define car_left_360 R_go;L_back
#define car_right_360 L_go;R_back - //定义数码管位选控制信号
sbit LSA=P2^0;
sbit LSB=P2^1;
sbit LSC=P2^2;
sbit LSD=P2^3; - //--定义全局变量--//
unsigned char code DIG_CODE[17]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char disbuff[4] ={ 0,0,0,0,};
//数据定义
unsigned char l_tt=0; //定时器计数用 - unsigned char l_Lpwm=0; //左轮PWM占空比值,我们设计10个格,0-9,0为停止,9为全速
unsigned char l_Rpwm=0; //右轮PWM占空比值,我们设计10个格,0-9,0为停止,9为全速
/*******************************************************************************
* 函 数 名 : DigDisplay
* 函数功能 : 使用数码管显示
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void DigDisplay()
{
unsigned char i;
unsigned int j;
for(i=0;i<4;i++)
{
switch(i) //位选,选择点亮的数码管
{
case(0):
LSA=0;LSB=1;LSC=1;LSD=1; break;//显示第1位
case(1):
LSA=1;LSB=0;LSC=1;LSD=1; break;//显示第2位
case(2):
LSA=1;LSB=1;LSC=0;LSD=1; break;//显示第3位
case(3):
LSA=1;LSB=1;LSC=1;LSD=0; break;//显示第4位
}
GPIO_DIG=disbuff[ i];//发送段码
j=10; //扫描间隔时间设定
while(j--);
GPIO_DIG=0xFF;//消隐
}
}
/********************************************************/
void Conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S= (long)(time*0.17); //算出来是MM
if((S>=4000)||flag==1) //超出测量范围显示“ERR0”
{
flag=0;
disbuff[3]=0xc0; //“-”
disbuff[2]=~0x50; //“-”
disbuff[1]=~0x50; //“-”
disbuff[0]=0x86; //“-”
}
else
{
disbuff[0]=DIG_CODE[S%10000/1000];
disbuff[1]=DIG_CODE[S%1000/100];
disbuff[2]=DIG_CODE[S%100/10];
disbuff[3]=DIG_CODE[S%10/1];
}
}
/********************************************************/
void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
{
flag=1; //中断溢出标志
}
/********************************************************/
void zd3() interrupt 3 //T1中断用来扫描数码管和计800MS启动模块
{
TH1=0xf8;
TL1=0x30;
DigDisplay();
timer++;
if(timer>=100)
{
timer=0;
TX=1; //800MS 启动一次模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
}
/*********************************************************/
//TIMER0中断服务子函数产生PWM信号
void timer0()interrupt 1 using 2
{
TH0=0XFC; //定时1毫秒,10格调速,为100HZ频率,此频率下效果比较好,过大有噪声,过小振动大
TL0=0X17;
l_tt++;
if(l_tt>9)l_tt=0; //比较用,10格调速
if(l_tt<=l_Lpwm){//左调速,占空比数值越大,输出高电平时间越宽,电机转速越高,我们设计10个格,0-9,0为停止,9为全速
L_PWM=1;
}
else{
L_PWM=0;
}
if(l_tt<=l_Rpwm){//右调速,同上
R_PWM=1;
}
else{
R_PWM=0;
}
}- [ i]/*********************************************************/
- [ i] void main( void )
- [ i] { int i=0;
TMOD=0x11; //设T0为方式1,GATE=1;
TH0=0;
TL0=0;
TH1=0xf8; //2MS定时
TL1=0x30;
ET0=1; //允许T0中断
ET1=1; //允许T1中断
TR1=1; //开启定时器
EA=1; //开启总中断
car_go; //前进
while(1)
{
while(!RX); //当RX为零时等待
TR0=1; //开启计数
while(RX); //当RX为1计数并等待
TR0=0; //关闭计数
Conut(); //计算
if(S<=500)
{L_go;
i++;}
else
{car_go;}
if(i==3)
break; //左转四次后跳出循环
}
car_stop;
} - [ i]谢谢大家
|