gracialee 发表于 2013-5-14 22:58:37

红外遥控小车,前后左右四个动作,只有前进正常。。。

void main(void)
{
    InitTimer();                //³õʼ»¯Timer
    while(1)
    {
      if(B_IR_Press)                //ÓÐIR¼ü°´ÏÂ
      {
            B_IR_Press = 0;           //Çå³ýIR¼ü°´Ï±êÖ¾
                        if(IR_code==0x1b)               
                        {
                                fun1();
//                                delayms(255);
                        }
                        if(IR_code==0x0d)               
                        {
                                fun2();
//                                delayms(100);
                        }
                        if(IR_code==0x16)               
                        {
                                fun3();
//                                delayms(100);
                        }
                        if(IR_code==0x17)               
                        {
                                fun4();
//                                delayms(100);
                        }
                        if(IR_code==0x0c)               
                        {
                                fun5();
                                delayms(100);
                        }
                        IR_code=0;
      }
    }
}
void fun1()
{ P10=0;P11=1;P12=0;P13=1;}
void fun2()
{ P10=1;P11=0;P12=1;P13=0;}
void fun3()
{ P10=1;P11=0;P12=0;P13=1;}
void fun4()
{ P10=0;P11=1;P12=1;P13=0;}
void fun5()
{ P10=1;P11=1;P12=1;P13=1;}

fun12345分别是前进,后退,左拐,右拐,停机。目前红外解码正常,前进正常,也就是按一下遥控电机会向前走一小段,但其它三个动作都是按一下,一直走。。。。。只有再按一下前进或者停机,小车才会停下来。

devcang 发表于 2013-5-15 00:32:52

逻辑问题。


if(B_IR_Press){
...................
}else{
fun5();//stop
}


另,把fun1~4的名字,改成容易识别吧。

gracialee 发表于 2013-5-15 08:01:55

devcang 发表于 2013-5-15 00:32 static/image/common/back.gif
逻辑问题。




虽没有完全解决问题,但还是谢谢您,逻辑上没啥大问题。但改成容易识别的确实必要,改之。

gracialee 发表于 2013-5-15 18:05:03


/*************      用户系统配置      **************/         
#include <intrins.h>

#define         D_TIMER0                   125               //选择定时器时间, us, 红外接收要求在60us~250us之间
#define   User_code_L                0x00                //定义红外接收用户码
#define   User_code_H                0x00                //定义红外接收用户码         

/*************      以下宏定义用户请勿修改      **************/
#include    "reg51.H"
#define   uchar       unsigned char
#define   uint      unsigned int
#define Led_LineP2             //段选口
#define LED_dataP0             //数据口

sbit P10=P2^4;         //右轮前进
sbit P11=P2^5;        //右轮后退
sbit P12=P2^6;        //左轮前进
sbit P13=P2^7;        //左轮后退

void QianJin()
{ P10=0;P11=1;P12=0;P13=1;}
void HouTui()
{ P10=1;P11=0;P12=1;P13=0;}
void ZuoGuai()
{ P10=1;P11=0;P12=0;P13=1;}
void YouGuai()
{ P10=0;P11=1;P12=1;P13=0;}
void TingJi()
{ P10=1;P11=1;P12=1;P13=1;}

sbit      P_IR_RX = P3^3;                //定义红外接收输入端口

bit          P_IR_RX_temp;                //Last sample
bit          B_IR_Sync;                        //已收到同步标志
uchar      SampleTime;
uchar      IR_SampleCnt;                //采样计数
uchar      IR_BitCnt;                        //编码位数
uchar      IR_UserH;                        //用户码(地址)高字节
uchar      IR_UserL;                        //用户码(地址)低字节
uchar      IR_data;                        //数据原码
uchar      IR_DataShit;          //数据反码

bit          B_IrUserErr;          //User code error flag
bit          B_IR_Press;         //Key press flag,include repeat key.
uchar      IR_code;            //IR code      红外键码
uchar      temp0;               //临时计算
uchar      temp1;               //临时计算

int num,miao=0,fen=0,shi=0,zhou=0,mg,ms,fg,fs,sg,ss;
uchar code LedCode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,
                      0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x7f,
                                          0x8e,0x89,0xc8,0xab,0xa3
                     };
uchar code LedCode16[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};

uint tt,k=0;

/*************      本地函数声明      **************/
void      InitTimer(void);

void delayms(uint xms)   //延时子函数
{
        uint i,j;
        for(i=xms;i>0;i--)
           for(j=20;j>0;j--);
}

/********************* 主函数 *************************/
void main(void)
{
    InitTimer();                //初始化Timer
    while(1)
    {
      if(B_IR_Press)                //有IR键按下
      {
            B_IR_Press = 0;           //清除IR键按下标志
                        switch(IR_code)
                        {
                          case 0x1b : k=1;break;
                          case 0x0d : k=2;break;
                          case 0x16 : k=3;break;
                          case 0x17 : k=4;break;
                          case 0x0c : k=5;break;
                                default:break;
                        }
      }
    }
}

/**************** Timer初始化函数 ******************************/
void InitTimer(void)
{
    TMOD = 0x22;   //8位自动重装 timer1负责PWM timer0负责红外解码
        TH0=0x8d;           //125us
        TL0=TH0;
        TH1=0xb8;           //20MS时钟1 11.0592
    TL1=0x00;
    EA = 1;
    ET0 = 1;
    TR0 = 1;

    ET1=1;
    TR1=1;            //1为开启时钟。
}

