标题:
单片机程序如何用红外实现超声波功能的开启和关闭?
[打印本页]
作者:
放眼天下
时间:
2019-3-29 17:08
标题:
单片机程序如何用红外实现超声波功能的开启和关闭?
我做了一个智能小车,用了红外线控制小车左右转动,和超声波实现简单的避障功能,但是有时候超声波执行功能的时候会影响红外线的功能使用,我想用红线的开关键通过解码直接控制超声波功能,我就直接在红外线的中断里面解码对应关掉超声波的功能,但是不知道为什么好像不太管用。请大佬帮忙看一下,初学51单片机,请多指教!
单片机源程序:
#include<reg52.h>
#include<intrins.h>
typedef unsigned int uint; //对数据类型进行声明定义
typedef unsigned char uchar;
sbit IN1=P0^0;
sbit IN2=P0^1;
sbit IN3=P0^2;
sbit IN4=P0^3;
sbit IRIN=P3^2;
sbit led3=P2^2;
sbit led8=P2^7;
sbit led7=P2^6;
sbit Trig = P2^1;
sbit Echo = P2^0;
uchar IrValue[6];
uchar Time;
static unsigned int time1=0;
unsigned long S=0;
unsigned char disbuff[4] = { 0,0,0,0,};
bit flag =0;
void delay(uint i)
{
while(i--);
}
void delayms(unsigned int ms)
{
unsigned char i=100,j;
for(;ms;ms--)
{
while(--i)
{
j=10;
while(--j);
}
}
}
//左边电机前进
void leftqian()
{
IN1=0;
IN2=1;
}
//左边电机后退
void lefthou()
{
IN1=1;
IN2=0;
}
//右边电机前进
void rightqian()
{
IN3=0;
IN4=1;
}
//右边电机后退
void righthou()
{
IN3=1;
IN4=0;
}
//初始化红外线
void IrInit()
{
IT0=1;//下降沿触发
EX0=1;//打开中断0允许
EA=1; //打开总中断
IRIN=1;//初始化端口
}
void Conut(void)
{
time1=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time1*1.7)/100; //算出来是CM
if((S>=600)||flag==1)
{
flag=0;
leftqian();
rightqian();
}
else if(S<80)
{
leftqian();
righthou();
delay(200);
// led7=1;
}
else
{
leftqian();
rightqian();
led7=0;
}
led8=0;
}
void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
{
flag=1; //中断溢出标志
}
void StartModule() //启动模块
{
Trig=1; //启动一次模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
Trig=0;
}
void main()
{
TMOD|=0x01; //设T0为方式1,GATE=1;
TH0=0;
TL0=0;
ET0=1; //允许T0中断
EA=1; //开启总中断
IrInit();
leftqian();
rightqian();
while(1)
{
switch(IrValue[2])
{
case 24: leftqian();rightqian(); break;
case 82: lefthou();righthou(); break;
case 8: lefthou();rightqian(); break;
case 90: leftqian();righthou(); break;
default : break;
}
StartModule();
led8=0;
while(!Echo); //当RX为零时等待
TR0=1; //开启计数
while(Echo); //当RX为1计数并等待
TR0=0; //关闭计数
Conut(); //计算
led8=1;
delayms(80);
}
}
void ReadIr() interrupt 0
{
uchar j,k;
uint err;
Time=0;
delay(700); //7ms
if(IRIN==0) //确认是否真的接收到正确的信号
{
err=1000; //1000*10us=10ms,超过说明接收到错误的信号
/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
侯,程序死在这里*/
while((IRIN==0)&&(err>0)) //等待前面9ms的低电平过去
{
delay(1);
err--;
}
if(IRIN==1) //如果正确等到9ms低电平
{
err=500;
while((IRIN==1)&&(err>0)) //等待4.5ms的起始高电平过去
{
delay(1);
err--;
}
for(k=0;k<4;k++) //共有4组数据
{
for(j=0;j<8;j++) //接收一组数据
{
err=60;
while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
{
delay(1);
err--;
}
err=500;
while((IRIN==1)&&(err>0)) //计算高电平的时间长度。
{
delay(10); //0.1ms
Time++;
err--;
if(Time>30)
{
return;
}
}
IrValue[k]>>=1; //k表示第几组数据
if(Time>=8) //如果高电平出现大于565us,那么是1
{
IrValue[k]|=0x80;
}
Time=0; //用完时间要重新赋值
}
}
}
if(IrValue[2]!=~IrValue[3])
{
return;
}
led3=~led3;
// if(IrValue[2]==69)
// ET0=0;
}
}
复制代码
作者:
放眼天下
时间:
2019-3-31 09:16
求助大神
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1