• 红外线接受程序 理解


      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
  • 相关阅读:
    可重入锁 RLOCK(转)
    python 全局变量的简单理解
    urlopen设置代理方法
    python is id == 的差别,cmp方法
    FutureTask
    Java基础复习
    计算机编程底层基础
    Microsoft.NET框架程序设计20 CLR寄宿、应用程序域、反射
    Microsoft.NET框架程序设计19 自动内存管理(垃圾收集)
    Microsoft.NET框架程序设计17 委托
  • 原文地址:https://www.cnblogs.com/wises/p/9557572.html
Copyright © 2020-2023  润新知