找回密码
 立即注册

QQ登录

只需一步,快速开始

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

8051单片机制作的红外遥控器控制的数码管时钟,可显示温度,并将温度值写入24c02.

[复制链接]
跳转到指定楼层
楼主
可以用红外遥控器控制的数码管时钟,不同按键控制写入ds1302的时间值,从而调整时间。也可通过按键显示温度,每次显示后将温度值顺序记入24c02。可以通过仿真查看24c02内的值。不同遥控器需要更改红外读入的键值,才能正常使用。仿真中用按键代替了红外显示温度。实物在普中开发板上运行通过。部分程序借用普中开发板附带代码修改而成。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. /*******************************************************************************
  2. 8 digits LED display Ds1302 Real time clock with IR remote adjust and temperature display
  3. ********************************************************************************/
  4. #include<reg52.h>
  5. #include<intrins.h>

  6. sbit SCL = P2^1;      /* 定义位变量 */             // I2C总线的时钟信号
  7. sbit SDA = P2^0;                                   // I2C总线的数据信号

  8. sbit DS1302_CK = P3^6;        //时钟       
  9. sbit DS1302_IO = P3^4;        //数据       
  10. sbit DS1302_CE = P3^5;// DS1302复位

  11. sbit LS138A = P2^2;         
  12. sbit LS138B = P2^3;          
  13. sbit LS138C = P2^4;       
  14. sbit BEEP = P1^5;
  15. sbit IRIN = P3^2;


  16. unsigned char t0,miao,fen,shi;
  17. unsigned int tabe2[8];
  18. unsigned char IRCOM[7];
  19. unsigned char AT24C02Address = 0;

  20. unsigned char code tabe1[]={~0xC0,~0xF9,~0xA4,~0xB0,~0x99,~0x92,~0x82,~0xF8,~0x80,~0x90,~0x40,};

  21. void display();
  22. void display_date();
  23. void display_temp();
  24. void Read_RTC();
  25. extern unsigned int ReadTemperature(void);
  26. extern void InitDS1302();
  27. extern void DS1302SingleWrite(unsigned char reg, unsigned char dat);
  28. extern unsigned char DS1302SingleRead(unsigned char reg);
  29. extern void DS1302SingleWriteRAM(unsigned char ram, unsigned char dat);
  30. extern unsigned char DS1302SingleReadRAM(unsigned char ram);

  31. extern void AT24C02_Write1Byte(        unsigned char AT24C02_Address, unsigned char AT24C02_1Byte);


  32. /******************************************************************/
  33. /*                   读时钟数据                                   */
  34. /******************************************************************/
  35. void Read_RTC(void)                //读取 日历
  36. {
  37. //unsigned char i,*p;
  38. //p=read_rtc_address;             //地址传递
  39. //for(i=0;i<7;i++)                    //分7次读取 秒分时日月周年
  40. //{
  41.   //tmpdate[i]=Read_Ds1302(*p);
  42.   //p++;
  43. //}
  44. miao=DS1302SingleRead(0x80); miao=(miao>>4)*10+(miao&0x0f);
  45. fen= DS1302SingleRead(0x81); fen=(fen>>4)*10+(fen&0x0f);
  46. shi= DS1302SingleRead(0x82); shi=(shi>>4)*10+(shi&0x0f);
  47. }


  48. void delay(unsigned int a)
  49. {
  50.     unsigned char i;
  51.     while(a--)
  52.          {
  53.             for(i=0;i<=80;i++)
  54.                 ;
  55.          }
  56.           
  57. }

  58. void delayIR(unsigned char x)    //x*0.14MS
  59. {
  60. unsigned char y;
  61.   while(x--)
  62. {
  63.   for (y = 0; y<13; y++) {}
  64. }
  65. }

  66. //=================================BEEP驱动===========================================//

  67. //sbit        Bell_Out        =        P3 ^ 0;//元件是动圈式扬声器(并非有源蜂鸣器),需要MCU驱动发声

  68. /********************************************************************************************/
  69. void bell(        unsigned char a,unsigned char b,unsigned char c,unsigned char d)
  70. {
  71.         for(;a>0;a--){//第一个声音的长度
  72.                 BEEP = !BEEP;//取反扬声器驱动口,以产生音频
  73.                 delay(b);//音调设置延时
  74.         }
  75.         for(;c>0;c--){//同上
  76.                 BEEP = !BEEP;
  77.                 delay(d);//
  78.         }
  79.         BEEP = 1;
  80. }
  81. /********************************************************************************************/
  82. //--------------------------------------------扬声器--按键音
  83. //void beep_k(void){beep(10,60,5,250); }
  84. //--------------------------------------------扬声器--闹钟报警
  85. //void beep_a(void){beep(250,16,150,40); }//BELL
  86. //--------------------------------------------扬声器--成功音
  87. //void beep_y(void){beep(50,30,100,50); }//BELL
  88. //--------------------------------------------扬声器--无效音
  89. //void beep_n(void){beep(50,80,100,100); }//BELL
  90. /********************************************************************************************/

  91. void beep(void)
  92. {
  93.   unsigned char i;
  94.             for (i=0;i<100;i++)
  95.                    {
  96.                    delay(1);
  97.                    BEEP=!BEEP;                 //BEEP reverse
  98.             }
  99.                   BEEP=1;                      //close buzzer
  100. }

  101. void main()
  102. {

  103.         BEEP = 1;                        //close buzzer
  104.            IT0=1;                       //enable timer 0
  105.            //IT1=1;      
  106.            EX0=1;                                //enable int 0
  107.         EX1=1;                                //enable int 1
  108.           TMOD=0x01,TH0=0x3c,TL0=0xb0, EA=1;//定时器0方式1, enable all int
  109.            ET0=1;                                //INT0下降沿有效
  110.            TR0=1;
  111.           
  112.    InitDS1302();
  113.         //DS1302SingleWrite(0x83,0x11);                 //set DATE
  114.         //DS1302SingleWrite(0x84,0x12);                 //set MONTH
  115.         //DS1302SingleWrite(0x85,0x05);                 //set DAY         Sun=0,Mon=1
  116.         //DS1302SingleWrite(0x86,0x14);                 //set YEAR
  117.     // DS1302SingleWriteRAM(0x00,0x21);        //set Alarm1 Hour
  118.     // DS1302SingleWriteRAM(0x01,0x15);        //set Alarm1 Minute
  119.    //DS1302SingleWriteRAM(0x02,0x18);        //set Alarm2 Hour
  120.    //DS1302SingleWriteRAM(0x03,0x15);        //set Alarm2 Minute

  121.    while(1)
  122.    {
  123.          display();
  124.          if (fen==0&miao<3)
  125.          bell(4,1,8,1);
  126.          //if (DS1302SingleReadRAM(0x00) == ((shi/10)*16+shi%10)
  127.         //                        &DS1302SingleReadRAM(0x01) == ((fen/10)*16+fen%10))
  128.                           
  129.         //                                {bell(4,1,8,1);}
  130.                                
  131.         //if (DS1302SingleReadRAM(0x02) == ((shi/10)*16+shi%10)
  132.         //                        &DS1302SingleReadRAM(0x03) == ((fen/10)*16+fen%10))               
  133.         //                        {bell(4,1,8,1); }
  134.                        
  135.    }
  136. }

  137. //外部中断0         IR Remote

  138. void IR_IN() interrupt 0 //using 0
  139. {
  140.   unsigned char j,k,N=0;
  141.   P0=0x00;
  142.         //char bx;
  143.      EX0 = 0;                     //关掉外部中断防止中断的再次发生进入检测引导码阶段(9ms的低电平4.5ms的高电平)
  144.          delayIR(15);
  145.          if (IRIN==1)
  146.      { EX0 =1;                          //9ms的检测检测结束从新打开外部中断
  147.            return;
  148.           }
  149.                            //确认IR信号出现
  150.   while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。
  151.     {delayIR(1);}

  152. for (j=0;j<4;j++)         //收集四组数据
  153. {
  154.           for (k=0;k<8;k++)        //每组数据有8位
  155.           {
  156.                    while (IRIN)            //等 IR 变为低电平,跳过4.5ms的引导高电平信号。
  157.                      {delayIR(1);}
  158.                     while (!IRIN)          //等 IR 变为高电平
  159.                      {delayIR(1);}
  160.                      while (IRIN)           //计算IR高电平时长(0和1的低电平的时长一样的,只要判断高电平时长超过0.56ms并小于1.12ms为1否则为0)
  161.                       {
  162.                             delayIR(1);
  163.                             N++;           
  164.                                 if (N>=30)
  165.                                          {
  166.                                                  EX0=1;
  167.                                                  return;
  168.                                          }                  //0.14ms计数过长自动离开。
  169.                       }                        //高电平计数完毕               
  170.                      IRCOM[j]=IRCOM[j] >> 1;                  //数据最高位补“0”
  171.                      if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}  //高电平持续时间大于1.12ms则数据最高位补“1”
  172.                      N=0;
  173.           }                                                                //end for k
  174. }                                                                        //end for j
  175.    
  176.    if (IRCOM[2]!=~IRCOM[3])                  // 判断有没有误码(有责放弃没有判断键码)
  177.    { EX0=1;
  178.      return;
  179.    }
  180.         beep();
  181.         DS1302SingleWrite(0x8e,0x00);                                //allow write to DS1302
  182.              switch(IRCOM[2])
  183.                  {                        
  184.                         case 0x40: if (fen>0) {fen--;} else{fen=59;} DS1302SingleWrite(0x81,((fen/10)*16+fen%10));  break;//minute-1,write to ds1302
  185.                         case 0x43: fen++;          if (fen>=60) {fen=0;}   DS1302SingleWrite(0x81,((fen/10)*16+fen%10));  break;//minute+1
  186.                         case 0x15: if (shi>0) {shi--;} else{shi=23;} DS1302SingleWrite(0x82,((shi/10)*16+shi%10));  break;//hour-1
  187.                         case 0x09: shi++;    if (shi>=24) {shi=0;}   DS1302SingleWrite(0x82,((shi/10)*16+shi%10));  break;//hour+1
  188.                         case 0x47: miao=0;                                                                        DS1302SingleWrite(0x80,0x00);                    break;//second=0
  189.                         case 0x44:
  190.                        
  191.                                 display_date();        //display year,month,date
  192.                                 break;
  193.                         case 0x45:
  194.                                 display_temp();
  195.                 }
  196.          DS1302SingleWrite(0x8e,0x80);                        // protect write to DS1302
  197.          EX0 = 1;
  198. }


  199. void display()
  200. {
  201.      unsigned char i;
  202.          tabe2[7]=tabe1[miao%10];
  203.          tabe2[6]=tabe1[miao/10];
  204.          tabe2[5]=0x40;
  205.          tabe2[4]=tabe1[fen%10];
  206.          tabe2[3]=tabe1[fen/10];
  207.          tabe2[2]=0x40;
  208.          tabe2[1]=tabe1[shi%10];
  209.          tabe2[0]=tabe1[shi/10];
  210.         for(i=0;i<8;i++)
  211.           {
  212.                      switch(i)                                            
  213.                      {
  214.                           case 0:LS138A=0; LS138B=0; LS138C=0;  break;         
  215.                   case 1:LS138A=1; LS138B=0; LS138C=0;  break;                    
  216.                   case 2:LS138A=0; LS138B=1; LS138C=0;  break;
  217.                   case 3:LS138A=1; LS138B=1; LS138C=0;  break;
  218.                           case 4:LS138A=0; LS138B=0; LS138C=1;  break;
  219.                           case 5:LS138A=1; LS138B=0; LS138C=1;  break;
  220.                           case 6:LS138A=0; LS138B=1; LS138C=1;  break;
  221.                           case 7:LS138A=1; LS138B=1; LS138C=1;  break;            
  222.                                                         
  223.                                   }
  224.                          P0=tabe2[i];
  225.                          delay(5);
  226.           }
  227. }

  228. /* every second timer update second,minute,hour 2 times.*/
  229. void timer0(void) interrupt 1
  230. {
  231.          

  232.      TH0=0x3c,TL0=0xb0;
  233.          t0++;
  234.          //display();
  235.            if(t0==10)
  236.               {
  237.                        
  238.                         t0= 0;
  239.                         Read_RTC();
  240.                        
  241.                   }  
  242. }



  243. void display_date(void)
  244. {
  245.         unsigned char i;
  246.         miao=DS1302SingleRead(0x83); miao=(miao>>4)*10+(miao&0x0f);
  247.         fen= DS1302SingleRead(0x84); fen=(fen>>4)*10+(fen&0x0f);
  248.         shi= DS1302SingleRead(0x86); shi=(shi>>4)*10+(shi&0x0f);
  249.         for (i=1;i<255;i++)
  250.         display();
  251.        
  252. }

  253. void display_temp(void)                          
  254. {
  255.         unsigned char n;
  256.         P0=0x00;
  257.         miao = 0;
  258.         fen = ReadTemperature();
  259.         shi = 0;
  260.         AT24C02_Write1Byte(AT24C02Address,fen);
  261.         AT24C02Address++;
  262.         for (n=1;n<255;n++)
  263.         display();
  264. }


  265. void ButtonPress() interrupt 2 //using INT1
  266. {
  267.        
  268.         display_temp();
  269. }
复制代码

所有资料51hei提供下载:
红外遥控器调节时间的数码管时钟.zip (34.97 KB, 下载次数: 64)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:744410 发表于 2020-5-5 14:10 | 只看该作者
大佬,你的那个红外遥控器控制的数码管时钟里面,数码管下面的RN1在proteus中的名称是什么
回复

使用道具 举报

板凳
ID:808676 发表于 2020-11-30 05:24 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

地板
ID:315554 发表于 2020-12-2 16:21 | 只看该作者
学习了,其它代码很多都不成功,特别是遥控部份,键码都改不对,;谢谢分享
回复

使用道具 举报

5#
ID:853394 发表于 2020-12-2 21:48 | 只看该作者
写的很好,小白看着好厉害
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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