找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3439|回复: 9
收起左侧

红外遥控,能在1602上解码,但是改成用来遥控LED灯的亮咩的时候就不行了

[复制链接]
ID:83523 发表于 2015-9-19 22:14 | 显示全部楼层 |阅读模式
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint  unsigned int
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
void delay(uchar x);  //x*0.14MS
void delay1(int ms);
void beep();
void led();
sbit IRIN = P3^3;         //红外接收器数据线
sbit BEEP = P1^5;         //蜂鸣器驱动线
sbit RELAY= P1^4;         //继电器驱动线


uchar IRCOM[7];


sbit LCD_RS = P2^6;            
sbit LCD_RW = P2^5;
sbit LCD_EN = P2^7;
sbit led1= P1^0;

uchar code  cdis1[ ] = {" Red Control "};
uchar code  cdis2[ ] = {"  IR-CODE: --H  "};

/*******************************************************************/
/*                                                                 */
/*检查LCD忙状态                                                    */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。      */
/*                                                                 */
/*******************************************************************/

bit lcd_busy()
{                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    delayNOP();
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return(result);
}

/*******************************************************************/
/*                                                                 */
/*写指令数据到LCD                                                  */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                             */
/*                                                                 */
/*******************************************************************/

void lcd_wcmd(uchar cmd)

{                          
   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_();
   // cmd = ((cmd&0x01)<<7)|((cmd&0x02)<<5)|((cmd&0x04)<<3)|((cmd&0x08)<<1)|((cmd&0x10)>>1)|((cmd&0x20)>>3)|((cmd&0x40)>>5)|((cmd&0x80)>>7);
    P0 = cmd;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;  
}

/*******************************************************************/
/*                                                                 */
/*写显示数据到LCD                                                  */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。                               */
/*                                                                 */
/*******************************************************************/

void lcd_wdat(uchar dat)
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
//        dat = ((dat&0x01)<<7)|((dat&0x02)<<5)|((dat&0x04)<<3)|((dat&0x08)<<1)|((dat&0x10)>>1)|((dat&0x20)>>3)|((dat&0x40)>>5)|((dat&0x80)>>7);
    P0 = dat;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;
}

/*******************************************************************/
/*                                                                 */
/*  LCD初始化设定                                                  */
/*                                                                 */
/*******************************************************************/

void lcd_init()
{
    delay1(15);                  
    lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
    delay1(5);
    lcd_wcmd(0x38);         
    delay1(5);
    lcd_wcmd(0x38);         
    delay1(5);

    lcd_wcmd(0x0c);      //显示开,关光标
    delay1(5);
    lcd_wcmd(0x06);      //移动光标
    delay1(5);
    lcd_wcmd(0x01);      //清除LCD的显示内容
    delay1(5);
}

/*******************************************************************/
/*                                                                 */
/*  设定显示位置                                                   */
/*                                                                 */
/*******************************************************************/

void lcd_pos(uchar pos)
{                          
  lcd_wcmd(pos | 0x80);  //数据指针=80+地址变量
}

/*******************************************************************/
main()
{
   uchar m;

    IRIN=1;                    //I/O口初始化
    BEEP=1;
    RELAY=1;
        led1=0;
       
    delay1(10);                 //延时
    lcd_init();                //初始化LCD            

    lcd_pos(0);                //设置显示位置为第一行的第1个字符

     m = 0;
    while(cdis1[m] != '\0')
     {                         //显示字符
       lcd_wdat(cdis1[m]);
       m++;
     }

    lcd_pos(0x40);             //设置显示位置为第二行第1个字符
     m = 0;
    while(cdis2[m] != '\0')
     {
       lcd_wdat(cdis2[m]);      //显示字符
       m++;
     }


//        IE = 0x81;                 //允许总中断中断,使能 INT0 外部中断
//        TCON = 0x01;               //触发方式为脉冲负边沿触发
IT1=1;
EX1=1;
EA=1;


   while(1)        ;

} //end main
/**********************************************************/
void IR_IN() interrupt 2 using 0
{
  unsigned char j,k,N=0;
     EX1 = 0;   
         delay(15);
         if (IRIN==1)
     { EX1 =1;
           return;
          }
                           //确认IR信号出现
  while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。
    {delay(1);}

for (j=0;j<4;j++)         //收集四组数据
{
  for (k=0;k<8;k++)        //每组数据有8位
  {
   while (IRIN)            //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
     {delay(1);}
    while (!IRIN)          //等 IR 变为高电平
     {delay(1);}
     while (IRIN)           //计算IR高电平时长
      {
    delay(1);
    N++;           
    if (N>=30)
         { EX1=1;
         return;}                  //0.14ms计数过长自动离开。
      }                        //高电平计数完毕               
     IRCOM[j]=IRCOM[j] >> 1;                  //数据最高位补“0”
     if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}  //数据最高位补“1”
     N=0;
  }//end for k
}//end for j

   if (IRCOM[2]!=~IRCOM[3])
   { EX1=1;
     return; }

   IRCOM[5]=IRCOM[2] & 0x0F;     //取键码的低四位
   IRCOM[6]=IRCOM[2] >> 4;       //右移4次,高四位变为低四位

   if(IRCOM[5]>9)
    { IRCOM[5]=IRCOM[5]+0x37;}
   else
          IRCOM[5]=IRCOM[5]+0x30;

   if(IRCOM[6]>9)
    { IRCOM[6]=IRCOM[6]+0x37;}
   else
          IRCOM[6]=IRCOM[6]+0x30;

     lcd_pos(0x4b);            
     lcd_wdat(IRCOM[6]);        //第一位数显示
     lcd_pos(0x4c);            
     lcd_wdat(IRCOM[5]);        //第二位数显示

         


     beep();
     EX1 = 1;
       
}