#if ((D_TIMER0 <= 250) && (D_TIMER0 >= 60))
      #define      D_IR_sample                        D_TIMER0                //定义采样时间,在60us~250us之间
#endif

#define D_IR_SYNC_MAX                (15000/D_IR_sample)      //SYNC max time
#define D_IR_SYNC_MIN                (9700 /D_IR_sample)      //SYNC min time
#define D_IR_SYNC_DIVIDE      (12375/D_IR_sample)      //decide data 0 or 1
#define D_IR_DATA_MAX                (3000 /D_IR_sample)      //data max time
#define D_IR_DATA_MIN                (600/D_IR_sample)      //data min time
#define D_IR_DATA_DIVIDE      (1687 /D_IR_sample)      //decide data 0 or 1
#define D_IR_BIT_NUMBER                32                                        //bit number

/********************** Timer0中断函数************************/
void timer0 (void) interrupt 1
{
    IR_SampleCnt++;                                                      //Sample + 1

    F0 = P_IR_RX_temp;                                                //Save Last sample status
    P_IR_RX_temp = P_IR_RX;                                        //Read current status
    if(F0 && !P_IR_RX_temp)                                        //Last sample is high,and current sample is low, so is fall edge
    {
      SampleTime = IR_SampleCnt;                        //get the sample time
      IR_SampleCnt = 0;                                        //Clear the sample counter

      if(SampleTime > D_IR_SYNC_MAX)                B_IR_Sync = 0;      //large the Maxim SYNC time, then error
      else if(SampleTime >= D_IR_SYNC_MIN)                                        //SYNC
      {
                if(SampleTime >= D_IR_SYNC_DIVIDE)
                {
                        B_IR_Sync = 1;                                        //has received SYNC
                        IR_BitCnt = D_IR_BIT_NUMBER;      //Load bit number
                }
      }
      else if(B_IR_Sync)                                                //has received SYNC
      {
            if(SampleTime > D_IR_DATA_MAX)                B_IR_Sync=0;      //data samlpe time to large
            else
            {
                IR_DataShit >>= 1;                                        //data shift right 1 bit
                if(SampleTime >= D_IR_DATA_DIVIDE)      IR_DataShit |= 0x80;      //devide data 0 or 1
                if(--IR_BitCnt == 0)                              //bit number is over?
                {
                  B_IR_Sync = 0;                                        //Clear SYNC
                  if(~IR_DataShit == IR_data)                //判断数据正反码
                  {
                        if((IR_UserH == User_code_H) && (IR_UserL == User_code_L))
                                        B_IrUserErr = 0;      //User code is righe
                        else      B_IrUserErr = 1;      //user code is wrong
                              
                        IR_code      = IR_data;
                        B_IR_Press   = 1;                        //数据有效
                  }
                }
                else if((IR_BitCnt & 7)== 0)                //one byte receive
                {
                  IR_UserL = IR_UserH;                        //Save the User code high byte
                  IR_UserH = IR_data;                              //Save the User code low byte
                  IR_data= IR_DataShit;                        //Save the IR data byte         状态机,移动
                }
            }
      }
    }
}
void t1_time()interrupt 3   //中断子函数
{
        TH1=(65536-50000)/256;
        TL1=(65536-50000)%256;
        tt++;
        if(tt==10)
        {
          tt=0;
                switch(k)
                {
                  case 1:QianJin(); break;
                  case 2:HouTui();break;
                  case 3:ZuoGuai(); break;
                  case 4:YouGuai(); break;
                        default:
                             TingJi();break;
                }
        }

}      

zjk 发表于 2013-5-16 08:48:37

是不是红外接收部分有问题?

Playboy_xixi 发表于 2013-5-16 09:53:14

我们刚开始做小车测试也是这个问题,只是直走,不转弯。。看看楼主,你是否把过多的时间留在判断上了??

gracialee 发表于 2013-5-16 10:44:02

zjk 发表于 2013-5-16 08:48 static/image/common/back.gif
是不是红外接收部分有问题?

前帖已说明,解码正常。

gracialee 发表于 2013-5-16 10:46:37

Playboy_xixi 发表于 2013-5-16 09:53 static/image/common/back.gif
我们刚开始做小车测试也是这个问题,只是直走,不转弯。。看看楼主,你是否把过多的时间留在判断上了?? ...

不是过多时间放在判断上,而是所有时间都在上面,当没有遥控按下的时候,它在那里无何止是判断是否有遥控按下。一旦检测到有键按下,就开始解码,然后行动。再然后又开始新一轮的判断是否有键按下了。

Playboy_xixi 发表于 2013-5-16 10:48:49

gracialee 发表于 2013-5-16 10:46 static/image/common/back.gif
不是过多时间放在判断上,而是所有时间都在上面,当没有遥控按下的时候,它在那里无何止是判断是否有遥控 ...

不是寻迹小车?

gracialee 发表于 2013-5-16 10:54:42

Playboy_xixi 发表于 2013-5-16 10:48 static/image/common/back.gif
不是寻迹小车?

明显不是,是红外遥控小车。
页: [1]
查看完整版本: 红外遥控小车,前后左右四个动作,只有前进正常。。。