新手上路 
 
	- 积分
 - 39
 
        - 金钱
 - 39 
 
       - 注册时间
 - 2016-5-24
 
      - 在线时间
 - 6 小时
 
 
 
 | 
 
1金钱 
遥控时想实现连按重复上次操作(如连按小车前进,不按小车停止),但是现在只能实现按下走一定的延时时间后又停止再按才能走,必须要有一定频率的按键操作才能实现重复上次操作的功能,估计是重复码无法识别,求解决 
 
 
 
 
#include <reg52.h> 
 
#define u8  unsigned char 
#define u16  unsigned int 
sbit led=P0^0; 
 
sbit IR_INPUT = P3^3; //红外接收引脚 
bit irflag = 0; //红外接收标志,收到一帧正确数据后置 1 
unsigned char ircode[4]; //红外代码接收缓冲区 
 
 
unsigned char code LedChar[] = { //?????????? 
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x84 
}; 
unsigned char LedBuff[4] = {  
    0xC0, 0xC0, 0xC0, 0xC0 
}; 
 
#define  u16  unsigned int 
#define  u8   unsigned char 
 
sbit IN1=P1^0; 
sbit IN2=P1^1; 
sbit IN3=P1^2; 
sbit IN4=P1^3; 
 
 
 
sbit key4 = P3^7; 
sbit key3 = P3^6; 
sbit key2 = P3^5; 
sbit key1 = P3^4; 
 
u8 pp; 
 
char sum; 
 
 
sbit L_PWM=P1^4; 
sbit R_PWM=P1^5; 
 
 
#define  L_go          IN1=1;IN2=0    //左轮进 
#define  L_back        IN1=0;IN2=1    //左轮退 
#define  L_stop        IN1=0;IN2=0    //左轮停 
 
#define  R_go          IN3=1;IN4=0     //右轮进 
#define  R_back        IN3=0;IN4=1     //右轮退 
#define  R_stop        IN3=0;IN4=0     //右轮停止 
 
#define  car_go        L_go;R_go       //车向前进 
#define  car_back      L_back;R_back   //车倒退 
#define  car_stop      L_stop;R_stop   //车停止 
#define  car_lift      R_go;L_stop     //车左转 
#define  car_right     L_go;R_stop     //车右转 
 
 
#define  car_lift360   L_back;R_go     //可以理解为左大转弯 
#define  car_right360  R_back;L_go     //可以理解为右大转弯 
 
 
 
 
void delay(unsigned int t){                 
        while(t--); 
         
} 
 
void delay_ms(u16 x) 
{ 
        u8 i; 
  while(x--) 
  for(i=0;i<120;i++); 
} 
 
 
 
void T0_Init() 
{ 
        TMOD&=0Xf0; 
        TMOD|=0x01; 
        TH0=0XFC;      //定时器0实现1ms产生一次中断,若是设置10格调速,则PWM的周期就是10ms 
        TL0=0X07; 
        ET0=1; 
        TR0=1; 
        EA=1; 
         
} 
 
