一乐电子

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 3257|回复: 13

[其他综合] 红外遥控小车,前后左右四个动作,只有前进正常。。。 ...

[复制链接]
发表于 2013-5-15 18:09 | 显示全部楼层 |阅读模式

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


/*************        用户系统配置        **************/         
#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_Line  P2             //段选口
#define LED_data  P0             //数据口

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;
        }
    }

}        



发表于 2013-5-15 19:46 | 显示全部楼层
编程高手。。。
回复

使用道具 举报

发表于 2013-5-15 22:58 | 显示全部楼层
本帖最后由 xxxx7 于 2013-5-15 23:01 编辑

void t1_time()interrupt 3   //中断子函数
{% U4 F* M3 i$ t/ ?: m
     TH1=(65536-50000)/256;
    TL1=(65536-50000)%256;
    tt++;& s; `1 ~& |  b; V: {" E" l! z! E
     if(tt==10)% F& S: A0 a' c7 L' f
     {
        tt=0;  G) S( o, \7 E+ ^& Q
         switch(k)' G* S7 i+ i/ l* X. \
         {& d% E: S. j0 Z5 v. i" @
             case 1:QianJin(); break;' q# [' z( a9 S& R( H2 k! H- P
             case 2:HouTui();  break;5 p" M" P# q9 L/ X2 J3 j
             case 3:ZuoGuai(); break;
            case 4:YouGuai(); break;: E3 W9 K- |4 P# {$ D  {
             default:; l: h8 M4 b* }) l  ^0 M# k$ F
                    TingJi();  break;3 p. K: p3 R" S* h
         }
     k=5;    //加一句K=5 试试
    }& W) ~( i# ?* z
5 h: e* e8 K/ I+ _, }' Y- q. x
}        
回复

使用道具 举报

发表于 2013-5-15 23:01 | 显示全部楼层
这代码,太长了,看别人的代码很难受的,应该把可能出问题的地方截出来加上详尽注释,也能节省别人时间。
ps:我没写过红外驱动,我是打酱油路过的
回复

使用道具 举报

发表于 2013-5-15 23:21 | 显示全部楼层
本帖最后由 xxxx7 于 2013-5-15 23:22 编辑

仔细考虑了下 在 void t1_time()interrupt 3   //中断子函数
中加 k=5;  不是很好

主循环试试

void main(void), f$ W3 `% E# t7 a1 U/ i7 h
{
    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;) @6 k0 P/ j/ u0 ]2 F+ Y
                 case 0x16 : k=3;break;
                case 0x17 : k=4;break;
                case 0x0c : k=5;break;; x" c" h, P( g3 D
                 default:  break;* ?8 I' W5 k) i  j
             }  a5 e& \& @: j- A8 K, ~  k
         }
     else                     //加在这里
     {k=5;}

    }
}
回复

使用道具 举报

发表于 2013-5-16 01:04 | 显示全部楼层
是因为我用手机的关系吗?完全看不懂这代码
回复

使用道具 举报

 楼主| 发表于 2013-5-16 10:21 | 显示全部楼层
xxxx7 发表于 2013-5-15 23:21 static/image/common/back.gif
仔细考虑了下 在 void t1_time()interrupt 3   //中断子函数
中加 k=5;  不是很好

你回过两次帖子,并进行了修改,说明你认真地看过这个程序了。赞一个。尽管没有实质性地解决问题。
回复

使用道具 举报

发表于 2013-5-16 10:50 | 显示全部楼层

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

dianzichina 发表于 2013-5-16 10:21 static/image/common/back.gif
你回过两次帖子,并进行了修改,说明你认真地看过这个程序了。赞一个。尽管没有实质性地解决问题。

按我的修改,应该还是有效果的吧!?只是速度有所降低
回复

使用道具 举报

发表于 2013-5-16 11:05 | 显示全部楼层
在你说的解码正常的前提下,
前进动作应该是不正常的,其他3个动作是正常的吧。
都应该是触发-》保持-》直到下一次改变动作才对。
回复

使用道具 举报

 楼主| 发表于 2013-5-16 12:01 | 显示全部楼层
本帖最后由 dianzichina 于 2013-5-16 12:04 编辑
文句子 发表于 2013-5-16 11:05 static/image/common/back.gif
在你说的解码正常的前提下,
前进动作应该是不正常的,其他3个动作是正常的吧。
都应该是触发-》保持-》直 ...

果然是高手,能一语道破天机。我再改改。 PS:既然“前后左右是近乎一样的程序,为何后三可行,而薄此最前,”
回复

使用道具 举报

本版积分规则

QQ|一淘宝店|手机版|商店|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2025-11-2 01:02 , Processed in 0.043468 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表