公告:

AI:红外线遥控

作者:智凡单片机 / 时间:1个月前 (12/19) / 分类:51单片机 / 阅读:308 / 评论:0

有个想法,就是用红外信号遥控机器人,因为红外发射器有二十多个不同编码,控制能力强,但信号覆盖就弱些。在网上找到一个很好的接收解码程序,里面用到中断、定时等功能,把它改写一下就可以用到单片机上,转载如下:

#include "reg52.h" 
 
// 此口为红外信号输入MCU口 
sbit IR_Out = P3^2;  //作外部中断检测,该口对下降沿有效,触发中断
 
// 主程序运行标志位,运行主程序时标志灯灭,运行中断程序时标志灯亮   
sbit IR_Flag = P1^0;  //接标志灯
 
// LED显示口 
#define LED_Port P2 
sbit p21=P2^0 ;   //p21接led灯用来显示检测结果
 
// 用于存放按键码值,初始化为0000 0000这样接受数据时可以只考虑1了  
unsigned char dat[4] = {0,0,0,0}; 
 
  void delay_ms(uint n)  //延时1ms子程序
{ while (--n)
    {uint n2=120;
while(--n2);}
}  
 
void main() 
{ 
    IR_Out = 1;     // 此口为MCU输入口,故需要置1 
    IR_Flag = 1;    // 灭LED灯 
    TMOD = 0x01;    // 定时器0,方式1 
    IT0 = 1;        // 外部中断0,下降沿触发 
    EX0 = 1;        // 准许外部中断 
    EA = 1;         // CPU准许中断 
 
    while(1) 
    { 
        IR_Flag = 1;// 执行主程序时,标志灯灭 
       switch(dat[2]){      //红外码-动作识别
case 0x45:             //LED长亮
  p21=0;    
  break;
case 0x46:          //LED闪
  P2^=0x01;
  delay_ms(1000);
  break;
case 0x47:        //LED长灭
  p21=1;
  break;
default:          //其他不处理
  break;
}
    } 
} 
 
void Int0() interrupt 0         //外部中断0处理,用于解码
{ 
    unsigned char i,j; 
    EX0 = 0;            // 关闭外部中断0 
    IR_Flag = 0;        // 执行中断程序时,LED灯亮 
    i = 10;             // 0.793ms延时,运行10次 
    while( --i ) 
    { 
        // 定时0.793ms,延时0.793ms*10=7.93ms 
        TH0 = 0xfc; 
        TL0 = 0xe7;        //由0xfce7跳到0xffff,大約跳793個機器周期
        TR0 = 1;           //激活定时器
        while( !TF0 ); 
        TF0 = 0; 
        TR0 = 0; 
         
        // 这7.93ms期间只要IR_Out变高电平,就非合法的红外信号,跳出 
        if( IR_Out ) 
        { 
            EX0 = 1;    // 准许中断 
            return ; 
        } 
    } 
     
    // 程序进行到这里,表明是合法的红外信号(利用9ms判断) 
    while( !IR_Out );   // 等待9ms低电平过去 
     
    // 程序进行到这里,表明经过9ms低电平 
    TH0 = 0xf6; 
    TL0 = 0xff; 
    TR0 = 1;            //啓動定時器0產生中斷
    while( !TF0 );      //如果計數滿溢出,TF0=1,退出循環
    TF0 = 0; 
    TR0 = 0;            // 延时2.305ms 
     
    // IR_Out 为低表明是连发码,不予理睬,跳出 
    if( !IR_Out ) 
    { 
        EX0=1; 
        return; 
    } 
 
    // 程序进行到这里,表明是引导码,等待4.5ms高电平的过去 
    while( IR_Out );     
     
    // 开始接收用户码 
    for(i=0; i<4; i++) 
    { 
        for(j=0; j<8; j++) 
        { 
            while( !IR_Out );   // 等待低电平过去 
            dat[i] >>= 1;     // 把上次的数据位右移一位 
 
            TH0 = 0xfc; 
            TL0 = 0xe7; 
            TR0 = 1; 
            while( !TF0 ); 
            TR0=0; 
            TF0=0;              //延时0.793ms  
             
            // 若为数据"1",则延时后IR_Out为高电平  ;数据"0"只移位不用处理
            if( IR_Out )  
            { 
                dat[i] |= 0x80;     // 或运算,所有数据位1放最高位 
                while( IR_Out );    // 等待高电平过去 
            } 
        } 
    }    
    LED_Port = dat[2];  //dat[0],dat[1]是用户码,dat【2】是数据码,dat[3]是数据码反码
    EX0=1;      // 开中断 
    return; 
}

89c52 引脚图

AI:红外线遥控 51单片机 第1张

红外编码解码信号图: 低位先输出和接收

AI:红外线遥控 51单片机 第2张

用keil 的uv 来编写编译

AI:红外线遥控 51单片机 第3张


没有评论,留下你的印记,证明你来过。


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。