久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

一個紅外線發射+解碼程序+仿真文件

作者:佚名   來源:本站原創   點擊數:  更新時間:2012年09月12日   【字體:

 可定義任意I/O作接收腳,支持長/短按,自適應主頻6MHz~40

 

//*********************【 NEC解碼頭文件 】*******************
//
//     簡介:本程序適用于NCE解碼:(9ms+4.5ms)引導碼+32位編碼。
//           兼容STC所有型號(包括 1T 和 12T 系列),可以定義任意I/O作紅外接收腳,
//                         自適應解碼主頻:6MHz ~ 40MHz。
// 
// 使用條件:占用系統定時器0,開啟定時器0中斷(如使用其它定時器請自改IR_Init();初始化函數)
// 
// 使用說明:填相關宏定義:USER_H、USER_L、Check_EN、CPU_Fosc、IR,
//           上電初始化函數IR_Init(),
//           在定時器0中斷中調用IR_NEC()解碼函數,
//           解碼有效時,IR_BT=2即短按,IR_BT=3即長按,由用戶清0,
//           解碼存放:用戶碼高8位NEC[0],用戶碼低8位NEC[1],操作碼NEC[2],操作碼反碼NEC[3]。
//
//【供用戶調用的函數】
//    IR_Init();                         //接收初始化,開啟定時器0中斷400us
//    IR_NEC();                             //紅外線解碼(解NEC編碼)
//          
//***************************************************************/ 
#ifndef __IR_NEC_H__
#define __IR_NEC_H__


//【用戶必填項:USER_H、USER_L、Check_EN、CPU_Fosc、IR】
#define  USER_H     0x80         //用戶碼高8位
#define  USER_L     0x7F         //用戶碼低8位
#define  Check_EN   0                    //是否要校驗16位用戶碼:不校驗填0,校驗則填1        
#define  CPU_Fosc   12000000L    //輸入主頻,自適應解碼(單位:Hz,范圍:6MHz ~ 40MHz)
#define  CA_S       8                    //長按時間設置,單位:108mS(即 108mS整數倍,10倍以上為宜)

sbit IR = P3^6;                  //紅外線接口(任意引腳) 

#define  Step       400          //紅外采樣步長:400us
#define  TH_H      ((65536-Step*(CPU_Fosc/300)/40000)/256)  //定時器高8位基準賦值
#define  TH_L      ((65536-Step*(CPU_Fosc/300)/40000)%256)  //定時器低8位基準賦值

uint8   IR_BT;     //解碼效果返回:0無效,1有效,2短按,3長按
uint8   NEC[4];    //解碼存放:16位用戶碼、操作碼正反碼
uint8   cntCA;     //長按計數
uint16  cntStep;   //步數計
bit     IRa,IRb;   //接收腳電位狀態保存
bit     IRsync;    //同步標志
uint8   BitN;      //位碼裝載數


/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數:紅外線解碼初始化
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void IR_Init()
{
   TMOD &= 0xF0;           //清定時器0
   TMOD |= 0x01;           //定時器0:16位定時器
   TL0 = TH_L;           //每步時間
   TH0 = TH_H;
   ET0 = 1;
   EA  = 1;
   TR0 = 1;
}

