找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1801|回复: 11
收起左侧

单片机红外遥控跟独立按键怎样实现同样的功能?

[复制链接]
ID:899076 发表于 2022-6-10 14:03 | 显示全部楼层 |阅读模式
请教一下各位大佬,我想要红外遥控跟一个独立按键实现同样的功能,但是不会整合。下面的代码单独使用红外遥控或者独立按键都能正常切换功能,但是整合到一起就不会了。本人初学者软件写的有点乱,望大佬们指点一二。

谢谢
  1. #include <reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. unsigned char irtime;//红外用全局变量
  5. bit irpro_ok,irok;
  6. unsigned char IRcord[4];//用来存放用户码、用户反码、数据码、数据反码
  7. unsigned char irdata[33];//用来存放32位码值

  8. typedef unsigned char u8;
  9. typedef unsigned int u16;

  10. u16 mode;

  11. sbit key = P3^4;

  12. void delay(u16 i)
  13. {
  14.         while(i--);
  15. }

  16. void tim0_isr()interrupt 1  //定时器0中断服务函数
  17. {
  18.         irtime++;
  19. }

  20. void ex0_isr()interrupt 0   //外部中断0服务函数
  21. {
  22.         static unsigned char i;
  23.         static bit startflag;
  24.         if(startflag)
  25.         {
  26.                 if(irtime<53&&irtime>=32)
  27.                 i=0;
  28.                 irdata[ i]=irtime;[ i]
  29.                 irtime=0;
  30.                 i++;
  31.                 if(i==33)
  32.                 {
  33.                         irok=1;
  34.                         i=0;
  35.                 }
  36.         }
  37.         else
  38.         {
  39.                 irtime=0;
  40.                 startflag=1;                        
  41.         }
  42. }

  43. void TIM0init()//定时器0初始化
  44. {
  45.         TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
  46.         TH0=0x00;
  47.         TL0=0x00;
  48.                 EA=1;
  49.         ET0=1;//开总中断
  50.         TR0=1;

  51.         IT0=1;
  52.         EX0=1;

  53. }
  54. void Ircordpro()//红外码值处理函数(关键函数)
  55. {
  56.         unsigned char i,j,k=1;
  57.         unsigned char cord,value;

  58.         for(i=0;i<4;i++)                //处理4个字节
  59.         {
  60.                 for(j=1;j<=8;j++)         //处理1个字节8位
  61.                 {
  62.                         cord=irdata[k];
  63.                         value=value>>1;
  64.                         if(cord>7)value=value|0x80;//大于某值为1
  65.                         k++;
  66.                 }
  67.                 IRcord[ i]=value;[ i]
  68.                 value=0;
  69.         }
  70.         irpro_ok=1;//处理完毕标志位置1
  71. }

  72. void Key()                          //按键
  73. {
  74.         if(key==0)
  75.         {
  76.                 delay(1000);
  77.                 if(key==0)
  78.                 {
  79.                         mode++;
  80.                         if(mode==8)
  81.                         {
  82.                                 mode=0;
  83.                         }
  84.                         while(!key);
  85.                 }
  86.         }
  87. }

  88. void IR_LED()
  89. {
  90.         if(irok)
  91.         {                        
  92.                 Ircordpro();
  93.                 irok=0;
  94.         }
  95.         if(irpro_ok)//遥控成功接收
  96.         {                        
  97.                 switch(IRcord[2])
  98.                 {        
  99.                         case 0x04:P1 = 0x01; break;      //打开红色LED
  100.                         case 0x05:P1 = 0x02; break;      //打开绿色LED
  101.                         case 0x06:P1 = 0x04; break;      //打开蓝色LED
  102.                         case 0x07:P1 = 0x07; break;      //打开白色LED
  103.                         case 0x08:P1 = 0x03; break;      //打开红绿色LED
  104.                         case 0x09:P1 = 0x05; break;      //打开红蓝色LED
  105.                         case 0x0a:P1 = 0x06; break;      //打开绿蓝色LED
  106.                 }
  107.         }
  108. }

  109. void main()
  110. {        
  111.         TIM0init();
  112.         while(1)
  113.         {        
  114.                 Key();
  115.                 IR_LED();
  116.         }
  117. }        

复制代码


回复

使用道具 举报

