找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5480|回复: 5
收起左侧

红外控制时钟(遥控器51单片机程序)

[复制链接]
ID:76127 发表于 2015-4-18 03:59 | 显示全部楼层 |阅读模式
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #include<stdio.h>
  4. #define DataPort P2  //8位数据口(硬件)
  5. #define Busy 0x80
  6. #define LED P0
  7. //#define HLED P3
  8. #define uchar unsigned char
  9. #define uint unsigned int
  10. sbit jia=P1^1;
  11. sbit jian=P1^2;
  12. sbit IR=P3^2;
  13. sbit P1_6=P1^6;
  14. sbit P1_7=P1^7;
  15. sbit jiguang=P1^5;
  16. unsigned char a[4];
  17. unsigned int LowTime,HighTime; //
  18. uchar yaokong;
  19. uchar SecondL = 0;         //时间秒低位
  20. uchar SecondH = 0;         //时间秒高位
  21. uchar MinuteL =2;         //时间分低位
  22. uchar MinuteH =3;         //时间分高
  23. uchar hourh=0;
  24. uchar hourl=7;
  25. bit  kai=0;
  26. uchar yueh=0,yuel=5;
  27. uchar rih=2,ril=8;
  28. uchar xingqi=3;
  29. unsigned char IRCode[4],num, shu;
  30. //uchar ircount;
  31. //uchar irtime[33];
  32. //uchar irdate[33];
  33. //uchar irnum;
  34. //uchar irflag;
  35. //sbit irflag=P3^2;
  36. // irrecOK;
  37. //uchar ircode[4];
  38. //uchar irvalue;
  39. //uchar dsirOK;
  40. //uchar code16H[8];
  41. //uchar irtranOK;   
  42. /*********************************************
  43.                 引脚位定义
  44. **********************************************/
  45. sbit RS=P3^7;  //寄存器选择输入端(硬件)
  46. sbit RW=P3^6;  //读写控制输入端(硬件)
  47. sbit E =P3^5;  //使能信号输入端(硬件)
  48. /*********************************************
  49. 函数名称: delay
  50. 函数功能: 简易延时函数,us级延时
  51. 函数输入: j-延时时间控制变量
  52. 函数输出: 无
  53. **********************************************/
  54. void delay(unsigned int j)
  55. {
  56.   for(j;j>0;j--);
  57. }
  58. /*********************************************
  59. 函数名称: Delay5Ms
  60. 函数功能: 固定延时时间延时函数,延时5ms
  61. 函数输入: 无
  62. 函数输出: 无
  63. **********************************************/

  64. void  DelayA(void)
  65.   {
  66. unsigned int TempCyc;
  67. for (TempCyc=0;
  68. TempCyc<3500; TempCyc++); //3.5ms
  69.   }
  70. void DelayB(void)
  71. {
  72. unsigned int TempCyc;
  73. for (TempCyc=0; TempCyc<840; TempCyc++); // 0.84ms
  74. }


  75. void Delay5Ms(void)
  76. {
  77.   unsigned int TempCyc = 4552;
  78.   while(TempCyc--);
  79. }
  80. /*********************************************
  81. 函数名称: Lcddelay
  82. 函数功能: LCD毫秒级延时函数
  83. 函数输入: MS-延时时间为MS*ms
  84. 函数输出: 无
  85. **********************************************/
  86. void Lcddelay(uint MS)
  87. {
  88.   unsigned char i,j;
  89.   while(MS!=0)
  90.    {
  91.      j = 4;
  92.      while(j!=0)
  93.       {
  94.         i=0xf0;
  95.         while(i!=0){i--;}
  96.         j--;
  97.       }
  98.      MS--;
  99.    }
  100. }
  101. /*********************************************
  102. 函数名称: WaitForEnable
  103. 函数功能: 检测lcd状态。注意有的LCD检测忙时会一直处
  104.            于忙状态,导致程序不能正常工作,这时可以
  105.            讲忙检测屏蔽掉试试。
  106. 函数输入: 无
  107. 函数输出: 无
  108. **********************************************/
  109. void WaitForEnable(void)
  110. {
  111.    DataPort=0xff;
  112.    RS=0;
  113.    RW=1;
  114.    Lcddelay(5);
  115.    _nop_();
  116.    E=1;
  117.    _nop_();
  118.    _nop_();
  119.    while(DataPort&Busy);
  120.    E=0;
  121. }

  122. /*********************************************
  123. 函数名称: LcdWriteCommand
  124. 函数功能: 向LCD写命令
  125. 函数输入: CMD-LCD命令
  126.            AttribC-忙检测使能变量
  127. 函数输出: 无
  128. **********************************************/
  129. void LcdWriteCommand(unsigned char CMD)
  130. {
  131.    RS=0;
  132.    RW=0;
  133.    _nop_();
  134.    DataPort=CMD;
  135.    Lcddelay(5);
  136.    _nop_();
  137.    E=1;
  138.    _nop_();
  139.    _nop_();
  140.    E=0;
  141. }
  142. /*********************************************
  143. 函数名称: LocateXY
  144. 函数功能: 确定LCD的坐标
  145. 函数输入: polx-LCD横坐标
  146.            poly-LCD纵坐标
  147. 函数输出: 无
  148. **********************************************/
  149. void LocateXY(char polx,char poly)
  150. {
  151.    unsigned char temp;
  152.    temp=polx&0xf;
  153.    poly&=0x01;
  154.    if(poly) temp|=0x40;
  155.    temp|=0x80;
  156.    LcdWriteCommand(temp);
  157. }
  158. /*********************************************
  159. 函数名称: LcdWriteData
  160. 函数功能: 向LCD写数据
  161. 函数输入: DataW-LCD数据
  162. 函数输出: 无
  163. **********************************************/
  164. void LcdWriteData(char DataW)
  165. {
  166.    RS=1;
  167.    RW=0;
  168.    _nop_();
  169.    DataPort=DataW;
  170.    Lcddelay(5);
  171.    _nop_();
  172.    E=1;
  173.    _nop_();
  174.    _nop_();
  175.    E=0;
  176. }
  177. /*********************************************
  178. 函数名称: DispOneChar
  179. 函数功能: 在指定位置显示单个字符
  180. 函数输入: x-横坐标
  181.            y-纵坐标
  182.            Wlata-字符数据(单个)
  183. 函数输出: 无
  184. **********************************************/
  185. void DispOneChar(unsigned char x,unsigned char y,unsigned char WData)
  186. {
  187.    LocateXY(x,y);
  188.    LcdWriteData(WData);
  189. }
  190. /*********************************************
  191. 函数名称: LcdReset
  192. 函数功能: LCD1602初始化
  193. 函数输入: 无
  194. 函数输出: 无
  195. **********************************************/
  196. void LcdReset(void)
  197. {
  198.    LcdWriteCommand(0x38);
  199.    Lcddelay(5);
  200.    LcdWriteCommand(0x38);
  201.    Lcddelay(5);
  202.    LcdWriteCommand(0x38);
  203.    Lcddelay(5);
  204.    LcdWriteCommand(0x38);// 清屏
  205.    LcdWriteCommand(0x08);
  206.    LcdWriteCommand(0x01);
  207.    LcdWriteCommand(0x06);
  208.    LcdWriteCommand(0x0c);
  209. }
  210. /*********************************************
  211. 函数名称: DisplayListChar
  212. 函数功能: 在指定位置显示字符串
  213. 函数输入: x-横坐标
  214.            y-纵坐标
  215.            *Dlata-字符串数据指针
  216. 函数输出: 无
  217. **********************************************/
  218. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *SData,unsigned char L)
  219. {
  220.    unsigned char i;
  221.    for(i=0;i<L;i++)
  222.    DispOneChar(X++,Y,SData[i]);
  223. }
  224. void Init_Timer(void)
  225. {
  226.    TMOD = 0x11;             //设定T1的工作模式为1,设定T0工作模式1
  227.    //----装入定时器初值 -----//
  228.    TH0 = 0x95;              //100us定时
  229.    TL0 = 0x95;
  230.    TH1 = (65536-50000)/256; //50ms定时            
  231.    TL1 = (65536-50000)%256;
  232.    IT0 = 1;
  233.    IP  = 0x03;
  234.    EA  = 1;                 // 开总中断
  235.    ET0 = 1;                 // 定时器0允许中断
  236.    ET1 = 1;                 // 定时器1允许中断
  237.    TR1 = 1;                 // 启动定时器1
  238.    TR0 = 1;                 // 启动定时器0
  239. }
  240. void Timer1_ISR() interrupt 3      
  241. {
  242. uint cnt;
  243. TH1 = (65536-50000)/256;            
  244. TL1 = (65536-50000)%256;
  245. cnt++;
  246. if(cnt >=20)
  247. {
  248.     cnt = 0;
  249.     ++SecondL;
  250.     if(SecondL == 10)
  251.     {
  252.     SecondL = 0;
  253.     ++SecondH;
  254.     if(SecondH == 6)
  255.     {
  256.     SecondH = 0;
  257.     ++MinuteL;
  258.     if(MinuteL == 10)
  259.     {
  260.     MinuteL = 0;
  261.     ++MinuteH;
  262.     if(MinuteH==6)
  263.     {MinuteH=0;
  264.     ++hourl;
  265.     if(hourl==10)
  266.     { hourl=0;
  267.     ++hourh;
  268.     if((hourh==2)&(hourl=4))
  269.     {hourh=0;hourl=0;
  270.     ++ril;++xingqi;if(xingqi==8) xingqi=1;
  271.     if(ril==10)
  272.     {ril=0;++rih;
  273.     if((rih==3)&ril==1)
  274.     {
  275.     rih=1;ril=1;
  276.     ++yuel;if(yuel==10)
  277.     {yuel=0;++yueh;
  278.     if((yueh==1)&(yuel==3)){ yuel=1;yueh=1; }
  279.     }
  280.      }
  281.     }
  282.     }   
  283.     }
  284.      }
  285.     }
  286.     }
  287.      }
  288.      }
  289.    }
  290. /*void ComOutChar(unsigned char OutData)
  291. {
  292. SBUF = OutData; //输出字符
  293. while(!TI); //空语句判断字符是否发完
  294. TI = 0; //清TI
  295. }
  296. void INT0Fun(void) interrupt 0 using 2
  297. {
  298. //unsigned char IRCode[2], IROK;
  299. unsigned int TempCyc,  TempCycA;  EX0 = 0; //外部中断0关闭
  300.   IROK = 0;
  301. DelayA(); //延时等待引导码的前半部结束
  302.   DelayA();
  303. if (!P3_2)  //检验前半部是否过早结束,防干扰  
  304. {
  305.   
  306.     {
  307.      DelayA();
  308.      if (P3_2)  //检验前半部是否过早结束,防干扰 ,检验是否是正确的输入信号   
  309.     {
  310.        for (TempCyc=0; TempCyc<3500; TempCyc++)        
  311.     if (!P3_2) break; //等待第一个位,      
  312.     if (TempCyc<3500) //超时检验
  313.      for (TempCycA=0; TempCycA<4; TempCycA++)
  314.         {
  315.          for (TempCyc=0; TempCyc<8; TempCyc++)      
  316.       {
  317.            while(!P3_2); //等待P3_2拉高,开始位的下部分
  318.            DelayB(); //这里没设超时,实际应用在多功能的设计时应设超时         
  319.       IRCode[TempCycA] = IRCode[TempCycA]>>1;         
  320.      if (P3_2) //当延时750us后P3_2仍为高则当前位为1        
  321.        {
  322.              IRCode[TempCycA] = IRCode[TempCycA] | 0x80;      
  323.     // for (TempCycB=0; TempCycB<840; TempCycB++)              
  324.     // if (!P3_2) break; //等待下个位 当位1时高电平为1.5ms,            
  325.     // if (TempCycB>840) //之前已延时了750us, 所以超时应大于1.5ms-750us
  326.              //;  // goto endchk; //这里最大为1ms
  327.             }
  328.    else   IRCode[TempCycA] = IRCode[TempCycA]&0x00;
  329.           }
  330.         }
  331.       // else       // goto endchk;
  332.       }
  333.     // else      // goto endchk;
  334.     // IROK++; //当自定码和数据码都完成时为2
  335.   LcdWriteCommand(0x01);
  336. LcdWriteCommand(0x0c);
  337. if(IRCode[2]=IRCode[3])
  338.    DispOneChar(0,1,IRCode[2]+0x30);
  339.     }

  340. }  */
  341. /*endchk:  if (IROK==2)
  342. {
  343.    ComOutChar(IRCode[0]);
  344.    ComOutChar(IRCode[1]); //连接PC串口查看自定义码和数据码

  345.    if (IRCode[1]==0x10) //1号键  //只演示点亮2只LED,读者可以自行扩展控制别的器件   
  346.     P1_7 = ~P1_7;    if (IRCode[1]==0x11) //2号键
  347.     P1_6 = ~P1_6;    for (TempCyc=0; TempCyc<300; TempCyc++)
  348.     DelayA(); //延时
  349.      
  350. }         
  351. EX0 = 1;
  352.    
  353. }        */
  354. void busy()
  355. {
  356. LcdWriteCommand(0x01);  
  357. LcdWriteCommand(0x0c);  
  358. DisplayListChar(0,0,"STC89c52Rc",10);
  359. DisplayListChar(0,1,"hongwai yaokong",15);
  360. LcdWriteCommand(0x01);
  361. LcdWriteCommand(0x0c);
  362. }
  363. void hled()
  364. {char i, j;
  365. LcdWriteCommand(0x01);
  366. LcdWriteCommand(0x0c);
  367. DisplayListChar(0,0,"JIGUANFDENG$laba",16);
  368. DisplayListChar(0,1,"note:p1.5kou",12);
  369. for(j=30;j>0;j--)
  370. for(i=30;i>0;i--)
  371. {jiguang=0;
  372. delay(500);
  373. jiguang=1;
  374. delay(500); }
  375. }
  376. void led()
  377. {char i,j;
  378. LcdWriteCommand(0x01);
  379. LcdWriteCommand(0x0c);
  380. DisplayListChar(0,0,"liushuideng mode ",16);
  381. DisplayListChar(0,1,"da dang jia zuo",15);
  382. for(j=30;j>0;j--)
  383. for(i=0;i<8;i++)
  384. {LED=~(1<<i);
  385. delay(500); }
  386. }
  387. void time()
  388. { uchar i; ET1=1;TR1=1;
  389.           LcdWriteCommand(0x01);
  390.      LcdWriteCommand(0x0c);
  391.          DisplayListChar(0,0,"Time",4);  
  392.                   DispOneChar(9,0,':');
  393.                   DispOneChar(6,0,':');
  394.              DispOneChar(4,0,hourh+0x30); //显示时间”分“的十位
  395.                DispOneChar(5,0,hourl+0x30); //显示时间”分“的个
  396.       DispOneChar(7,0,MinuteH+0x30); //显示时间”分“的十位
  397.       DispOneChar(8,0,MinuteL+0x30);
  398.       DisplayListChar(0,1,"2014",4);
  399.                   DispOneChar(5,1,yueh+0x30); //显示时间”分“的十位
  400.                DispOneChar(6,1,yuel+0x30); //显示时间”分“的个
  401.       DispOneChar(7,1,'-');
  402.       DispOneChar(8,1,rih+0x30); //显示时间”分“的十位
  403.                DispOneChar(9,1,ril+0x30); //显示时间”分“的个位
  404.                DispOneChar(11,1,xingqi+0x30); //显示时间”秒“的十位
  405.       for(i=255;i>0;i--)
  406.        {
  407.       DispOneChar(8,0,MinuteL+0x30); //显示时间”分“的个位
  408.       DispOneChar(10,0,SecondH+0x30); //显示时间”秒“的十位
  409.                   DispOneChar(11,0,SecondL+0x30); //显示时间”秒“的个位
  410.       }
  411.               //    DispOneChar(12,1,SecondL+0x30); //显示
  412.    // delay(1000);
  413.    }

  414.   bit DeCode(void)
  415. {
  416. unsigned char i,j;
  417. unsigned char temp;
  418. LcdWriteCommand(0x01);
  419. LcdWriteCommand(0x0c);
  420. DisplayListChar(0,0,"start",4);
  421. DispOneChar(4,0,':');
  422. for(i=0;i<4;i++)
  423. {
  424. for(j=0;j<8;j++)
  425. {
  426. temp=temp>>1;
  427. TH0=0;
  428. TL0=0;
  429. TR0=1;
  430. while(IR==0);
  431. TR0=0;
  432. LowTime=TH0*256+TL0;
  433. TH0=0;
  434. TL0=0;
  435. TR0=1;
  436. while(IR==1);
  437. TR0=0;
  438. HighTime=TH0*256+TL0;
  439. if((LowTime<370)||(LowTime>640))
  440. return 0;
  441. if((HighTime>420)&&(HighTime<620))
  442. temp=temp&0x7f;
  443. if((HighTime>1300)&&(HighTime<1800))
  444. temp=temp|0x80;
  445. }
  446. a[i]=temp; }
  447. if(a[2]=~a[3])return 1;
  448. }
  449. void codedisplay()
  450. {uchar i;
  451. i=0;
  452. while(a[i]!="\0")
  453. { i++;
  454. }
  455. }
  456. void yaokong1()
  457. {
  458. LcdWriteCommand(0x0c);
  459. DisplayListChar(0,0,"enter the label",15);
  460. EA=1;
  461. ET1=0;
  462. TR1=0;
  463. ET0=1;
  464. DispOneChar(0,1,a[0]/100+0x30);
  465. DispOneChar(1,1,a[0]%100/10+0x30);
  466. DispOneChar(2,1,a[0]%10+0x30);
  467. while(1);
  468. }
  469.   void key()
  470. {uchar k;
  471. P1=0xff;
  472. k=P1;
  473. if(k==0xff)
  474. return;  
  475. Lcddelay(20);
  476. if(k==0xff)
  477. return;
  478. while(P1!=0xff)
  479. switch(k)
  480. {case 0xf3:LcdWriteCommand(0x01);   break;
  481.   case 0xFF:LcdWriteCommand(0x0c);DisplayListChar(0,0,"open the 1602",13); break;
  482.   case 0xfd:busy();yaokong1();break;
  483.   case 0xfb: hled(); break;
  484.   case 0xf7:time();   break;
  485.   case 0xef:led(); break;
  486. }
  487. }
  488.    void main(void)
  489. {

  490.   shu=0;
  491. LcdReset();         //液晶初始化
  492. Init_Timer();       //Timer0、Timer1初始化
  493.     DisplayListChar(0,0,"name:da dang jia",16);
  494.     DisplayListChar(0,1,"note:20121003920",16);
  495.      yaokong=1;  kai=0;
  496. while(1)
  497. {
  498. key();
  499. }   
  500. }

  501.   void Int0(void) interrupt 0
  502. {EX0=0;
  503. TH0=0;
  504. TL0=0;
  505. TR0=1;
  506. while(IR==0);
  507. TR0=0;
  508. LowTime=TH0*256+TL0;
  509. TH0=0;
  510. TL0=0;
  511. TR0=1;
  512. while(IR==1);
  513. TR0=0;
  514. HighTime=TH0*256+TL0;
  515. if((LowTime>7800)&&(LowTime<8800)&&(HighTime>3600)&&(HighTime<4700))
  516. {
  517. if(DeCode()==1)
  518. {
  519. codedisplay();}}
  520. EX0=1;

  521. }   
复制代码


回复

使用道具 举报

ID:60515 发表于 2015-4-18 05:21 | 显示全部楼层
不知是解码什么型号的遥控,电路图????
回复

使用道具 举报

ID:66287 发表于 2015-6-2 09:02 | 显示全部楼层
支持楼主的分享精神
回复

使用道具 举报

ID:66287 发表于 2015-6-2 09:06 | 显示全部楼层
解码思路清晰,程序写的很不错
回复

使用道具 举报

ID:97497 发表于 2015-11-28 20:55 | 显示全部楼层
木有电路图,,,,,看程序表示理解起来不容易
回复

使用道具 举报

ID:326450 发表于 2018-10-28 18:54 | 显示全部楼层
这个遥控怎么接?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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