/*┈┈┈┈┈┈┈┈┈┈ 基準 ┈┈┈┈┈┈┈┈┈┈┈*/
#define    Boot_Limit    ((9000+4500 +1000)/Step)   //引導碼周期上限    
#define    Boot_Lower    ((9000+4500 -1000)/Step)   //引導碼周期下限    
#define    Bit1_Limit    ((2250 +800)/Step)         //“1”周期上限
#define    Bit0_Limit    ((1125 +400)/Step)         //“0”周期上限
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數:紅外線NEC周期采樣解碼法(定時中斷,下降沿查詢周期時間)
全局變量:IR_BT = 0無效
                  1有效,待繼續判斷長、短按(如不需要判斷長、短按,則直接使用)
                  2短按
                  3長按
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void IR_NEC()
{          
   TL0 = TH_L;   //重賦值
   TH0 = TH_H;        

   cntStep++;    //步數累加
   if(IR_BT==1)if(cntStep>300)IR_BT=2; //解碼有效后,如果無長按,120ms(400us×300)后默認短按

   IRb = IRa;    //保存上次電位狀態
   IRa = IR;     //保存當前電位狀態
        
   if(IRb && !IRa)    //是否下降沿(上次高,當前低)
   {
      if(cntStep > Boot_Limit)   //超過同步時間?
      {        
          if(IR_BT==1)if(++cntCA>CA_S)IR_BT=3; //解碼有效后,繼續按住遙控>CA_S即長按
          IRsync=0;                            //同步位清0
      }
      else if(cntStep > Boot_Lower){ IRsync=1; BitN=32; }   //同步位置1,裝載位碼數32                          
      else if(IRsync)            //如果已同步
      {
         if(cntStep > Bit1_Limit)IRsync=0;                   
         else
         {        
            NEC[3] >>= 1;                                
            if(cntStep > Bit0_Limit)NEC[3] |= 0x80;    //“0”與“1”
            if(--BitN == 0)                                
            {
               IRsync = 0;    //同步位清0

               #if (Check_EN == 1)                                        
               if((NEC[0]==USER_H)&&(NEC[1]==USER_L)&&(NEC[2]==~NEC[3]))    //校驗16位用戶碼、操作碼正反碼
               {  IR_BT=1; cntCA=0;  }     //解碼有效,接下來判斷:短按?長按?
               #else
               if(NEC[2]==~NEC[3]){ IR_BT=1; cntCA=0; }  //只校驗操作碼正反碼
               #endif                                        
            }
            else if((BitN & 0x07)== 0)    //NEC[3]每裝滿8位,移動保存一次(即 BitN%8 == 0)
            {   NEC[0]=NEC[1]; NEC[1]=NEC[2]; NEC[2]=NEC[3];   }
         }
      }
      cntStep = 0;   //步數計清0
   }
} 

//取消相關宏定義
#undef CPU_Fosc 

#endif





主程序
#include "INC\STC89C52RC.H"
#include "INC\MY_SET.H"
#include "INC\IR_NEC.H"        //調用NEC解碼頭文件

sfr   SE   = 0x80;             //數碼管段選 P0:0x80   P1:0x90 
sbit  WX1  = P2^0;                 //數碼管位顯
sbit  WX2  = P2^1;
sbit  WX3  = P2^2;
sbit  WX4  = P2^3;
sbit  WX5  = P2^4;
sbit  WX6  = P2^5;
sbit  WX7  = P2^6;
sbit  WX8  = P2^7;

uint8c tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0X88,0X83,0XC6,0XA1,0X86,0X8E,0xFF};
uint8  Xn,X1,X2,X3,X4,X5,X6;

void KZ0();      //短按處理
void KZ1();      //長按處理


