微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 第六篇----红外光走直线不穿墙

第六篇----红外光走直线不穿墙

时间: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号是这个鸟样子。


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top