51单片机个人学习笔记16(红外遥控)

打印 上一主题 下一主题

主题 540|帖子 540|积分 1620

前言

本篇文章属于STC89C52单片机(以下简称单片机)的学习笔记,泉源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记,只能做参考,细节方面建议观看视频,肯定受益匪浅。
[1-1] 课程简介_哔哩哔哩_bilibili
 一、红外遥控介绍


二、硬件电路



   此中的三极管是低电平导通,红外信号发送时要进行调制,继承时要进行解调,OUT输出的就是解调后的方波,OUT要接到单片机的外部中断上,保证单片机能捕捉到这个信号 
  三、基本发送与继承


 四、NEC编码


   留意Data的逻辑0和逻辑1,不是单纯的高低电平,而是高低电平的组合,Repeat信号是当一个按键一直处于按下状态,就重复利用这个按键
  五、遥控器键码



 六、51单片机的外部中断


七、外部中断寄存器



八、实例一(红外遥控) 

   主要有Timer0.c 和 Int0.c 和IR.c 和 main.c
    1.Timer0.c模块,主要用于计时,来判断信号类型
  1. #include <REGX52.H>
  2. void Timer0_Init(void)               
  3. {
  4.         TMOD &= 0xF0;                //设置定时器模式
  5.         TMOD |= 0x01;                //设置定时器模式
  6.         TL0 = 0;                //设置定时初值
  7.         TH0 = 0;                //设置定时初值
  8.         TF0 = 0;                //清除TF0标志
  9.         TR0 = 0;                //定时器0不计时
  10. }
  11. void Timer0_SetCounter(unsigned char Value)
  12. {
  13.         TH0=Value/256;
  14.         TL0=Value%256;
  15. }
  16. unsigned int Timer0_GetCounter(void)
  17. {
  18.         return (TH0<<8)|TL0;
  19. }
  20. void Timer0_Run(unsigned char Flag)
  21. {
  22.         TR0=Flag;
  23. }
复制代码
   2.Int0.c 外部中断模块,使红外遥控的命令处于较高的优先级,保证数据不丢失
  1. #include <REGX52.H>
  2. void Int0_Init(void)
  3. {
  4.         IT0=1;
  5.         IE0=0;
  6.         EX0=1;
  7.         EA=1;
  8.         PX0=1;
  9. }
  10. /*中断函数模板
  11. void Int0_Routine(void) interrupt 0
  12. {
  13.        
  14. }
  15. */
复制代码

   3.IR.c 红外遥控模块 ,解码过程
  1. #include <REGX52.H>
  2. #include "Int0.h"
  3. #include "Timer0.h"
  4. unsigned int IR_Time;
  5. unsigned char IR_State;
  6. unsigned char IR_Data[4];
  7. unsigned char IR_pData;
  8. unsigned char IR_DataFlag;
  9. unsigned char IR_RepeatFlag;
  10. unsigned char IR_Address;
  11. unsigned char IR_Command;
  12. void IR_Init(void)
  13. {
  14.         Timer0_Init();
  15.         Int0_Init();
  16. }
  17. unsigned char IR_GetDataFlag(void)
  18. {
  19.         if (IR_DataFlag)
  20.         {
  21.                 IR_DataFlag=0;
  22.                 return 1;
  23.         }
  24.         return 0;
  25. }
  26. unsigned char IR_GetRepeatFlag(void)
  27. {
  28.         if (IR_RepeatFlag)
  29.         {
  30.                 IR_RepeatFlag=0;
  31.                 return 1;
  32.         }
  33.         return 0;
  34. }
  35. unsigned char IR_GetAddress(void)
  36. {
  37.         return IR_Address;
  38. }
  39. unsigned char IR_GetCommand(void)
  40. {
  41.         return IR_Command;
  42. }
  43. void Int0_Routine(void) interrupt 0
  44. {
  45.         if(IR_State==0)
  46.         {
  47.                 Timer0_SetCounter(0);
  48.                 Timer0_Run(1);
  49.                 IR_State=1;
  50.         }
  51.         else if (IR_State==1)
  52.         {
  53.                 IR_Time=Timer0_GetCounter();
  54.                 Timer0_SetCounter(0);
  55.                 if (IR_Time>13500-1000 && IR_Time<13500+1000)
  56.                 {
  57.                         IR_State=2;
  58.                 }
  59.                 else if (IR_Time>11250-1000 && IR_Time<11250+1000)
  60.                 {
  61.                         IR_RepeatFlag=1;
  62.                         Timer0_Run(0);
  63.                         IR_State=0;
  64.                 }
  65.                 else
  66.                 {
  67.                         IR_State=1;
  68.                 }
  69.         }
  70.         else if (IR_State==2)
  71.         {
  72.                 IR_Time=Timer0_GetCounter();
  73.                 Timer0_SetCounter(0);
  74.                 if (IR_Time>1120-500 && IR_Time<1120+500)
  75.                 {
  76.                         IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));
  77.                         IR_pData++;
  78.                 }
  79.                 else if (IR_Time>2250-500 && IR_Time<2250+500)
  80.                 {
  81.                         IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));
  82.                         IR_pData++;
  83.                 }
  84.                 else
  85.                 {
  86.                         IR_pData=0;
  87.                         IR_State=1;
  88.                 }
  89.                 if (IR_pData>=32)
  90.                 {
  91.                         IR_pData=0;
  92.                         if ((IR_Data[0]==~IR_Data[1]) && (IR_Data[2]==~IR_Data[3]))
  93.                         {
  94.                                 IR_Address=IR_Data[0];
  95.                                 IR_Command=IR_Data[2];
  96.                                 IR_DataFlag=1;
  97.                         }
  98.                         Timer0_Run(0);
  99.                         IR_State=0;
  100.                 }
  101.         }
  102. }
