找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1060|回复: 0
打印 上一主题 下一主题
收起左侧

单片机红外遥控定时0.5-10小时源程序

[复制链接]
跳转到指定楼层
楼主
ID:322197 发表于 2022-10-28 08:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. /*************        用户系统配置        **************/

  2. #define MAIN_Fosc                12000000L        //定义主时钟, 模拟串口和红外接收会自动适应。5~36MHZ

  3. #define D_TIMER0                125                        //选择定时器时间, us, 红外接收要求在60us~250us之间

  4. #define        User_code                0xFD02                //定义红外接收用户码


  5. /*************        以下宏定义用户请勿修改        **************/
  6. #include        "reg51.H"
  7. #define        uchar        unsigned char
  8. #define uint        unsigned int

  9. #define freq_base                        (MAIN_Fosc / 1200)
  10. #define Timer0_Reload                (65536 - (D_TIMER0 * freq_base / 10000))

  11. sfr AUXR = 0x8e;
  12. sfr IE2  = 0xAF;
  13. sfr        T2H  = 0xD6;
  14. sfr        T2L  = 0xD7;


  15. /*************        本地常量声明        **************/



  16. /*************        本地变量声明        **************/
  17. sbit        P_IR_RX = P3^2;                //定义红外接收输入端口
  18. sbit    LED1    = P3^0;
  19. sbit    LED2    = P3^1;
  20. sbit    LED3    = P3^3;
  21. sbit    LED4    = P3^4;                //定义提示灯输出端口
  22. sbit    L2      = P3^5;                //定义继电器输出端口

  23. bit                P_IR_RX_temp;                //Last sample
  24. bit                B_IR_Sync;                        //已收到同步标志
  25. uchar        IR_SampleCnt;                //采样计数
  26. uchar        IR_BitCnt;                        //编码位数
  27. uchar        IR_UserH;                        //用户码(地址)高字节
  28. uchar        IR_UserL;                        //用户码(地址)低字节
  29. uchar        IR_data;                        //数据原码
  30. uchar        IR_DataShit;                //数据反码
  31. uchar   IR_BUF[2];

  32. bit                B_IrUserErr;                //User code error flag
  33. bit                B_IR_Press;                        //Key press flag,include repeat key.
  34. uchar        IR_code;                        //IR code        红外键码

  35. bit FLAG = 0;       //计数完成标志位

  36. uint count;     //计数变量1
  37. uint count2;    //计数变量2
  38. uint count3;    //计数变量3


  39. /*************        本地函数声明        **************/
  40. uchar        HEX2ASCII(uchar dat);
  41. void        InitTimer(void);
  42. void         Timer2Init(void);


  43. /*************  外部函数和变量声明 *****************/



  44. /********************* 主函数 *************************/
  45. void main(void)
  46. {
  47.         L2   = 1;
  48.         LED1 = 1;
  49.         LED2 = 1;
  50.         LED3 = 1;                        //端口初始化
  51.         InitTimer();                //初始化Timer0
  52.         Timer2Init();                //初始化Timer2
  53.         

  54.         while(1)
  55.         {
  56.                 if(B_IR_Press)                //有IR键按下
  57.                 {
  58.                         B_IR_Press = 0;                //清除IR键按下标志
  59.                         if((HEX2ASCII(IR_code >> 4))=='1'&&HEX2ASCII(IR_code)=='8')L2=~L2; //如果按键码是18,启动继电器
  60.                         if((HEX2ASCII(IR_code >> 4))=='1'&&HEX2ASCII(IR_code)=='A')        //如果按键码是0A,启动继电器,并开始计时,0.5小时后关闭继电器
  61.                         {
  62.                                 L2     = 0;
  63.                                 LED1   = 1;LED2 = 1;LED3 = 1;LED4 = 1;        //打开红灯
  64.                                 count  = 0;
  65.                                 count2 = 30;        //30
  66.                                 count3 = 11;                                        //定时0.5小时
  67.                                 IE2   |= 0x04;                                //启动定时器2

  68.                         }                        if((HEX2ASCII(IR_code >> 4))=='1'&&HEX2ASCII(IR_code)=='7')        //如果按键码是17,启动继电器,并开始计时,1小时后关闭继电器
  69.                         {
  70.                                 L2     = 0;
  71.                                 LED1   = 0;LED2 = 1;LED3 = 1;LED4 = 1;        //打开红灯
  72.                                 count  = 0;
  73.                                 count2 = 0;
  74.                                 count3 = 11;                                        //定时1小时
  75.                                 IE2   |= 0x04;                                //启动定时器2

  76.                         }
  77.                         if((HEX2ASCII(IR_code >> 4))=='1'&&HEX2ASCII(IR_code)=='6')        //如果按键码是16,启动继电器,并开始计时,2小时后关闭继电器
  78.                         {
  79.                                 L2     = 0;
  80.                                 LED1   = 1;LED2 = 0;LED3 = 1;LED4 = 1;                //打开红灯和黄灯
  81.                                 count  = 0;
  82.                                 count2 = 0;
  83.                                 count3 = 10;                                        //定时2小时
  84.                                 IE2   |= 0x04;                                //启动定时器2
  85.                                 

  86.                         }
  87.                         if((HEX2ASCII(IR_code >> 4))=='1'&&HEX2ASCII(IR_code)=='5')        //如果按键码是15,启动继电器,并开始计时,3小时后关闭继电器
  88.                         {
  89.                                 L2     = 0;
  90.                                 LED1   = 1;LED2 = 1;LED3 = 0;LED4 = 1;                //打开红灯和黄灯
  91.                                 count  = 0;
  92.                                 count2 = 0;
  93.                                 count3 = 9;                                        //定时3小时
  94.                                 IE2   |= 0x04;                                //启动定时器2
  95.                                 

  96.                         }
  97.                         if((HEX2ASCII(IR_code >> 4))=='1'&&HEX2ASCII(IR_code)=='4')        //如果按键码是14,启动继电器,并开始计时,4小时后关闭继电器
  98.                         {
  99.                                 L2     = 0;
  100.                                 LED1   = 1;LED2 = 1;LED3 = 1;LED4 = 0;                //打开红灯和黄灯
  101.                                 count  = 0;
  102.                                 count2 = 0;
  103.                                 count3 = 8;                                        //定时4小时
  104.                                 IE2   |= 0x04;                                //启动定时器2
  105.                                 

  106.                         }
  107.                         if((HEX2ASCII(IR_code >> 4))=='1'&&HEX2ASCII(IR_code)=='3')        //如果按键码是13,启动继电器,并开始计时,5小时后关闭继电器
  108.                         {
  109.                                 L2     = 0;
  110.                                 LED1   = 0;LED2 = 1;LED3 = 1;LED4 = 0;                //打开红灯和黄灯
  111.                                 count  = 0;
  112.                                 count2 = 0;
  113.                                 count3 = 7;                                        //定时5小时
  114.                                 IE2   |= 0x04;                                //启动定时器2
  115.                                 

  116.                         }
  117.                         if((HEX2ASCII(IR_code >> 4))=='1'&&HEX2ASCII(IR_code)=='2')        //如果按键码是12,启动继电器,并开始计时,6小时后关闭继电器
  118.                         {
  119.                                 L2     = 0;
  120.                                 LED1   = 1;LED2 = 0;LED3 = 1;LED4 = 0;                //打开红灯和黄灯
  121.                                 count  = 0;
  122.                                 count2 = 0;
  123.                                 count3 = 6;                                        //定时6小时
  124.                                 IE2   |= 0x04;                                //启动定时器2
  125.                                 

  126.                         }
  127.                         if((HEX2ASCII(IR_code >> 4))=='1'&&HEX2ASCII(IR_code)=='1')        //如果按键码是11,启动继电器,并开始计时,7小时后关闭继电器
  128.                         {
  129.                                 L2     = 0;
  130.                                 LED1   = 1;LED2 = 1;LED3 = 0;LED4 = 0;                //打开红灯和黄灯
  131.                                 count  = 0;
  132.                                 count2 = 0;
  133.                                 count3 = 5;                                        //定时7小时
  134.                                 IE2   |= 0x04;                                //启动定时器2
  135.                                 

  136.                         }
  137.                         if((HEX2ASCII(IR_code >> 4))=='1'&&HEX2ASCII(IR_code)=='0')        //如果按键码是10,启动继电器,并开始计时,8小时后关闭继电器
  138.                         {
  139.                                 L2     = 0;
  140.                                 LED1   = 0;LED2 = 1;LED3 = 0;LED4 = 0;                //打开红灯和黄灯
  141.                                 count  = 0;
  142.                                 count2 = 0;
  143.                                 count3 = 4;                                        //定时8小时
  144.                                 IE2   |= 0x04;                                //启动定时器2
  145.                                 

  146.                         }
  147.                         if((HEX2ASCII(IR_code >> 4))=='0'&&HEX2ASCII(IR_code)=='F')        //如果按键码是0F,启动继电器,并开始计时,9小时后关闭继电器
  148.                         {
  149.                                 L2     = 0;
  150.                                 LED1   = 1;LED2 = 0;LED3 = 0;LED4 = 0;                //打开红灯和黄灯
  151.                                 count  = 0;
  152.                                 count2 = 0;
  153.                                 count3 = 3;                                        //定时9小时
  154.                                 IE2   |= 0x04;                                //启动定时器2
  155.                                 

  156.                         }
  157.                                 if((HEX2ASCII(IR_code >> 4))=='0'&&HEX2ASCII(IR_code)=='E')        //如果按键码是0E,启动继电器,并开始计时,10小时后关闭继电器
  158.                         {
  159.                                 L2     = 0;
  160.                                 LED1   = 0;LED2 = 0;LED3 = 0;LED4 = 0;                 //打开红灯、黄灯、绿灯
  161.                                 count  = 0;
  162.                                 count2 = 0;
  163.                                 count3 = 2;                                        //定时10小时
  164.                                 IE2   |= 0x04;                                //启动定时器2
  165.                                 if(count3==1)LED3 = 1;      //如果一小时到,关闭绿灯
  166.                                 if(count2==30&&count3==1)LED2 = 1;      //如果一个半小时到,关闭黄灯

  167.                         }
  168.                 }
  169.                 if(FLAG == 1)                                                //定时计数时间到标志
  170.                 {
  171.                         FLAG = 0;                                                //标志清0
  172.                         IE2  &= ~(1<<2);                                //关闭定时器2
  173.                 }
  174.                 if(count2==30)LED2 = 1;                 //如果半小时到,关闭黄灯
  175.                 if(count2==30&&count3==1)LED2 = 1;      //如果一个半小时到,关闭黄灯
  176.                 if(L2==1)
  177.                 {
  178.                         LED1 = 1;
  179.                         LED2 = 1;
  180.                         LED3 = 1;
  181.          LED4 = 1;                 //继电器关掉,灯也关掉
  182.                 }
  183.         }
  184. }


  185. /********************* 十六进制转ASCII函数 *************************/
  186. uchar        HEX2ASCII(uchar dat)
  187. {
  188.         dat &= 0x0f;
  189.         if(dat <= 9)        return (dat + '0');        //数字0~9
  190.         return (dat - 10 + 'A');                        //字母A~F
  191. }


  192. /******************** 红外采样时间宏定义, 用户不要随意修改        *******************/

  193. #if ((D_TIMER0 <= 250) && (D_TIMER0 >= 60))
  194.         #define        D_IR_sample                        D_TIMER0                //定义采样时间,在60us~250us之间
  195. #endif

  196. #define D_IR_SYNC_MAX                (15000/D_IR_sample)        //SYNC max time
  197. #define D_IR_SYNC_MIN                (9700 /D_IR_sample)        //SYNC min time
  198. #define D_IR_SYNC_DIVIDE        (12375/D_IR_sample)        //decide data 0 or 1
  199. #define D_IR_DATA_MAX                (3000 /D_IR_sample)        //data max time
  200. #define D_IR_DATA_MIN                (600  /D_IR_sample)        //data min time
  201. #define D_IR_DATA_DIVIDE        (1687 /D_IR_sample)        //decide data 0 or 1
  202. #define D_IR_BIT_NUMBER                32                                        //bit number

  203. //*******************************************************************************************
  204. //**************************** IR RECEIVE MODULE ********************************************

  205. void IR_RX_HT6121(void)
  206. {
  207.         uchar        SampleTime;

  208.         IR_SampleCnt++;                                                        //Sample + 1

  209.         F0 = P_IR_RX_temp;                                                //Save Last sample status
  210.         P_IR_RX_temp = P_IR_RX;                                        //Read current status
  211.         if(F0 && !P_IR_RX_temp)                                        //Last sample is high,and current sample is low, so is fall edge
  212.         {
  213.                 SampleTime = IR_SampleCnt;                        //get the sample time
  214.                 IR_SampleCnt = 0;                                        //Clear the sample counter

  215.                          if(SampleTime > D_IR_SYNC_MAX)                B_IR_Sync = 0;        //large the Maxim SYNC time, then error
  216.                 else if(SampleTime >= D_IR_SYNC_MIN)                                        //SYNC
  217.                 {
  218.                         if(SampleTime >= D_IR_SYNC_DIVIDE)
  219.                         {
  220.                                 B_IR_Sync = 1;                                        //has received SYNC
  221.                                 IR_BitCnt = D_IR_BIT_NUMBER;        //Load bit number
  222.                         }
  223.                 }
  224.                 else if(B_IR_Sync)                                                //has received SYNC
  225.                 {
  226.                         if(SampleTime > D_IR_DATA_MAX)                B_IR_Sync=0;        //data samlpe time to large
  227.                         else
  228.                         {
  229.                                 IR_DataShit >>= 1;                                        //data shift right 1 bit
  230.                                 if(SampleTime >= D_IR_DATA_DIVIDE)        IR_DataShit |= 0x80;        //devide data 0 or 1
  231.                                 if(--IR_BitCnt == 0)                                //bit number is over?
  232.                                 {
  233.                                         B_IR_Sync = 0;                                        //Clear SYNC
  234.                                         if(~IR_DataShit == IR_data)                //判断数据正反码
  235.                                         {
  236.                                                 if((IR_UserH == (User_code / 256)) &&
  237.                                                         IR_UserL == (User_code % 256))
  238.                                                                 B_IrUserErr = 0;        //User code is righe
  239.                                                 else        B_IrUserErr = 1;        //user code is wrong
  240.                                                         
  241.                                                 IR_code      = IR_data;
  242.                                                 B_IR_Press   = 1;                        //数据有效
  243.                                         }
  244.                                 }
  245.                                 else if((IR_BitCnt & 7)== 0)                //one byte receive
  246.                                 {
  247.                                         IR_UserL = IR_UserH;                        //Save the User code high byte
  248.                                         IR_UserH = IR_data;                                //Save the User code low byte
  249.                                         IR_data  = IR_DataShit;                        //Save the IR data byte
  250.                                 }
  251.                         }
  252.                 }
  253.         }
  254. }


  255. /**************** Timer初始化函数 ******************************/
  256. void InitTimer(void)
  257. {
  258.         TMOD = 0;                //for STC15Fxxx系列        Timer0 as 16bit reload timer.
  259.         TH0 = Timer0_Reload / 256;
  260.         TL0 = Timer0_Reload % 256;
  261.         ET0 = 1;
  262.         TR0 = 1;

  263.         EA  = 1;
  264. }

  265. /**************** Timer2初始化函数 ******************************/
  266. void Timer2Init(void)                 //50毫秒@11.0592MHz
  267. {
  268.         AUXR &= 0xFB;  //定时器12T模式
  269.         T2L   =        0x00;
  270.         T2H   =        0x4C;  //设置定时器初值
  271.         IE2  &= ~(1<<2);  //关闭定时器2产生中断
  272.         AUXR |= 0x10;  //定时2开始计时
  273.         EA    = 1;     //开总中断
  274. }



  275. /********************** Timer0中断函数************************/
  276. void timer0 (void) interrupt 1
  277. {
  278.         IR_RX_HT6121();
  279. }


  280. /********************** Timer2中断函数************************/
  281. void Timer2()interrupt 12 using 1
  282. {
  283.         T2L   =        0x00;
  284.         T2H   =        0x4C;            //50MS
  285.         count++;
  286.         if(count==1200)            //60S 1200
  287.         {
  288.                 count=0;
  289.                 count2++;
  290.                 if(count2==60)        //60分钟  60
  291.                 {
  292.                         count2=0;
  293.                         count3++;
  294.                         if(count3==12)//2小时 2
  295.                         {
  296.                                 count3=0;
  297.                                 LED1 = 1;
  298.                                 LED2 = 1;
  299.             LED3 = 1;
  300.                                 LED4 = 1;          //关闭提示灯
  301.                                 L2 = ~L2;          //关闭继电器
  302.                                 FLAG = 1;          //计数时间到标志
  303.                         }
  304.                 }
  305.         }               
  306. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶1 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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