void led()
{


                  if(IRCOM[5]=6&&IRCOM[1]==1) {led1=0;}
                 
}
void beep()
{
  unsigned char i;
  for (i=0;i<100;i++)
   {
   delay(4);
   BEEP=!BEEP;                 //BEEP取反
   }
  BEEP=1;                      //关闭蜂鸣器
}
/**********************************************************/
void delay(unsigned char x)    //x*0.14MS
{
unsigned char i;
  while(x--)
{
  for (i = 0; i<13; i++) {}
}
}

/**********************************************************/
void delay1(int ms)
{
unsigned char y;
  while(ms--)
{
  for(y = 0; y<250; y++)
  {
   _nop_();
   _nop_();
   _nop_();
   _nop_();
  }
}
}

回复

使用道具 举报

ID:83523 发表于 2015-9-19 22:18 | 显示全部楼层
1602上显示遥控“0”的键码值是16H
C:\Users\Administrator\Desktop
回复

使用道具 举报

ID:83523 发表于 2015-9-19 22:18 | 显示全部楼层
求大侠指导一下,毕设剩下红外了,跪求
回复

使用道具 举报

ID:1 发表于 2015-9-19 22:54 来自手机 | 显示全部楼层
这个是修改前的程序还是修改后的程序
回复

使用道具 举报

ID:84652 发表于 2015-9-19 22:58 | 显示全部楼层
if(IRCOM[5]=6&&IRCOM[1]==1) {led1=0;}
应该是IRCOM[5]==6吧?
回复

使用道具 举报

ID:83523 发表于 2015-9-19 23:12 | 显示全部楼层
王朗的诱惑 发表于 2015-9-19 22:58
if(IRCOM[5]=6&&IRCOM[1]==1) {led1=0;}
应该是IRCOM[5]==6吧?

对对对
回复

使用道具 举报

ID:83523 发表于 2015-9-19 23:14 | 显示全部楼层
admin 发表于 2015-9-19 22:54
这个是修改前的程序还是修改后的程序

回老师,修改后的,但是led()没加进去,试过加进去,不能控制,所以想问论坛里的师兄修改后再加进去调试
回复

使用道具 举报

ID:79544 发表于 2015-9-21 11:03 | 显示全部楼层
红外可以解出码值对吧,用解出的码值去控制继电器不就行啦,switch(IRCOM[2]){case 码值:RELAY= 0;}放在大循环里。试试
回复

使用道具 举报