复制代码
   IR.h中定义键码值
  1. #ifndef __IR_H__
  2. #define __IR_H__
  3. #define IR_POWER                0x45
  4. #define IR_MODE                        0x46
  5. #define IR_MUTE                        0x47
  6. #define IR_START_STOP        0x44
  7. #define IR_PREVIOUS                0x40
  8. #define IR_NEXT                        0x43
  9. #define IR_EQ                        0x07
  10. #define IR_VOL_MINUS        0x15
  11. #define IR_VOL_ADD                0x09
  12. #define IR_0                        0x16
  13. #define IR_RPT                        0x19
  14. #define IR_USD                        0x0D
  15. #define IR_1                        0x0C
  16. #define IR_2                        0x18
  17. #define IR_3                        0x5E
  18. #define IR_4                        0x08
  19. #define IR_5                        0x1C
  20. #define IR_6                        0x5A
  21. #define IR_7                        0x42
  22. #define IR_8                        0x52
  23. #define IR_9                        0x4A
  24. void IR_Init(void);
  25. unsigned char IR_GetDataFlag(void);
  26. unsigned char IR_GetRepeatFlag(void);
  27. unsigned char IR_GetAddress(void);
  28. unsigned char IR_GetCommand(void);
  29. #endif
复制代码
   4.main.c 主函数调用模块
  
  1. #include <REGX52.H>
  2. #include "LCD1602.h"
  3. #include "Delay.h"
  4. #include "IR.h"
  5. unsigned char Address;
  6. unsigned char Command;
  7. unsigned char Num;
  8. void main()
  9. {
  10.         LCD_Init();
  11.         LCD_ShowString(1,1,"ADD");
  12.         LCD_ShowString(1,6,"CMD");
  13.         LCD_ShowString(1,11,"Num");
  14.         LCD_ShowString(2,1,"00");
  15.         LCD_ShowString(2,6,"00");
  16.         LCD_ShowString(2,11,"000");
  17.         IR_Init();
  18.         while(1)
  19.         {
  20.                 if(IR_GetDataFlag() || IR_GetRepeatFlag())
  21.                 {
  22.                         Address=IR_GetAddress();
  23.                         Command=IR_GetCommand();
  24.                        
  25.                         LCD_ShowHexNum(2,1,Address,2);
  26.                         LCD_ShowHexNum(2,6,Command,2);
  27.                        
  28.                         if (Command==IR_VOL_MINUS)
  29.                         {
  30.                                 Num--;
  31.                         }
  32.                         if (Command==IR_VOL_ADD)
  33.                         {
  34.                                 Num++;
  35.                         }
  36.                        
  37.                         LCD_ShowNum(2,11,Num,3);
  38.                 }
  39.         }
  40. }
复制代码
九、实例二(红外遥控电机调速)
   先把电机模块化
  Motor.c
  1. #include <REGX52.H>
  2. #include "Timer1.h"
  3. sbit Motor=P1^0;
  4. unsigned char Counter,Compare;
  5. void Motor_Init(void)
  6. {
  7.         Timer1_Init();
  8. }
  9. void Motor_SetSpeed(unsigned char Speed)
  10. {
  11.         Compare=Speed;
  12. }
  13. void Timer1_Rountine() interrupt 3
  14. {
  15.         TH1=0xFF;               
  16.         TL1=0xA4;                  
  17.         Counter++;
  18.         Counter%=100;
  19.         if (Counter<Compare)
  20.         {
  21.                 Motor=1;
  22.         }
  23.         else
  24.         {
  25.                 Motor=0;
  26.         }
  27. }
复制代码
 
    然后在主程序中应用红外模块和马达模块
  main.c
  1. #include <REGX52.H>
  2. #include "Nixie.h"
  3. #include "Motor.h"
  4. #include "Timer1.h"
  5. #include "IR.h"
  6. unsigned char Command,Speed;
  7. void main()
  8. {
  9.         Motor_Init();
  10.         IR_Init();
  11.         while(1)
  12.         {
  13.                 if(IR_GetDataFlag())
  14.                 {
  15.                         Command=IR_GetCommand();       
  16.                         if (Command==IR_0)
  17.                         {
  18.                                 Speed=0;
  19.                         }
  20.                         if (Command==IR_1)
  21.                         {
  22.                                 Speed=1;
  23.                         }
  24.                         if (Command==IR_2)
  25.                         {
  26.                                 Speed=2;
  27.                         }
  28.                         if (Command==IR_3)
  29.                         {
  30.                                 Speed=3;
  31.                         }
  32.                         switch(Speed)
  33.                         {
  34.                                 case 0:Motor_SetSpeed(0);break;
  35.                                 case 1:Motor_SetSpeed(50);break;
  36.                                 case 2:Motor_SetSpeed(75);break;
  37.                                 case 3:Motor_SetSpeed(100);break;
  38.                         }
  39.                 }
  40.                 Nixie(1,Speed);
  41.         }
  42. }
复制代码
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

王柳

金牌会员
这个人很懒什么都没写!

标签云

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