IRLCD.C
上传用户:taysgs
上传日期:2021-07-28
资源大小:53k
文件大小:7k
源码类别:

单片机开发

开发平台:

HTML/CSS

  1. /********************************************************************************
  2. *  描述:                                                                       *
  3. *          lcd1602显示 遥控键值读取器                                          *
  4. *         lcd1602显示 遥控器接p3.2                                             *
  5. *          喇叭接p1.5  继电器接p1.4                                            *
  6. *         17(40h)键按下,继电器吸合。19(04h)键按下,继电器关闭。               *
  7. *       连接方法:使用红外功能时 J1跳线短接                                                                          *
  8. ********************************************************************************/
  9. #include <reg51.h>
  10. #include <intrins.h>
  11. #define uchar unsigned char
  12. #define uint  unsigned int
  13. uchar LCD_ID_1[16] = {"Red Control"};
  14. uchar LCD_ID_2[16] = {"IR CODE:--H"};
  15. void delay(uchar x);  //x*0.14MS
  16. void delay1(int ms);
  17. void beep();
  18. sbit IRIN = P3^3;         //红外接收器数据线
  19. sbit BEEP = P1^5;         //蜂鸣器驱动线
  20. sbit RELAY= P1^4;         //继电器驱动线
  21. uchar IRCOM[7];
  22. sbit E=P2^7; //1602使能引脚
  23. sbit RW=P2^6; //1602读写引脚
  24. sbit RS=P2^5; //1602数据/命令选择引脚
  25. /********************************************************************
  26. * 名称 : delay()
  27. * 功能 : 延时,延时时间大概为140US。
  28. * 输入 : 无
  29. * 输出 : 无
  30. ***********************************************************************/
  31. void Delay2()
  32. {
  33. int i,j;
  34. for(i=0; i<=10; i++)
  35. for(j=0; j<=2; j++)
  36. ;
  37. }
  38. /********************************************************************
  39. * 名称 : Convert(uchar In_Date)
  40. * 功能 : 因为电路设计时,P0.0--P0.7接法刚好了资料中的相反,所以设计该函数。
  41. * 输入 : 1602资料上的值
  42. * 输出 : 送到1602的值
  43. ***********************************************************************/
  44. uchar Convert(uchar In_Date)
  45. {
  46.     uchar i, Out_Date = 0, temp = 0;
  47.     for(i=0; i<8; i++)
  48.     {
  49.         temp = (In_Date >> i) & 0x01;
  50.         Out_Date |= (temp << (7 - i));
  51.     }
  52.     return Out_Date;
  53. }
  54. /********************************************************************
  55. * 名称 : enable(uchar del)
  56. * 功能 : 1602命令函数
  57. * 输入 : 输入的命令值
  58. * 输出 : 无
  59. ***********************************************************************/
  60. void enable(uchar del)
  61. {
  62. P0 = Convert(del);
  63. RS = 0;
  64. RW = 0;
  65. E = 0;
  66. Delay2();
  67. E = 1;
  68. Delay2();
  69. }
  70. /********************************************************************
  71. * 名称 : write(uchar del)
  72. * 功能 : 1602写数据函数
  73. * 输入 : 需要写入1602的数据
  74. * 输出 : 无
  75. ***********************************************************************/
  76. void write(uchar del)
  77. {
  78. P0 = Convert(del);
  79. RS = 1;
  80. RW = 0;
  81. E = 0;
  82. Delay2();
  83. E = 1;
  84. Delay2();
  85. }
  86. /********************************************************************
  87. * 名称 : L1602_init()
  88. * 功能 : 1602初始化,请参考1602的资料
  89. * 输入 : 无
  90. * 输出 : 无
  91. ***********************************************************************/
  92. void L1602_init(void)
  93. {
  94. enable(0x01);
  95. enable(0x38);
  96. enable(0x0c);
  97. enable(0x06);
  98. enable(0xd0);
  99. }
  100. /********************************************************************
  101. * 名称 : L1602_char(uchar hang,uchar lie,char sign)
  102. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
  103.  L1602_char(1,5,'b')
  104. * 输入 : 行,列,需要输入1602的数据
  105. * 输出 : 无
  106. ***********************************************************************/
  107. void L1602_char(uchar hang,uchar lie,char sign)
  108. {
  109. uchar a;
  110. if(hang == 1) a = 0x80;
  111. if(hang == 2) a = 0xc0;
  112. a = a + lie - 1;
  113. enable(a);
  114. write(sign);
  115. }
  116. /********************************************************************
  117. * 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
  118. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
  119.    L1602_string(1,5,"ab cd ef;")
  120. * 输入 : 行,列,需要输入1602的数据
  121. * 输出 : 无
  122. ***********************************************************************/
  123. void L1602_string(uchar hang,uchar lie,uchar *p)
  124. {
  125. uchar a;
  126. if(hang == 1) a = 0x80;
  127. if(hang == 2) a = 0xc0;
  128. a = a + lie - 1;
  129. enable(a);
  130. while(1)
  131. {
  132. if(*p == '') break;
  133. write(*p);
  134. p++;
  135. }
  136. }
  137. /*******************************************************************/
  138. main()
  139. {
  140.  
  141.     IE = 0x84;                 //允许总中断中断,使能 INT1 外部中断
  142.     TCON = 0x10;               //触发方式为脉冲负边沿触发
  143.     
  144.     IRIN=1;                    //I/O口初始化
  145.     BEEP=1;
  146.     RELAY=1; 
  147.     delay1(10);                 //延时
  148.     L1602_init();               //初始化LCD             
  149. L1602_string(1, 1, LCD_ID_1);
  150. L1602_string(2, 1, LCD_ID_2);
  151.    while(1) ;
  152. } //end main
  153. /**********************************************************/
  154. void IR_IN() interrupt 2 using 0
  155. {
  156.   unsigned char j,k,N=0;
  157.      EX1 = 0;   
  158.  delay(15);
  159.  if (IRIN==1) 
  160.      { EX1 =1;
  161.    return;
  162.   } 
  163.                            //确认IR信号出现
  164.   while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。
  165.     {delay(1);}
  166.  for (j=0;j<4;j++)         //收集四组数据
  167.  { 
  168.   for (k=0;k<8;k++)        //每组数据有8位
  169.   {
  170.    while (IRIN)            //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
  171.      {delay(1);}
  172.     while (!IRIN)          //等 IR 变为高电平
  173.      {delay(1);}
  174.      while (IRIN)           //计算IR高电平时长
  175.       {
  176.     delay(1);
  177.     N++;           
  178.     if (N>=30)
  179.  { EX1=1;
  180.  return;}                  //0.14ms计数过长自动离开。
  181.       }                        //高电平计数完毕                
  182.      IRCOM[j]=IRCOM[j] >> 1;                  //数据最高位补“0”
  183.      if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}  //数据最高位补“1”
  184.      N=0;
  185.   }//end for k
  186.  }//end for j
  187.    
  188.    if (IRCOM[2]!=~IRCOM[3])
  189.    { EX1=1;
  190.      return; }
  191.    IRCOM[5]=IRCOM[2] & 0x0F;     //取键码的低四位
  192.    IRCOM[6]=IRCOM[2] >> 4;       //右移4次,高四位变为低四位
  193.    if(IRCOM[5]>9)
  194.     { IRCOM[5]=IRCOM[5]+0x37;}
  195.    else
  196.   IRCOM[5]=IRCOM[5]+0x30;
  197.    if(IRCOM[6]>9)
  198.     { IRCOM[6]=IRCOM[6]+0x37;}
  199.    else
  200.   IRCOM[6]=IRCOM[6]+0x30;
  201. //////////////////////////
  202. L1602_char(2,10,IRCOM[5]);
  203. L1602_char(2,9,IRCOM[6]);
  204.      //beep();
  205.      EX1 = 1; 
  206. /**********************************************************/
  207. void beep()
  208. {
  209.   unsigned char i;
  210.   for (i=0;i<100;i++)
  211.    {
  212.    delay(4);
  213.    BEEP=!BEEP;                 //BEEP取反
  214.    } 
  215.   BEEP=1;                      //关闭蜂鸣器
  216. }
  217. /**********************************************************/
  218. void delay(unsigned char x)    //x*0.14MS
  219. {
  220.  unsigned char i;
  221.   while(x--)
  222.  {
  223.   for (i = 0; i<13; i++) {}
  224.  }
  225. }
  226. /**********************************************************/
  227. void delay1(int ms)
  228. {
  229.  unsigned char y;
  230.   while(ms--)
  231.  {
  232.   for(y = 0; y<250; y++)
  233.   {
  234.    _nop_();
  235.    _nop_();
  236.    _nop_();
  237.    _nop_();
  238.   }
  239.  }
  240. }