红外线接受程序 理解

  1 /**************************************************************************************
  2 *                      红外通信实验                                                  *
  3 实现现象:下载程序后,数码管显示红外遥控键值数据
  4 注意事项:    红外遥控器内的电池绝缘片一定要抽掉      
  5 通过该函数可以控制很多东西,因为每个按键都有一个固定的16定制的编码,故而通过if语句来进行判断这个
  6 键是否按下,当按下的时候,就可以执行相应的动作                                                                          
  7 ***************************************************************************************/
  8 
  9 #include "reg52.h"             //此文件中定义了单片机的一些特殊功能寄存器
 10     
 11 
 12 typedef unsigned int u16;      //对数据类型进行声明定义
 13 typedef unsigned char u8;
 14 
 15 sbit LSA=P2^2;
 16 sbit LSB=P2^3;
 17 sbit LSC=P2^4;
 18 
 19 sbit IRIN=P3^2;
 20 
 21 u8 IrValue[6];
 22 u8 Time;
 23 
 24 u8 DisplayData[8];
 25 u8 code smgduan[17]={
 26 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
 27 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X76};
 28 //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、H的显示码
 29 
 30 /*******************************************************************************
 31 * 函 数 名         : delay
 32 * 函数功能           : 延时函数,i=1时,大约延时10us
 33 *******************************************************************************/
 34 void delay(u16 i)
 35 {
 36     while(i--);    
 37 }
 38 
 39 
 40 /*******************************************************************************
 41 * 函数名         :DigDisplay()
 42 * 函数功能         :数码管显示函数
 43 * 输入           : 无
 44 * 输出              : 无
 45 *******************************************************************************/
 46 void DigDisplay()
 47 {
 48     u8 i;
 49     for(i=0;i<3;i++)
 50     {
 51         switch(i)     //位选,选择点亮的数码管,
 52         {
 53             case(0):
 54                 LSA=0;LSB=0;LSC=0; break;//显示第0位
 55             case(1):
 56                 LSA=1;LSB=0;LSC=0; break;//显示第1位
 57             case(2):
 58                 LSA=0;LSB=1;LSC=0; break;//显示第2位    
 59         }
 60         P0=DisplayData[2-i];//发送数据
 61         delay(100); //间隔一段时间扫描    
 62         P0=0x00;//消隐
 63     }        
 64 }
 65 
 66 
 67 /*******************************************************************************
 68 * 函数名         : IrInit()
 69 * 函数功能           : 初始化红外线接收
 70 * 输入           : 无
 71 * 输出              : 无
 72 *******************************************************************************/
 73 
 74 void IrInit()
 75 {
 76     IT0=1;//下降沿触发   由于P3^2的引脚刚好连的是单片机的外部中断0 ,故而通过外部中断0来判断起始码9ms和4.5ms
 77     EX0=1;//打开中断0允许
 78     EA=1;    //打开总中断
 79 
 80     IRIN=1;//初始化端口  红外接收端的引脚
 81 }
 82 
 83 
 84 /*******************************************************************************
 85 * 函 数 名       : main
 86 * 函数功能         : 主函数
 87 * 输    入       : 无
 88 * 输    出         : 无
 89 *******************************************************************************/
 90 void main()
 91 {    
 92     IrInit();
 93     while(1)
 94     {    
 95         DisplayData[0] = smgduan[IrValue[2]/16];//得到16位数的高位
 96         DisplayData[1] = smgduan[IrValue[2]%16];//得到16位数的低位
 97         DisplayData[2] = smgduan[16];//数码管前面定义的16为字母 H
 98         DigDisplay();        
 99     }        
100 }
101 
102 /*******************************************************************************
103 * 函数名         : ReadIr()
104 * 函数功能           : 读取红外数值的中断函数
105 * 输入           : 无
106 * 输出              : 无
107 *******************************************************************************/
108 
109 void ReadIr() interrupt 0
110 {
111     u8 j,k;
112     u16 err;
113     Time=0;                     
114     delay(700);    //7ms
115     if(IRIN==0)        //确认是否真的接收到正确的信号
116     {     
117         
118         err=1000;                //1000*10us=10ms,超过说明接收到错误的信号
119         /*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
120         侯,程序死在这里*/    
121         while((IRIN==0)&&(err>0))    //等待前面9ms的低电平过去          
122         {            
123             delay(1);
124             err--;
125         } 
126         if(IRIN==1)            //如果正确等到9ms低电平
127         {
128             err=500;
129             while((IRIN==1)&&(err>0))         //等待4.5ms的起始高电平过去
130             {
131                 delay(1);
132                 err--;
133             }
134             for(k=0;k<4;k++)        //共有4组数据
135             {                
136                 for(j=0;j<8;j++)    //接收一组数据
137                 {
138 
139                     err=60;        
140                     while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
141                     {
142                         delay(1);
143                         err--;
144                     }
145                     err=500;
146                     while((IRIN==1)&&(err>0))     //计算高电平的时间长度。
147                     {
148                         delay(10);     //0.1ms
149                         Time++;
150                         err--;
151                         if(Time>30)
152                         {
153                             return;
154                         }
155                     }
156                     IrValue[k]>>=1;     //k表示第几组数据  将四组字节放入其中
157                     if(Time>=8)            //如果高电平出现大于565us,那么是1    如果Time =8的时候,表示时间为0.1mS*8=0.8ms
158                     {
159                         IrValue[k]|=0x80; /*当时间大于565us的时候,为位1     这里相当于读取(因为已经通过时间确定了位0还是位1相当于写入了)
160                         这个数据 ,因为是读,故而才将IrValue[k]>>=1;放在IrValue[k]|=0x80;的上面
161                         将其先放在高位,之后通过上面的IrValue[k]>>=1;
162                         这个语句将其移到下一位 ,这样就可以将其8位依次由低位移到高位  */
163                     }
164                     Time=0;        //用完时间要重新赋值    当用Time确定完之后,就要重新赋0,一边下一次使用                         
165                 }
166             }
167         }
168         if(IrValue[2]!=~IrValue[3]) //用于判断收到的数据是否正确 ,如果不正确,强行退出
169         {
170             return;
171         }
172     }            
173 }
View Code

猜你喜欢

转载自www.cnblogs.com/wises/p/9557572.html