ID:79544 发表于 2015-9-21 19:18 | 显示全部楼层
楼主的程序我加上了控制LED的正确函数。加上三极管就可以控制继电器驱动电器。
  1. /***********************************************
  2.         功能:万能红外遥控器解码并用数码管显示。
  3.                         只显示键值码.根据键值控制LED
  4.                         加上三极管就可以控制继电器
  5.         红外接收头的输出接外部中断1.  P3.3
  6.         晶振:11.0592M
  7.         单片机:STC12C5A60S2
  8.         作者 :苏义江改编自51黑论坛
  9. *************************************************/
  10. #include <reg52.h>
  11. #define uchar unsigned char
  12. sbit dula=P0^7;
  13. sbit wela=P0^6;
  14. sbit fmq=P1^7;
  15. sbit  IR=P3^3;
  16. //共阳
  17. uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
  18.                                 0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,
  19.                                 0xa1,0x86,0x8e,0x89};
  20. //共阴
  21. /*uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
  22.        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  */

  23. uchar f;

  24. #define Imax 14000    //此处为晶振为11.0592时的取值,
  25. #define Imin 8000    //如用其它频率的晶振时,
  26. #define Inum1 1450    //要改变相应的取值。
  27. #define Inum2 700
  28. #define Inum3 3000

  29. uchar Im[4]={0x00,0x00,0x00,0x00};
  30. uchar show[2]={0,0};
  31. unsigned long m,Tc;
  32. unsigned char IrOK;

  33. void delay(uchar i)//延时
  34. {
  35.   uchar j,k;
  36.   for(j=i;j>0;j--)
  37.     for(k=125;k>0;k--);
  38. }

  39. void display()//显示函数
  40. {
  41.    P2=table[show[0]];
  42.    dula=1;
  43.    dula=0;
  44.         P2=0xff;
  45.    
  46.    wela=0;
  47.    P2=0xfe;
  48.    wela=1;
  49.    wela=0;
  50.    delay(5);
  51.    
  52.    P2=table[show[1]];
  53.    dula=1;
  54.    dula=0;
  55.         P2=0xff;
  56.    
  57.    P2=0xfd;
  58.    wela=1;
  59.    wela=0;
  60.    delay(5);
  61. }


  62. //外部中断1解码程序
  63. void intersvr1(void) interrupt 2 using 1
  64. {
  65.         fmq=0;    //蜂鸣器响
  66.         Tc=TH0*256+TL0;   //提取中断时间间隔时长
  67.         TH0=0;
  68.     TL0=0;         //定时中断重新置零
  69.         if((Tc>Imin)&&(Tc<Imax))
  70.     {
  71.                   m=0;
  72.         f=1;
  73.                   return;
  74.      }       //找到启始码
  75.    if(f==1)
  76.    {
  77.        if(Tc>Inum1&&Tc<Inum3)
  78.                    {
  79.                            Im[m/8]=Im[m/8]>>1|0x80; m++;
  80.             }
  81.               if(Tc>Inum2&&Tc<Inum1)
  82.         {
  83.                  Im[m/8]=Im[m/8]>>1; m++; //取码
  84.                   }
  85.                   if(m==32)
  86.                    {
  87.                  m=0;  
  88.                  f=0;
  89.          if(Im[2]==~Im[3])//键值码和反码相同
  90.                {
  91.            IrOK=1; //正确至1
  92.                     }
  93.          else IrOK=0;   //取码完成后判断读码是否正确
  94.      }
  95.                //准备读下一码
  96.    }
  97.         fmq=1; //蜂鸣器关,如果嫌吵,可删掉此行和上面对应的开喇叭那一行
  98. }
  99. /*主程序*/
  100. void main(void)
  101. {
  102.     uint  a;   
  103.          m=0;
  104.     f=0;
  105.         EA=1;
  106.         IT1=1;
  107.         EX1=1;
  108.     TMOD=0x11;  
  109.     TH0=0;TL0=0;
  110.     TR0=1;
  111.          while(1)
  112.         {

  113.        if(IrOK==1)
  114.                   {
  115.                       show[1]=Im[2] & 0x0F;     //取键码的低四位
  116.            show[0]=Im[2] >> 4;  
  117.            IrOK=0;     
  118.                   }
  119.            for(a=100;a>0;a--)
  120.           {
  121.                             display();
  122.                      }
  123.                 switch(Im[2])
  124.                 {
  125.                         case 0x1b:P0=0XFE;break;
  126.                         case 0x18:P0=0XFd;break;
  127.                         case 0x17:P0=0XFb;break;
  128.                         case 0x16:P0=0XF7;break;
  129.                         case 0x15:P0=0Xef;break;
  130.                         case 0x14:P0=0Xdf;break;
  131.                         default: break;
  132.                 //        return;
  133.                 }
  134.         }
  135. }
复制代码
回复

使用道具 举报

ID:51128 发表于 2015-12-21 22:12 | 显示全部楼层
aaxing 发表于 2015-9-19 22:18
1602上显示遥控“0”的键码值是16H

我的怎么是 :10H
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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