ID:161164 发表于 2022-6-10 15:52 | 显示全部楼层
  1. #include <reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. unsigned char irtime;//红外用全局变量
  5. bit irpro_ok,irok;
  6. bit key_ok;//<<<<<<<<<<<<<<<<<<<<<<<<<<<
  7. unsigned char IRcord[4];//用来存放用户码、用户反码、数据码、数据反码
  8. unsigned char irdata[33];//用来存放32位码值

  9. typedef unsigned char u8;
  10. typedef unsigned int u16;

  11. u16 mode;

  12. sbit key = P3^4;

  13. void delay(u16 i)
  14. {
  15.         while(i--);
  16. }

  17. void tim0_isr()interrupt 1  //定时器0中断服务函数
  18. {
  19.         irtime++;
  20. }

  21. void ex0_isr()interrupt 0   //外部中断0服务函数
  22. {
  23.         static unsigned char i;
  24.         static bit startflag;
  25.         if(startflag)
  26.         {
  27.                 if(irtime<53&&irtime>=32)
  28.                         i=0;
  29.                 irdata[ i]=irtime;
  30.                 [ i]
  31.                 irtime=0;
  32.                 i++;
  33.                 if(i==33)
  34.                 {
  35.                         irok=1;
  36.                         i=0;
  37.                 }
  38.         }
  39.         else
  40.         {
  41.                 irtime=0;
  42.                 startflag=1;
  43.         }
  44. }

  45. void TIM0init()//定时器0初始化
  46. {
  47.         TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
  48.         TH0=0x00;
  49.         TL0=0x00;
  50.         EA=1;
  51.         ET0=1;//开总中断
  52.         TR0=1;

  53.         IT0=1;
  54.         EX0=1;

  55. }
  56. void Ircordpro()//红外码值处理函数(关键函数)
  57. {
  58.         unsigned char i,j,k=1;
  59.         unsigned char cord,value;

  60.         for(i=0; i<4; i++)              //处理4个字节
  61.         {
  62.                 for(j=1; j<=8; j++)       //处理1个字节8位
  63.                 {
  64.                         cord=irdata[k];
  65.                         value=value>>1;
  66.                         if(cord>7)value=value|0x80;//大于某值为1
  67.                         k++;
  68.                 }
  69.                 IRcord[ i]=value;
  70.                 [ i]
  71.                 value=0;
  72.         }
  73.         irpro_ok=1;//处理完毕标志位置1
  74. }

  75. void Key()                          //按键
  76. {
  77.         if(key==0)
  78.         {
  79.                 delay(1000);
  80.                 if(key==0)
  81.                 {
  82.                         key_ok = 1;//<<<<<<<<<<<<<<<<<<<<<<<<<<<
  83.                         mode++;
  84.                         if(mode==8)
  85.                         {
  86.                                 mode=0;
  87.                         }
  88.                         while(!key);
  89.                 }
  90.         }
  91. }

  92. void IR_LED()
  93. {
  94.         if(irok)
  95.         {
  96.                 Ircordpro();
  97.                 irok=0;
  98.         }
  99. }
  100. void Led_Control()//<<<<<<<<<<<<<<<<<<<<<<<<<<<
  101. {
  102.         static u8 Temp = 0;
  103.         if(irpro_ok)
  104.         {
  105.                 irpro_ok = 0;
  106.                 Temp = IRcord[2];
  107.         }
  108.         if(key_ok)
  109.         {
  110.                 key_ok = 0;
  111.                 Temp = mode+4;
  112.         }
  113.         switch(Temp)
  114.         {
  115.                 case 0x04:P1 = 0x01; break;      //打开红色LED
  116.                 case 0x05:P1 = 0x02; break;      //打开绿色LED
  117.                 case 0x06:P1 = 0x04; break;      //打开蓝色LED
  118.                 case 0x07:P1 = 0x07; break;      //打开白色LED
  119.                 case 0x08:P1 = 0x03; break;      //打开红绿色LED
  120.                 case 0x09:P1 = 0x05; break;      //打开红蓝色LED
  121.                 case 0x0a:P1 = 0x06; break;      //打开绿蓝色LED
  122.                 default:break;
  123.         }
  124. }
  125. void main()
  126. {
  127.         TIM0init();
  128.         while(1)
  129.         {
  130.                 Key();
  131.                 IR_LED();
  132.                 Led_Control();//<<<<<<<<<<<<<<<<<<<<<<<<<<<
  133.         }
  134. }

复制代码


回复

使用道具 举报

ID:213173 发表于 2022-6-10 16:27 | 显示全部楼层
两者能对同一个变量控制就整合到一起了。
回复

使用道具 举报

ID:899076 发表于 2022-6-10 17:22 | 显示全部楼层
wulin 发表于 2022-6-10 16:27
两者能对同一个变量控制就整合到一起了。

就是不知道如何控制,能否给个示例呢。
回复

使用道具 举报

ID:899076 发表于 2022-6-10 23:46 | 显示全部楼层

