微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 红外遥控系统原理及单片机软件解码程序

红外遥控系统原理及单片机软件解码程序

时间:11-23 来源:互联网 点击:

  1. g=START_Judge();
  2. BOOT_REPEATING_CODE_Flag=BOOT_REPEATING_CODE_Judge();
  3. if(START_Flag&&!BOOT_REPEATING_CODE_Flag)
  4. {
  5. for(i=0;i<4;i++)
  6. {
  7. B0=H_L_LEVEL_Judge();
  8. B1=H_L_LEVEL_Judge();
  9. B2=H_L_LEVEL_Judge();
  10. B3=H_L_LEVEL_Judge();
  11. B4=H_L_LEVEL_Judge();
  12. B5=H_L_LEVEL_Judge();
  13. B6=H_L_LEVEL_Judge();
  14. B7=H_L_LEVEL_Judge();
  15. DATA[i]=TEMP_BIT;
  16. }
  17. for(i=0;i<4;i++)
  18. {
  19. SBUF=DATA[i];
  20. while(TI==0);
  21. TI=0;
  22. }
  23. }
  24. }
  25. }
  26. voidUART_Initial()
  27. {
  28. SCON=0x50;//SCON:模式1,8-bitUART,使能接收
  29. TMOD|=0x20;//TMOD:timer1,mode2,8-bitreload
  30. TH1=0xFD;//TH1:reloadvaluefor9600baud@
  31. //11.0592MHz
  32. TR1=1;//TR1:timer1run
  33. EA=0;//关闭总中断
  34. ES=0;//关闭串口中断
  35. }
  36. bitSTART_Judge()
  37. {
  38. bitTEMP_Flag=1;
  39. unsignedchari=0;
  40. //在正常无遥控信号时,一体化红外接收头输出是高电平,程序一直在循环。
  41. while(IR_Out==1);
  42. //重复10次,目的是检测在6876~8352微秒内如果出现高电平就退出解码程序
  43. for(i=0;i<9;i++)
  44. {
  45. DELAY_Us(800);//测试实际延时约为764~928us
  46. if(IR_Out==1)
  47. {
  48. TEMP_Flag=0;
  49. break;
  50. }
  51. }
  52. returnTEMP_Flag;
  53. }
  54. bitBOOT_REPEATING_CODE_Judge()
  55. {
  56. bitTEMP_Flag=1;
  57. while(IR_Out==0);//等待高电平避开9毫秒低电平引导脉冲
  58. DELAY_Ms(1);//测试实际延时约为1.007ms
  59. DELAY_Ms(1);//测试实际延时约为1.007ms
  60. DELAY_Us(200);//0.086ms
  61. DELAY_Us(200);//0.086ms
  62. DELAY_Us(200);//0.086ms
  63. //共计2.272ms
  64. if(IR_Out==0)
  65. {
  66. TEMP_Flag=1;//是连发码
  67. }
  68. else
  69. {
  70. TEMP_Flag=0;//不是连发码,而是引导码
  71. }
  72. returnTEMP_Flag;
  73. }
  74. bitH_L_LEVEL_Judge()
  75. {
  76. while(IR_Out==0);//等待地址码第一位的高电平信号
  77. DELAY_Us(800);//测试实际延时约为764~928us
  78. if(IR_Out==1)
  79. {
  80. DELAY_Ms(1);//测试实际延时约为1.007ms
  81. return1;
  82. }
  83. else
  84. {
  85. return0;
  86. }
  87. }

编辑如下:

01 FE 8B 74 --- 01 FE 8D 72 --- 01 FE 8F 70

01 FE 89 76 --- 01 FE 81 7E --- 01 FE 87 78

01 FE 0F F0 --- 01 FE 2B D4 --- 01 FE 13 EC

01 FE 2D D2 --- 01 FE 33 CC --- 01 FE 1B E4

01 FE 19 E6 --- 01 FE 31 CE --- 01 FE BD 42

01 FE 11 EE --- 01 FE 39 C6 --- 01 FE B5 4A
以上为对应按键的编码。

过程中存在问题:

一是如何有效的识别引导码和连发码,因为这个能直接影响到长时间按键,单片机的响应与否。这个问题,貌似我以解决,就是长时间按键后,单片机识别一次按键后,如果还是同一按键,就不与理睬。

还有一个问题就是,如果连续按下两次按键,该程序能够识别出,但是如果间隔很短,第二下按键的编码容易出错,容易变成这样:

03 FE 8B 74.。。。就是第一个字节出现误差,这个问题现在还未来得及解决。

还有就是本程序对于延时函数的精度要求很高,因为本身处理的脉冲就是MS级别的。所以需要严格的测试延时函数的实际延时时间:

以上的代码,可以看出许多问题,软件延时不准确,大量的“while( IR_Out == 0 ) ;”代码,抗干扰能力弱,容易进入死循环。

下面介绍的这种解码方法,利用外部中断触发程序,定时器定时(但没有设置定时中断程序,即判断TF的值确定定时结束),在代码过程中,开头的一个7.93ms延时,足以滤掉不合法的红外信号。应该说效率质量更高的。

代码注释很详细,在此不在细述:

[cpp]view plaincopy

  1. /*------------------------------------------------------------*-
  2. IR_Decoder.C(v1.00)
  3. ------------------------------------------------------------
  4. 名称:遥控器红外解码,PO口接LED,显示功能码以供查看
  5. 编写:mhjerry
  6. 日期:20011.7
  7. 内容:按遥控器上的按键,会在PO口LED上显示
  8. -*------------------------------------------------------------*/
  9. #include"reg52.h"
  10. //此口为红外信号输入MCU口
  11. sbitIR_Out=P3^2;
  12. //主程序运行标志位,运行主程序时LED灭,运行中断程序时LED亮
  13. sbitIR_Flag=P3^1;
  14. //LED显示口
  15. #defineLED_PortP1
  16. //用于存放按键码值,初始化为00000000这样接受数据时可以只考虑1了
  17. unsignedchardat[4]={0,0,0,0};
  18. /*............................................................*/
  19. voidmain()
  20. {
  21. IR_Out=1;//此口为MCU输入口,故需要置1
  22. IR_Flag=1;//灭LED灯
  23. TMOD=0x01;//定时器0,方式1
  24. IT0=1;//外部中断0,下降沿触发
  25. EX0=1;//准许外部中断
  26. EA=1;//CPU准许中断
  27. while(1)
  28. {
  29. IR_Flag=1;//执行主程序时,LED灯灭
  30. }
  31. }
  32. /*------------------------------------------------------------*-
  33. 函数名称:Int0()
  34. 函数输入:无(容许中断时,外部触发)
  35. 函数输出:无
  36. 函数说明:外部中断0中断处理
  37. -*-------------------------------------------------

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top