void time0()interrupt 1 
{ 
        TMOD&=0Xf0; 
        TMOD|=0x01; 
        TH0=0XFC;      //定时器0实现1ms产生一次中断,若是设置10格调速,则PWM的周期就是10ms 
        TL0=0X07; 
        pp++; 
  if(pp>9) pp=0; 
        if(sum!=0&&sum!=9) 
        { 
                if(pp<=sum) 
        {        L_PWM=1; 
                R_PWM=1; 
  } 
        else  
                { 
                        L_PWM=0; 
                        R_PWM=0; 
    } 
        } 
        else if(sum==0) 
        { 
                L_PWM=0; 
                        R_PWM=0; 
  } 
        else if(sum==9) 
        { 
                L_PWM=1; 
                R_PWM=1; 
  }         
} 
 
 
 
 
/* 初始化红外接收功能 */ 
void InitInfrared(){ 
    IR_INPUT = 1; //确保红外接收引脚被释放 
    TMOD &= 0x0F; //清零 T1 的控制位 
    TMOD |= 0x10; //配置 T1 为模式 1 
    TR1 = 0; //停止 T1 计数 
    ET1 = 0; //禁止 T1 中断 
    IT1 = 1; //设置 INT1 为负边沿触发 
    EX1 = 1; //使能 INT1 中断 
} 
/* 获取当前高电平的持续时间 */ 
unsigned int GetHighTime(){ 
    TH1 = 0; //清零 T1 计数初值 
    TL1 = 0; 
    TR1 = 1; //启动 T1 计数 
    while (IR_INPUT){ //红外输入引脚为 1 时循环检测等待,变为 0 时则结束本循环 
        //当 T1 计数值大于 0x4000,即高电平持续时间超过约 18ms 时, 
        //强制退出循环,是为了避免信号异常时,程序假死在这里。 
        if (TH1 >= 0x40){ 
            break; 
        } 
    } 
    TR1 = 0; //停止 T1 计数 
    return (TH1*256 + TL1); //T1 计数值合成为 16bit 整型数,并返回该数 
} 
/* 获取当前低电平的持续时间 */ 
unsigned int GetLowTime(){ 
    TH1 = 0; //清零 T1 计数初值 
    TL1 = 0; 
    TR1 = 1; //启动 T1 计数 
    while (!IR_INPUT){ //红外输入引脚为 0 时循环检测等待,变为 1 时则结束本循环 
        //当 T1 计数值大于 0x4000,即低电平持续时间超过约 18ms 时, 
        //强制退出循环,是为了避免信号异常时,程序假死在这里。 
        if (TH1 >= 0x40){ 
            break; 
        } 
    } 
    TR1 = 0; //停止 T1 计数 
    return (TH1*256 + TL1); //T1 计数值合成为 16bit 整型数,并返回该数 
} 
/* INT1 中断服务函数,执行红外接收及解码 */ 
void EXINT1_ISR() interrupt 2{ 
    unsigned char i, j; 
    unsigned char byt; 
    unsigned int time; 
    
    //接收并判定引导码的 9ms 低电平 
    time = GetLowTime(); 
    //时间判定范围为 8.5~9.5ms, 
    //超过此范围则说明为误码,直接退出 
    if ((time<7833) || (time>8755)){ 
        IE1 = 0; //退出前清零 INT1 中断标志 
        return; 
    } 
    //接收并判定引导码的 4.5ms 高电平 
    time = GetHighTime(); 
    //时间判定范围为 4.0~5.0ms, 
    //超过此范围则说明为误码,直接退出 
    if ((time<3686) || (time>4608)){ 
        IE1 = 0; 
        return; 
    } 
                        else if((time>1612)&&(time<2534)) 
                {irflag = 1; 
                        IE1 = 0; 
    return; 
    } 
    //接收并判定后续的 4 字节数据 
    for (i=0; i<4; i++){ //循环接收 4 个字节 
        for (j=0; j<8; j++){ //循环接收判定每字节的 8 个 bit 
            //接收判定每 bit 的 560us 低电平 
            time = GetLowTime(); 
            //时间判定范围为 340~780us, 
            //超过此范围则说明为误码,直接退出 
            if ((time<313) || (time>718)){ 
                IE1 = 0; 
                return; 
            } 
            //接收每 bit 高电平时间,判定该 bit 的值 
            time = GetHighTime(); 
            //时间判定范围为 340~780us, 
            //在此范围内说明该 bit 值为 0 
            if ((time>313) && (time<718)){ 
                byt >>= 1; //因低位在先,所以数据右移,高位为 0 
                //时间判定范围为 1460~1900us, 
                //在此范围内说明该 bit 值为 1 
            }else if ((time>1345) && (time<1751)){ 
                byt >>= 1; //因低位在先,所以数据右移, 
                byt |= 0x80; //高位置 1 
            }else{ //不在上述范围内则说明为误码,直接退出 
                IE1 = 0; 
                return; 
            } 
        } 
        ircode[i] = byt; //接收完一个字节后保存到缓冲区 
 
    } 
    irflag = 1; //接收完毕后设置标志 
    IE1 = 0; //退出前清零 INT1 中断标志 
                 
        } 
                 
void Date_kandle() 
                { 
                        if (irflag){ //接收到红外数据时刷新显示 
            irflag = 0; 
            LedBuff[0] = LedChar[ircode[0] >> 4]; //用户码显示 
            LedBuff[1] = LedChar[ircode[0]&0x0F]; 
            LedBuff[2] = LedChar[ircode[2] >> 4]; //键码显示 
            LedBuff[3] = LedChar[ircode[2]&0x0F]; 
         
                } 
        } 
         
                void main(){ 
                         
                        u8 i,tmp; 
    EA = 1; //开总中断 
   // T0_Init(); 
    InitInfrared(); //初始化红外功能                         
        //PT1=1; 
    
                        while (1) 
                        { 
                                 
                                 
                                if(irflag) 
                                { 
                                        irflag = 0; 
                                        tmp=ircode[2]; 
                                        switch(tmp)//led=~led;break; 
                                        { 
                                                case 0x40: car_go;break; 
                                                case 0x19: car_back;break; 
                                                case 0x07: car_lift;break; 
                                                case 0x09: car_right;break; 
                                                default: break; 
          } 
         
delay_ms(1000); 
        }else car_go; 
         
                        /*                                Date_kandle(); 
                                                for(i=0;i<4;i++) 
        { 
                P2=0X01<<i;    
                 
                P1=LedBuff[i]; 
                 
                delay_ms(5); 
         
    }*/ 
}         
} |   
 
 
 
 
 
 |