/***************** 主函數 ********************/
void main(void)
{
   IR_Init();                           //紅外線解碼初始化
                                                   
   while(1)
   { 
      //遙控檢測
      if((IR_BT==2)||(IR_BT==3))                          
      {
         if(IR_BT==2)KZ0();      //短按處理                  
         else        KZ1();      //長按處理        
         IR_BT =0;               //清有效標志

         X1 = NEC[0]/16;              //更新顯示
         X2 = NEC[0]%16;
         X3 = NEC[1]/16;
         X4 = NEC[1]%16;
         X5 = NEC[2]/16;
         X6 = NEC[2]%16; 
      }
          
   }

}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數:遙控短按處理
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void KZ0()
{
   switch(NEC[2])             
   {
          case 0x12: P10 = !P10; break;
          case 0x05: break;
          case 0x1E: break;
          case 0x55: break;

          case 0x01: break;
          case 0x1B: break;
          case 0x03: break;
          case 0x6B: break;

          case 0x07: break;
          case 0x08: break;
          case 0x09: break;
          case 0x68: break;

          case 0x22: break;
          case 0xE6: break;
          case 0x33: break;
          case 0xE2: break;
          default:break;
   }
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數:遙控長按處理
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void KZ1()
{
   switch(NEC[2])             
   {
          case 0x12: P14 = !P14; break;
          case 0x05: break;
          case 0x1E: break;
          case 0x55: break;

          case 0x01: break;
          case 0x1B: break;
          case 0x03: break;
          case 0x6B: break;

          case 0x07: break;
          case 0x08: break;
          case 0x09: break;
          case 0x68: break;

          case 0x22: break;
          case 0xE6: break;
          case 0x33: break;
          case 0xE2: break;
          default:break;
   }
}
/*********************數碼管掃描*************************/
void XS(void)
{ 
  if(++Xn > 7)Xn=0;
  switch(Xn)             
  {
            case 0: WX8=1;  NOP;           //屏蔽上個位顯
                    SE=tab[X1];           //送段碼
                    WX1=0;           //開位顯
                    break;
            case 1: WX1=1; NOP; SE=tab[X2]; WX2=0; break;
            case 2: WX2=1; NOP; SE=tab[X3]; WX3=0; break;        
         case 3: WX3=1; NOP; SE=tab[X4]; WX4=0; break;
         case 4: WX4=1; NOP; SE=tab[16]; WX5=0; break;
         case 5: WX5=1; NOP; SE=tab[16]; WX6=0; break;
         case 6: WX6=1; NOP; SE=tab[X5]; WX7=0; break;
         case 7: WX7=1; NOP; SE=tab[X6]; WX8=0; break;                 
         default:break;                         
  }
} 

/********************** 定時器0中斷函數************************/
void time0(void) interrupt 1
{ 
   IR_NEC(); 
   XS();         
}
 

接收源程序+仿真
點擊此處下載 http://www.zg4o1577.cn/f/hong1.rar

遙控器源程序
點擊此處下載 http://www.zg4o1577.cn/f/hong2.rar

/***************************************************************
    作品:紅外線遙控發射(NEC編碼)
  單片機:STC89C52RC
    晶振:12M
***************************************************************/
//
// 發射引腳(接PNP三極管b極)
// PNP三極管e極接2Ω電阻,c極接紅外發射管
     
#include <REG51.h>
#include "INC\MY_SET.h"
#include "INC\LCD1602_6IO.h"  

sbit  IR  = P3^6;                  //發射引腳(接PNP三極管基極)

#define  USER_H   P2              //用戶碼高8位
#define  USER_L   P0              //用戶碼低8位
uint8c tab[16] = {                  //操作碼
0x12,0x05,0x1e,0x55,
0x01,0x1b,0x03,0x6b,
0x07,0x08,0x09,0x68,
0x22,0xE6,0x33,0xe2};

#define m9    (65536-9000)           //9mS
#define m4_5  (65536-4500)           //4.5mS
#define m1_6  (65536-1650)           //1.65mS
#define m_56  (65536-560)           //0.56mS
#define m40   (65536-40000)       //40mS
#define m56   (65536-56000)       //56mS
#define m2_25 (65536-2250)        //2.25mS

void  SanZhuan();
uint8 KEY(void);
void  ZZ(uint8 x);                  //NEC編碼發送程序
void  Z0(uint8 temp);                  //單幀(8位數據)發送程序
void  TT0(bit BT,uint16 x);          //38KHz載波發射 + 延時程序



/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數:主程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void main(void)
{ 
  TMOD = 0x01;         //T0 16位工作方式
  IR=1;                  //發射端口常態為高電平
  L1602_Init(); 
  L1602_clr();
  L1602_xy(0,0);
  L1602_ZIFUC("UserCode :0x"); 
  L1602_xy(0,1);
  L1602_ZIFUC("Opcode   :0x");

  while(1) 
  {           
   L1602_xy(12,0);
   L1602_JZ(USER_H,16,1);
   L1602_JZ(USER_L,16,1);
   SanZhuan();
  }
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數:4×4矩陣鍵盤
                      【 線翻轉法鍵值表 】                    
P1.0  P1.1  P1.2  P1.3  P1.4  P1.5  P1.6  P1.7 
│     │    │    │    │    │    │    │    
│     │    │    └──7e    be    de   ee      
│     │    └─────7d    bd    dd   ed      
│     └────────7b    bb    db   eb      
└─────────── 77    b7    d7   e7    
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
uint8 KEY(void)
{
  uint8 Key = 0;

  P1 = 0xf0;           //鍵盤初始:行值=0,列值=1
  NOP;                 //緩沖,待IO端口電位穩定
  Key = P1&0xf0;       //得到行標志

  P1  = 0x0f;          //翻轉鍵盤接口輸出
  NOP;
  Key |= (P1&0x0f);    //列標志 + 行標志

  return Key;          //返回鍵值
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數:散轉程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void SanZhuan()
{
uint8 v;
v = KEY();                           //鍵盤檢測
switch(v)
{
  case 0x7e:ZZ(tab[0]);break;                
  case 0xbe:ZZ(tab[1]);break;                
  case 0xde:ZZ(tab[2]);break;                
  case 0xee:ZZ(tab[3]);break;                
  case 0x7d:ZZ(tab[4]);break;                
  case 0xbd:ZZ(tab[5]);break;                
  case 0xdd:ZZ(tab[6]);break;                
  case 0xed:ZZ(tab[7]);break;
  case 0x7b:ZZ(tab[8]);break;                
  case 0xbb:ZZ(tab[9]);break;                
  case 0xdb:ZZ(tab[10]);break;                
  case 0xeb:ZZ(tab[11]);break;
  case 0x77:ZZ(tab[12]);break;                
  case 0xb7:ZZ(tab[13]);break;                
  case 0xd7:ZZ(tab[14]);break;                
  case 0xe7:ZZ(tab[15]);break;                                
  default:break;
}
v=0;
}

/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數:NEC編碼發送程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void ZZ(uint8 Value)
{ 
  L1602_xy(12,1);
  L1602_JZ(Value,16,1);    //更新顯示
  
  TT0(1,m9);             //高電平9mS
  TT0(0,m4_5);             //低電平4.5mS

  /*┈ 發送4幀數據┈*/
  Z0(USER_H);             //用戶碼高8位
  Z0(USER_L);             //用戶碼低8位
  Z0(Value);             //操作碼
  Z0(~Value);             //操作碼反碼

  /*┈┈ 結束碼 ┈┈*/
  TT0(1,m_56);
  TT0(0,m40);

  /*┈┈ 重復碼 ┈┈*/
  while(KEY() != 0xFF)
   {
        TT0(1,m9);
        TT0(0,m2_25);

        TT0(1,m_56);
        TT0(0,m40);
        TT0(0,m56);                                  
    }                   
}

/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數:單幀(8位數據)發送程序
入口:temp
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Z0(uint8 temp)
{ 
  uint8 v;
  for(v=0;v<8;v++)  
  {     
      TT0(1,m_56);                  //高電平0.65mS         
      if(temp&0x01) TT0(0,m1_6);  //發送最低位
      else          TT0(0,m_56);     
      temp >>= 1;                 //右移一位 
  }    
}

/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數:38KHz載波發射 + 延時程序
入口:(是否發射載波,延時約 x (uS))
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void TT0(bit BT,uint16 x)
{
  TH0 = x>>8;                  //輸入定時值
  TL0 = x;
  TF0=0;                        //溢出標志位清0
  TR0=1;                        //啟動定時器0
  if(BT == 0) while(!TF0);        //BT=0時,不發射38KHz載波只延時;
  else while(1)                //BT=1時,發射38KHz脈沖+延時;38KHz載波(低電平)占空比5:26
       {
              IR = 0;
              if(TF0)break;if(TF0)break;
              IR = 1;
                if(TF0)break;if(TF0)break;
                 if(TF0)break;if(TF0)break;
                 if(TF0)break;if(TF0)break;
                 if(TF0)break;if(TF0)break;
                 if(TF0)break;if(TF0)break;
       }
  TR0=0;          //關閉定時器0
  IR =1;          //載波停止后,發射端口常態為高
}

 

關閉窗口

相關文章

主站蜘蛛池模板: 免费观看一级特黄欧美大片 | 国产91久久久久久久免费 | www.国产精品 | 亚洲www | 婷婷色在线播放 | 欧美精品一区二区三区一线天视频 | 日韩av成人在线 | 欧美一区二区三区日韩 | 日本欧美国产 | 嫩草最新网址 | 播放一级毛片 | 欧美三级三级三级爽爽爽 | 欧美高清hd | 欧美 日韩 国产 成人 | 欧美a在线看 | 久久亚洲天堂 | 最新中文字幕久久 | 色必久久| 日韩在线国产 | 激情网站 | 国产视频二区 | 毛片在线看看 | 一级网站 | 99久久精品国产一区二区三区 | 久久久久久99 | 精品国产一区二区三区四区在线 | 国产极品车模吞精高潮呻吟 | www操操 | 亚洲欧美激情精品一区二区 | 国产乱码精品一区二区三区中文 | www.久久| 欧美一区二区视频 | 日本理论片好看理论片 | 亚洲免费精品 | 国产精品视频观看 | 久久久蜜臀国产一区二区 | 亚洲精品免费在线 | 欧美久久一区二区三区 | 久久国产欧美日韩精品 | 欧美精品一区二区三区在线 | 日韩三区 |