第六篇----红外光走直线不穿墙
时间:10-02
整理:3721RD
点击:
上篇遗留了一个历史问题,需要用pwm来解决电机速度的问题,也就是车速的问题,我们尝试下,再增加两个遥控器的功能键,调节车速。两个问题,占空比,调速。
直接贴代码,代码水平不高,仅实现功能,欢迎功力深厚的童鞋可以当头棒喝,
/******************************************************************
** 头文件
******************************************************************/
#include<AT89X52.H>
bit Right_moto_stop=1;
bit Left_moto_stop =1;
/******************************************************************
** 接线定义
******************************************************************/
#define Left_moto_go {Left_moto_stop=1;P1_2=1,P1_3=0;} //左电机正转
#define Left_moto_back {Left_moto_stop=1;P1_2=0,P1_3=1;} //左电机反转
#define Right_moto_go {Right_moto_stop=1;P1_4=1,P1_5=0;} //右电机正转
#define Right_moto_back {Right_moto_stop=1;P1_4=0,P1_5=1;} //右电机反转
#define Left_moto_Stop {Left_moto_stop=0;} //左电机停转
#define Right_moto_Stop {Right_moto_stop=0;} //右电机停转
#define Left_moto_pwm P1_0 //PWM信号端
#define Right_moto_pwm P1_1 //PWM信号端
//sbit BUZZ = P3^6; //蜂鸣器引脚
/******************************************************************
** 红外遥控器的相关定义
******************************************************************/
#define Imax 14000 //此处为晶振为11.0592时的取值,
#define Imin 8000 //如用其它频率的晶振时,
#define Inum1 1450 //要改变相应的取值。
#define Inum2 700
#define Inum3 3000
/******************************************************************
** 变量定义
******************************************************************/
unsigned char f=0;
unsigned char Im[4]={0x00,0x00,0x00,0x00};
unsigned char show[2]={0,0};
unsigned long m,Tc;
unsigned char IrOK;
/******************************************************************
** PWM调速相关变量
******************************************************************/
unsigned char pwm_val_left =0; //变量定义
unsigned char push_val_left =5; //左电机占空比N/20
unsigned char pwm_val_right =0;
unsigned char push_val_right=5; //右电机占空比N/20
/******************************************************************
** 延时函数
******************************************************************/
void delay(unsigned int k)
{
unsigned int x,y;
for(x=0;x<k;x++)
for(y=0;y<2000;y++);
}
/******************************************************************
** 小车减速
******************************************************************/
void low(void)
{
if(push_val_left>1)
{
push_val_left--;
push_val_right--;
}
}
/******************************************************************
** 小车加速
******************************************************************/
void hearry(void)
{
if(push_val_left<20)
{
push_val_left++;
push_val_right++;
}
}
/******************************************************************
** 小车前进
******************************************************************/
void front_run(void)
{
Left_moto_go;
Right_moto_go;
}
/******************************************************************
** 小车左转
******************************************************************/
void left_run(void)
{
Left_moto_back;
}
/******************************************************************
** 小车右转
******************************************************************/
void right_run(void)
{
Right_moto_back;
}
void back_run(void)
{
Left_moto_back;
Right_moto_back;
}
/******************************************************************
** 小车停走
******************************************************************/
void stop(void)
{
Left_moto_Stop;
Right_moto_Stop;
}
/******************************************************************
** 左电机调速
******************************************************************/
void pwm_out_left_moto(void)
{
if(Left_moto_stop)
{
if(pwm_val_left<=push_val_left)
{
Left_moto_pwm=1;
}
else
{
Left_moto_pwm=0;
}
if(pwm_val_left>=20)
pwm_val_left=0;
}
else
{
Left_moto_pwm=0;
}
}
/******************************************************************
** 右电机调速
******************************************************************/
void pwm_out_right_moto(void)
{
if(Right_moto_stop)
{
if(pwm_val_right<=push_val_right)
{
Right_moto_pwm=1;
}
else
{
Right_moto_pwm=0;
}
if(pwm_val_right>=20)
pwm_val_right=0;
}
else
{
Right_moto_pwm=0;
}
}
/******************************************************************
** 定时器1初始化
******************************************************************/
void timer1_Init(void)
{
//EA=1; //开总中断
ET1=1; //定时器T1中断允许
TMOD|=0x10; //TMOD=0001 0000B,使用定时器T1的模式1
TH1=0XFc; //1ms定时 //定时器T1的高8位赋初值
TL1=0X18; //定时器T1的高8位赋初值
TR1=1; //启动定时器T1
}
/******************************************************************
** 定时器1中断服务子程序
******************************************************************/
void timer1(void) interrupt 3 using 0 //
{
TH1=0XFc; //定时器T1的高8位重新赋初值
TL1=0X18; //定时器T1的高8位重新赋初值
pwm_val_left++;
pwm_val_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}
/******************************************************************
** 外部中断解码程序
******************************************************************/
void intersvr0(void) interrupt 0 using 1
{
Tc=TH0*256+TL0; //提取中断时间间隔时长
TH0=0;
TL0=0; //定时中断重新置零
if((Tc>Imin)&&(Tc<Imax))
{
m=0;
f=1;
return;
} //找到启始码
if(f==1)
{
if(Tc>Inum1&&Tc<Inum3)
{
Im[m/8]=Im[m/8]>>1|0x80; m++;
}
if(Tc>Inum2&&Tc<Inum1)
{
Im[m/8]=Im[m/8]>>1; m++; //取码
}
if(m==32)
{
m=0;
f=0;
if(Im[2]==~Im[3])
{
IrOK=1;
}
else IrOK=0; //取码完成后判断读码是否正确
}
//准备读下一码
}
}
/******************************************************************
** 主函数
******************************************************************/
void main(void)
{
m=0;
f=0;
EA=1;
IT0=1;
EX0=1;
TMOD=0x11;
TH0=0;
TL0=0;
TR0=1;
timer1_Init();
delay(100);
while(1) /*无限循环*/
{
if(IrOK==1)
{
switch(Im[2])
{
case 0x18:
front_run(); //前进
break;
case 0x52:
back_run(); //后退
break;
case 0x08:
front_run();
left_run(); //左转
break;
case 0x5A:
front_run();
right_run(); //右转
break;
case 0x1C:
stop(); //停止
break;
case 0x07:
low(); //减速
break;
case 0x15:
hearry(); //加速
break;
default:
break;
}
IrOK=0;
}
}
}
这里边用到了timer0 和timer1两个计时器,一个用来红外解码,一个用来控制占空比调节转速,再增加两个调速键调节占空比。
红外的遥控器大家都玩耍过,从遥控的应用这个角度看,红外这东其实和红光没啥区别,除了波长,它是波长780~2526nm的光线,估计一般人的凡胎肉眼看不见,我觉得可能有极其个别的童鞋能看到吧,这个可见光的波长范围是780(红)~380(紫)nm,你说有个光的波长是781nm或者是379nm,地球上所有人都看不见了么?不见得吧,那么779nm或者381nm的所有童鞋都能看见吗?不见得吧,这本身应该是个统计值,绝大多数地球人的视网膜能感觉到这个范围的光,又跑题了。拉回来,我想说的是,红外光不能红杏穿墙,据说原因是红外光虽是一种波长较长的光,但比起声波其波长还是极其小的,不可能与现实中的障碍物发生衍射而绕过,因而红外夜视仪是不能看穿墙的,看不见MO7号的时候,也无法遥控了,为了解决这个问题,我们又需要动脑了,哎,没有办法,不想动腿儿就得动脑。
又翻了翻家当,发现,小车上这个核心板需要加强了,需要这个,
无线收发用到了PT2262/2272编码/解码芯片,相信有很多童鞋都玩耍过,先来看看原理图
这是扩展板上的无线的接收端芯片
这是连到主板上的接口定义,仔细看一下,只用了六根线,Vcc GND还有D0~D3四根数据线,因为无线遥控器就4个键,D4没有意义了
验证一下,是不是6根线,上图,
按下a,显示正确
这个开发板上用的是P1口接受无线遥控数据,MO7号的上边P1口用来控制车轮了,我们改下程序用P2口收,先接到MO7号上,电路通了,扩展板上的led接到遥控信号后会亮,应该是没接错,改下程序。
P2口用作输入,红外遥控增加切换键已决定是否采用无线遥控,
给红外增加一个无线控制切换键,由于红外遥控器年久失修,有一个键失灵了,恰巧切换无线用到了这个键,唉,折腾了半天。
于是,MO7号现在能被红外和无线两种遥控控制了,看不见了用无线,看得见用红外,红外的键多,可以定义多个功能多种控制,无线就4个键,弄些简单的前进后退就行了。
现在MO7号是这个鸟样子。