感谢大佬,还有个问题请教一下。按照你的代码下载进去之后发现上电时按下按键第一次的时候直接跳过第一个“case 0x04:P1 = 0x01; break;      //打开红色LED”直接从第二行“case 0x05:P1 = 0x02; break;      //打开绿色LED”开始执行。当case循环一周之后就又正常了。
回复

使用道具 举报

ID:161164 发表于 2022-6-11 17:37 来自手机 | 显示全部楼层
修罗_战 发表于 2022-6-10 23:46
感谢大佬,还有个问题请教一下。按照你的代码下载进去之后发现上电时按下按键第一次的时候直接跳过第一个 ...

大问题已帮你解决了
小问题就当是功课吧~
回复

使用道具 举报

ID:899076 发表于 2022-6-16 18:31 | 显示全部楼层
lkc8210 发表于 2022-6-11 17:37
大问题已帮你解决了
小问题就当是功课吧~

谢谢大佬,我把按键功能做到void Led_Control()里面问题解决了。

void Led_Control()//<<<<<<<<<<<<<<<<<<<<<<<<<<<
{
        static u8 Temp = 0;
        if(irok)
    {
        Ircordpro();
        irok=0;
    }
    if(irpro_ok)
    {
                irpro_ok = 0;
                Temp = IRcord[2];
    }
    if(key_ok)
    {
        key_ok = 0;
        Temp = mode+4;
                mode++;                          //*****************
                if(mode == 8)          //******************
                {                                  //*********************
                        mode = 0;          //************************
                }                                  //*****************

    }   
    switch(Temp)
    {
        case 0x04:P1 = 0x01; break;      //打开红色LED
        case 0x05:P1 = 0x02; break;      //打开绿色LED
        case 0x06:P1 = 0x04; break;      //打开蓝色LED
        case 0x07:P1 = 0x07; break;      //打开白色LED
        case 0x08:P1 = 0x03; break;      //打开红绿色LED
        case 0x09:P1 = 0x05; break;      //打开红蓝色LED
        case 0x0a:P1 = 0x06; break;      //打开绿蓝色LED
                case 0x0b:LED_R(); break;        //打开红色LED呼吸
        default:break;
    }
}
回复

使用道具 举报

ID:899076 发表于 2022-6-16 18:38 | 显示全部楼层
lkc8210 发表于 2022-6-11 17:37
大问题已帮你解决了
小问题就当是功课吧~

但是我又有个疑惑,现在的按键功能是按循序依次往下实行的。比如
case 0x04: ................;break;
case 0x05: ................;break;
case 0x06: ................;break;
case 0x07: ................;break;
case 0x08: ................;break;
按循序依次往上+1,那么如果我0x05这行去掉之后按键就会空按一下才能跳到0x06这一行。这个又改怎样做呢
大佬有空能否帮忙解答一下,谢谢
回复

使用道具 举报

ID:161164 发表于 2022-6-16 21:17 | 显示全部楼层
修罗_战 发表于 2022-6-16 18:38
但是我又有个疑惑,现在的按键功能是按循序依次往下实行的。比如
case 0x04: ................;break;
...

case 0x04: ................;break;
case 0x05: Temp=0x06; mode = 2; break;
case 0x06: ................;break;
case 0x07: ................;break;
case 0x08: ................;break;
简单粗爆
回复

使用道具 举报

ID:383215 发表于 2022-6-16 22:30 | 显示全部楼层
太乱了,基本上一点思路都没有,最近我可能也要编类似的程序,想想没有什么难度啊,板凳的说法是对的,两者能对同一个变量控制就整合到一起了。可惜哪里有整合?基本编程思路,按键去抖动得到稳定键值,红外接收得到稳定键值,这两个键值共用一个全局变量,比如叫做key_ok,if(key_ok==某键值){key_ok=0;操作1;操作2},最关键就是查询到一个稳定键值之后,稳定键值一定要清零,然后执行相应的操作,这就要求按键去抖动和红外接收要相当可靠,剩下的操作就简单了,if语句太多可改为switch语句就完事了。
回复

使用道具 举报

ID:899076 发表于 2022-6-17 09:59 | 显示全部楼层
lkc8210 发表于 2022-6-16 21:17
case 0x04: ................;break;
case 0x05: Temp=0x06; mode = 2; break;
case 0x06: ......... ...

非常感谢大佬的指点,这样做之后按键是正常的了。可是在红外遥控上面0x05跟0x06就同时控制一个功能了
回复

使用道具 举报

ID:264021 发表于 2022-7-8 18:46 | 显示全部楼层
遥控某个键用A代表,独立某个按键用B代表,if{(A==0x11)||(B==0)}{BEEP=0;}这样简单实现遥控和按键,A.B无论谁按下都能,控制蜂鸣器
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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