• <rp id="wfxtb"><acronym id="wfxtb"></acronym></rp><em id="wfxtb"></em><dd id="wfxtb"><big id="wfxtb"><video id="wfxtb"></video></big></dd>
  • <rp id="wfxtb"></rp>

    <mark id="wfxtb"><center id="wfxtb"></center></mark>

      <rp id="wfxtb"><span id="wfxtb"><u id="wfxtb"></u></span></rp>

      <rp id="wfxtb"><object id="wfxtb"></object></rp>

      注意:訪問本站需要Cookie和JavaScript支持!請設置您的瀏覽器! 打開購物車 查看留言付款方式聯系我們
      初中電子 單片機教材一 單片機教材二
      搜索上次看見的商品或文章:
      商品名、介紹 文章名、內容
      首頁 電子入門 學單片機 免費資源 下載中心 商品列表 象棋在線 在線繪圖 加盟五一 加入收藏 設為首頁
      本站推薦:
      紅外線遙控器解碼原理
      文章長度[] 加入時間[2008/6/17] 更新時間[2025/7/2 9:35:22] 級別[0] [評論] [收藏]
      2007年02月06日 星期二 16:01

      紅外線遙控是目前使用最廣泛的一種通信和遙控手段。由于紅外線遙控裝置具有體積小、功耗低、功能強、成本低等特點,因而,繼彩電、錄像機之后,在錄音機、音響設備、空凋機以及玩具等其它小型電器裝置上也紛紛采用紅外線遙控。工業設備中,在高壓、輻射、有毒氣體、粉塵等環境下,采用紅外線遙控不僅完全可靠而且能有效地隔離電氣干擾。

      1 紅外遙控系統

      通用紅外遙控系統由發射和接收兩大部分組成,應用編/解碼專用集成電路芯片來進行控制操作,如圖1所示。發射部分包括鍵盤矩陣、編碼調制、LED紅外發送器;接收部分包括光、電轉換放大器、解調、解碼電路。


      2 遙控發射器及其編碼

      遙控發射器專用芯片很多,根據編碼格式可以分成兩大類,這里我們以運用比較廣泛,解碼比較容易的一類來加以說明,現以日本NEC的uPD6121G組成發射電路為例說明編碼原理。當發射器按鍵按下后,即有遙控碼發出,所按的鍵不同遙控編碼也不同。這種遙控碼具有以下特征:

      采用脈寬調制的串行碼,以脈寬為0.565ms、間隔0.56ms、周期為1.125ms的組合表示二進制的“0”;以脈寬為0.565ms、間隔1.685ms、周期為2.25ms的組合表示二進制的“1”,其波形如圖2所示。


      上述“0”和“1”組成的32位二進制碼經38kHz的載頻進行二次調制以提高發射效率,達到降低電源功耗的目的。然后再通過紅外發射二極管產生紅外線向空間發射,如圖3所示。


      UPD6121G產生的遙控編碼是連續的32位二進制碼組,其中前16位為用戶識別碼,能區別不同的電器設備,防止不同機種遙控碼互相干擾。該芯片的用戶識別碼固定為十六進制01H;后16位為8位操作碼(功能碼)及其反碼。UPD6121G最多額128種不同組合的編碼。

      遙控器在按鍵按下后,周期性地發出同一種32位二進制碼,周期約為108ms。一組碼本身的持續時間隨它包含的二進制“0”和“1”的個數不同而不同,大約在45~63ms之間,圖4為發射波形圖。

      當一個鍵按下超過36ms,振蕩器使芯片激活,將發射一組108ms的編碼脈沖,這108ms發射代碼由一個起始碼(9ms),一個結果碼(4.5ms),低8位地址碼(9ms~18ms),高8位地址碼(9ms~18ms),8位數據碼(9ms~18ms)和這8位數據的反碼(9ms~18ms)組成。如果鍵按下超過108ms仍未松開,接下來發射的代碼(連發代碼)將僅由起始碼(9ms)和結束碼(2.5ms)組成。

      代碼格式(以接收代碼為準,接收代碼與發射代碼反向)
      ①位定義 

       
                 
      ②單發代碼格式 

              
      ③連發代碼格式 

      注:代碼寬度算法:

      16位地址碼的最短寬度:1.12×16=18ms 16位地址碼的最長寬度:2.24ms×16=36ms 

      易知8位數據代碼及其8位反代碼的寬度和不變:(1.12ms+2.24ms)×8=27ms

      ∴32位代碼的寬度為(18ms+27ms)~(36ms+27ms)

      1. 解碼的關鍵是如何識別“0”和“1”,從位的定義我們可以發現“0”、“1”均以0.56ms的低電平開始,不同的是高電平的寬度不同,“0”為0.56ms,“1”為1.68ms,所以必須根據高電平的寬度區別“0”和“1”。如果從0.56ms低電平過后,開始延時,0.56ms以后,若讀到的電平為低,說明該位為“0”,反之則為“1”,為了可靠起見,延時必須比0.56ms長些,但又不能超過1.12ms,否則如果該位為“0”,讀到的已是下一位的高電平,因此。1.12ms+0.56ms)/2=0.84ms最為可靠,一般取0.84ms左右均可。

      2. 根據碼的格式,應該等待9ms的起始碼和4.5ms的結果碼完成后才能讀碼。

       

      如果郵購我們開發的51單片機試驗板和擴展元件的網友,可以獲得如上圖所示的紅外遙控手柄,這種遙控器的編碼格式符合上面的描述規律,而且價格低廉,有32個按鍵,按鍵外形比較統一,如果用于批量開發,可以把遙控器上貼膜換成你需要的字符,這為開發產品提供了便利。

      接收器及解碼

      一體化紅外線接收器是一種集紅外線接收和放大于一體,不需要任何外接元件,就能完成從紅外線接收到輸出與TTL電平信號兼容的所有工作,而體積和普通的塑封三極管大小一樣,它適合于各種紅外線遙控和紅外線數據傳輸。

      下面是一個對51實驗板配套的紅外線遙控器的解碼程序,它可以把上圖32鍵的紅外遙控器每一個按鍵的鍵值讀出來,并且通過實驗板上P1口的8個LED顯示出來,在解碼成功的同時并且能發出“嘀嘀嘀”的提示音。
      紅外遙控器軟件解碼原理及程序 
                  
      紅外一開始發送一段13.5ms的引導碼,引導碼由9ms的高電平和4.5ms的低電平組成,跟著引導碼是系統碼,系統反碼,按鍵碼,按鍵反碼,如果按著鍵不放,則遙控器則發送一段重復碼,重復碼由9ms的高電平,2.25ms的低電平,跟著是一個短脈沖,本程序經過試用,能解大部分遙控器的編碼!

      #include "at89x52.h"
      #define NULL 0x00//數據無效
      #define RESET 0X01//程序復位
      #define REQUEST 0X02//請求信號
      #define ACK 0x03//應答信號,在接收數據后發送ACK信號表示數據接收正確,也位請求信號的應答信號
      #define NACK 0x04//應答信號,表示接收數據錯誤
      #define BUSY 0x05//忙信號,表示正在忙
      #define FREE 0x06//空閑信號,表示處于空閑狀態
      #define READ_IR 0x0b//讀取紅外
      #define STORE_IR 0x0c//保存數據
      #define READ_KEY 0x0d//讀取鍵值
      #define RECEIVE 0Xf400//接收緩沖開始地址
      #define SEND 0xfa00//發送緩沖開始地址
      #define IR 0x50//紅外接收緩沖開始地址
      #define HEAD 0xaa//數據幀頭
      #define TAIL 0x55//數據幀尾
      #define SDA P1_7
      #define SCL P1_6



      unsigned char xdata *buf1; //接受數據緩沖
      unsigned int buf1_length; //接收到的數據實際長度
      unsigned char xdata *buf2; //發送數據緩沖
      unsigned int buf2_length; //要發送的數據實際長度
      bit buf1_flag; //接收標志,1表示接受到一個數據幀,0表示沒有接受到數據幀或數據幀為空
      bit buf2_flag; //發送標志,1表示需要發送或沒發送完畢,0表示沒有要發送的數據或發送完畢
      unsigned char state1,state2; //用來標志接收字符的狀態,state1用來表示接收狀態,state2用來表示發送狀態
      unsigned char data *ir;
      union{
      unsigned char a[2];
      unsigned int b;
      unsigned char data *p1[2];
      unsigned int data *p2[2];
      unsigned char xdata *p3; //紅外緩沖的指針
      unsigned int xdata *p4;
      }p;
      //union{ //
      // unsigned char a[2]; //
      // unsigned int b;
      // unsigned char data *p1[2];
      // unsigned int data *p2[2];
      // unsigned char xdata *p3;
      // unsigned int xdata *p4; //地址指針
      //}q; //

      union{
      unsigned char a[2];
      unsigned int b;
      }count;
      union{
      unsigned char a[2];
      unsigned int b;
      }temp;
      union{
      unsigned char a[4];
      unsigned int b[2];
      unsigned long c;
      }ir_code;

      union{
      unsigned char a[4];
      unsigned int b[2];
      unsigned long c;
      unsigned char data *p1[4];
      unsigned int data *p2[4];
      unsigned char xdata *p3[2];
      unsigned int xdata *p4[2];
      }i;
      unsigned char ir_key;
      bit ir_flag; //紅外接收標志,0為緩沖區空,1為接收成功,2為緩沖溢出
      void sub(void);
      void delay(void);
      void ie_0(void);
      void tf_0(void);
      void ie_1(void);
      void tf_1(void);
      void tf_2(void);
      void read_ir(void);
      void ir_jiema(void);
      void ir_init(void);
      void ir_exit(void);
      void store_ir(void);
      void read_key(void);
      void reset_iic(void);
      unsigned char read_byte_ack_iic(void);
      unsigned char read_byte_nack_iic(void);
      bit write_byte_iic(unsigned char a);
      void send_ack_iic(void);
      void send_nack_iic(void);
      bit receive_ack_iic(void);
      void start_iic(void);
      void stop_iic(void);
      void write_key_data(unsigned char a);
      unsigned int read_key_data(unsigned char a);
      void ie0(void) interrupt 0{ie_0();}
      void tf0(void) interrupt 1{tf_0();}
      void ie1(void) interrupt 2{ie_1();}
      void tf1(void) interrupt 3{tf_1();tf_2();}
      void tf2(void) interrupt 5{ //采用中斷方式跟查詢方式相結合的辦法解碼
      EA=0; //禁止中斷
      if(TF2){ //判斷是否是溢出還是電平變化產生的中斷
      TF2=0; //如果是溢出產生的中斷則清除溢出位,重新開放中斷退出
      EA=1;
      goto end;
      }
      EXF2=0; //清除電平變化產生的中斷位
      *ir=RCAP2H; //把捕捉的數保存起來
      ir++;
      *ir=RCAP2L;
      *ir++;
      F0=1;
      TR0=1; //開啟計數器0
      loop:
      TL0=0; //將計數器0重新置為零
      TH0=0;
      while(!EXF2){ //查詢等待EXF2變為1
      if(TF0)goto exit; //檢查有沒超時,如果超時則退出
      };
      EXF2=0; //將EXF2清零
      if(!TH0) //判斷是否是長低電平脈沖過來了
      { //不是長低電平脈沖而是短低電平
      if(F0)count.b++; //短脈沖數加一
      temp.a[0]=RCAP2H; //將捕捉數臨時存放起來
      temp.a[1]=RCAP2L;
      goto loop; //返回繼續查詢
      }
      else{ //是低電平脈沖,則進行處理

      F0=0;
      *ir=temp.a[0]; //把連續的短脈沖總時間記錄下來
      ir++;
      *ir=temp.a[1];
      ir++;
      *ir=RCAP2H; //把長電平脈沖時間記錄下來
      ir++;
      *ir=RCAP2L;
      ir++;
      if(ir>=0xda) {
      goto exit; //判斷是否溢出緩沖,如果溢出則失敗退出
      }
      goto loop; //返回繼續查詢
      }
      exit:
      ir_flag=1; //置ir_flag為1表示接收成功
      end:
      ;
      }


      void rs232(void) interrupt 4{
      static unsigned char sbuf1,sbuf2,rsbuf1,rsbuf2; //sbuf1,sbuf2用來接收發送臨時用,rsbuf1,rsbuf2用來分別用來存放接收發送的半字節
      EA=0; //禁止中斷
      if(RI){
      RI=0; //清除接收中斷標志位
      sbuf1=SBUF; //將接收緩沖的字符復制到sbuf1
      if(sbuf1==HEAD){ //判斷是否幀開頭
      state1=10; //是則把state賦值為10
      buf1=RECEIVE; //初始化接收地址 
      }
      else{
      switch(state1){
      case 10:sbuf2=sbuf1>>4; //把高半字節右移到的半字節
      sbuf2=~sbuf2; //把低半字節取反
      if((sbuf2&0x0f)!=(sbuf1&0x0f)) //判斷接收是否正確
      { //接收錯誤,有可能接收的是數據幀尾,也有可能是接收錯誤
      if(sbuf1==TAIL) //判斷是否接收到數據幀尾
      { //是接收到數據幀尾
      buf1=RECEIVE; //初始化接收的地址
      if(*buf1==RESET) //判斷是否為復位命令
      {
      ES=0;
      sbuf2=SP+1;
      for(p.p1[0]=SP-0x10;p.p1[0]<=sbuf2;p.p1[0]++)*p.p1[0]=0;
      }
      state1=0; //將接收狀態標志置為零,接收下一個數據幀
      buf1_flag=1; //置接收標志為1,表示已經接收到一個數據幀
      REN=0; //禁止接收
      }
      else
      { //不是接受到數據幀尾,表明接收錯誤
      state1=0; // 將接收狀態標志置為零,重新接收
      buf1=RECEIVE; //初始化發送的地址
      *buf1=NACK; //把NACK信號存入接收緩沖里
      buf1_flag=1; //置標志位為1,使主程序能對接收錯誤進行處理
      REN=0; //禁止接收
      }

      }
      else
      { //接收正確
      rsbuf1=~sbuf1; //按位取反,使高半字節變原碼
      rsbuf1&=0xf0; //僅保留高半字節,低半字節去掉
      state1=20; //將狀態標志置為20,準備接收低半字節
      }
      break;
      case 20:sbuf2=sbuf1>>4; //把高半字節右移到的半字節
      sbuf2=~sbuf2; //將低半字節取反
      if((sbuf2&0x0f)!=(sbuf1&0x0f)) //判斷接收是否正確
      { //接受錯誤
      state1=0; // 將接收狀態標志置為零,重新接收
      buf1=RECEIVE; //初始化接收的地址
      *buf1=NACK; //把NACK信號存入發送緩沖里
      buf1_flag=1; //置標志位為1,使主程序能對接收錯誤進行處理
      REN=0; //禁止接收
      }
      else
      {
      sbuf1&=0x0f; //僅保留低半字節,去掉高半字節
      rsbuf1|=sbuf1; //高低半字節合并
      *buf1++=rsbuf1; //將接收的數據保存至接收緩沖里,并且數據指針加一
      buf1_length++; //接收數據長度加一
      state1=10; //將state1置為10,準備接收下個字節的高半字節
      }
      break;

      }
      }



      }
      else{

      TI=0; //清除發送中斷標志
      if(buf2_length) //判斷發送長度是否為零
      { //發送長度不為零
      if(state2==0) //判斷是否發送高半字節
      { //發送高半字節
      sbuf2=*buf2; //將要發送的字節送到sbuf2
      rsbuf2=~sbuf2; //取反,使高半字節變為反碼
      sbuf2>>=4; //將高半字節右移到低半字節
      rsbuf2&=0xf0; //保留高半字節,去掉低半字節
      sbuf2&=0x0f; //保留低半字節,去掉高半字節
      rsbuf2|=sbuf2; //合并高低半字節
      SBUF=rsbuf2; //發送出去
      state2=10; //將state2置為10準備發送下半字節
      }
      else
      { //發送低半字節
      sbuf2=*buf2; //將要發送的字節送到sbuf2
      buf2++; //指針加一
      buf2_length--; //發送數據長度減一
      rsbuf2=~sbuf2; //取反,使低半字節變為反碼
      rsbuf2<<=4; //將低半字節反碼左移到高半字節
      rsbuf2&=0xf0; //保留高半字節,去掉低半字節
      sbuf2&=0x0f; //保留低半字節,去掉高半字節
      rsbuf2|=sbuf2; //合并高低半字節
      SBUF=rsbuf2; //發送出
      state2=0;
      }
      }
      else
      { //如果發送數據長度為零則發送數據幀尾
      if(buf2_flag){ //判斷是否發過數據幀尾
      SBUF=TAIL; //將數據幀尾發送出去
      while(TI==0);
      TI=0;
      buf2_flag=0; //置發送標志為零,表示發送完畢
      }
      }
      }
      EA=1; //開放中斷
      }






      void ack(void) //發送ACK信號子程序
      {
      buf1_flag=0; //置接收標志位位零表示已經相應了,可以接收下一幀數據
      REN=1; //接收使能
      while(buf2_flag); //判斷上一幀有沒發送完,沒有則繼續等待
      buf2=SEND; //初始化發送地址
      *buf2=ACK; //將ACK信號存入發送緩沖里
      buf2_length=1; //存入發送數據長度
      buf2_flag=1; //置發送長度為1
      SBUF=HEAD; //發送數據幀頭
      }

      void nack(void) //發送NACK信號子程序
      {
      buf1_flag=0; //置接收標志位位零表示已經相應了,可以接收下一幀數據
      REN=1; //接收使能
      while(buf2_flag); //判斷上一幀有沒發送完,沒有則繼續等待
      buf2=SEND; //初始化發送地址
      *buf2=NACK; //將NACK信號存入發送緩沖里
      buf2_length=1; //存入發送數據長度
      buf2_flag=1; //置發送長度為1
      SBUF=HEAD; //發送數據幀頭
      }

      void free(void) //發送FREE信號子程序
      {
      buf1_flag=0; //置接收標志位位零表示已經相應了,可以接收下一幀數據
      REN=1; //接收使能
      while(buf2_flag); //判斷上一幀有沒發送完,沒有則繼續等待
      buf2=SEND; //初始化發送地址
      *buf2=FREE; //將FREE信號存入發送緩沖里
      buf2_length=1; //存入發送數據長度
      buf2_flag=1; //置發送長度為1
      SBUF=HEAD; //發送數據幀頭
      }

      void busy(void) //發送BUSY信號子程序
      {
      buf1_flag=0; //置接收標志位位零表示已經相應了,可以接收下一幀數據
      REN=1; //接收使能
      while(buf2_flag); //判斷上一幀有沒發送完,沒有則繼續等待
      buf2=SEND; //初始化發送地址
      *buf2=BUSY; //將BUSY信號存入發送緩沖里
      buf2_length=1; //存入發送數據長度
      buf2_flag=1; //置發送長度為1
      SBUF=HEAD; //發送數據幀頭
      }

      void download(void)
      {
      int i; //用于循環計數
      i=buf1_length-3; //數據長度等于數據包長度減去一個字節控制字和兩個字節地址
      buf1=RECEIVE+1; //使指針指向地址
      p.a[0]=*buf1++; //讀入目標地址高字節
      p.a[1]=*buf1++; //讀入目標地址低字節
      while(i--){ //長度減一直至為零
      *p.p3++=*buf1++; //將接受緩沖里數據送到目標地址,并且兩個指針加一
      }
      REN=1; //數據處理完,允許接收下一幀數據
      buf1_flag=0; //置接收標志為零,表示已經處理完
      free(); //發送FREE信號表示已經處理完處于空閑狀態

      }

      void upload(void){
      int i; //
      while(buf2_flag); //判斷上一幀有沒發送完,沒有則繼續等待
      buf1=RECEIVE+1; //將指針指向地址
      buf2=SEND; //初始化發送地址
      *buf2++=UPLOAD; //把控制字存進去并且指針加一
      *buf2++=*buf1++; //把地址高字節復制過去
      *buf2++=*buf1++; //把地址低字節復制過去
      p.a[0]=*buf1++; //把數據長度高字節復制過去
      p.a[1]=*buf1++; //把數據長度低字節復制過去
      i=p.b; //把數據長度復制過去
      buf1-=4; //將指針減4,使其指向地址處
      p.a[0]=*buf1++; //把地址高字節復制過去
      p.a[1]=*buf1++; //把地址低字節復制過去
      buf1_flag=0; //已經對接受數據處理完畢
      REN=1; //允許接收
      buf2_length=i+3; //數據包長度等于數據長度加3
      while(i--){ //判斷數據長度是否為零,為零則不執行循環語句,同時長度減一
      *buf2++=*p.p3++; //把數據復制到發送緩沖區
      }
      buf2=SEND;
      buf2_flag=1; //置發送標志為1
      SBUF=HEAD; //發送數據幀頭
      }

      void run(void) //運行下載的程序
      {
      sub();
      }



      void delay1s(void){
      for(i.b[0]=0;i.b[0]<0xffff;i.b[0]++){
      i.b[0]=i.b[0]++;
      i.b[0]=i.b[0]--;}
      }

      void ir_init(void)
      {
      ir_flag=0; //將紅外接收標志置為零
      for(ir=IR;ir<0xe0;ir++){
      *ir=0; //將紅外接收緩沖清零
      }
      EA=0; //禁止中斷
      ES=0; //禁止串行中斷
      ET2=1; //允許T2中斷
      ir=IR; //初始化紅外數據指針
      TR0=0; //禁止計數
      TH0=0; //將計數器置為0
      TL0=0;
      TF0=0; //清除溢出標志
      count.b=1; //初始化為零


      init:
      TR2=0;
      TL2=0x00;
      TH2=0xdc; //給T2賦一個初值,當計數器溢出時正好為6毫秒
      T2CON=0x0d; //EXEN2=1,TR2=1,C/T2=0,CP/RL2=1,工作于捕捉方式
      while(!TF2); //查詢計數器是否溢出
      TF2=0; //清除溢出位
      if(EXF2) //判斷在此期間又沒發生過電平變化
      { //如果發生過變化則重新計數
      goto init; //等待下一次按鍵
      }
      else
      { //計數器溢出并且電平沒有發生過變化,則開啟中斷開始解碼
      EA=1;
      }

      }

      void ir_exit(void) //紅外接收恢復程序,恢復到紅外接收前的狀態
      {
      TR2=0; //停止計數以便修改計數器2寄存器
      TR0=0;
      ET2=0; //禁止計數器2中斷
      TL2=0xfb; //重新設置波特率為115.2kbps
      TH2=0xff;
      RCAP2H=0xff;
      RCAP2L=0xfb;
      T2CON=0x34;
      ES=1; //允許串行中斷
      EA=1; //開放全局中斷
      }


      void ir_jiema(void){ //解碼程序,放在ir_code中,高十六位表示接收頻率
      //如果解碼失敗則為,如果是重復碼則為1
      //低八位表示載波頻率,以KHz為單位
      //低十六位的高八位表示系統碼,低八位為按鍵碼
      p.p2[0]=IR;
      p.p2[1]=p.p2[0]+1;
      i.b[0]=*p.p2[0];
      i.b[1]=*p.p2[1];
      for(;i.b[1]!=0{
      if(i.b[0]>i.b[1]){
      i.b[0]=0xffff-i.b[0];
      i.b[0]+=i.b[1];
      i.b[0]++;
      }
      else{
      i.b[0]=i.b[1]-i.b[0];
      }
      *p.p2[0]=i.b[0];
      p.p2[0]++;
      i.b[0]=*p.p2[0];
      p.p2[1]++;
      i.b[1]=*p.p2[1];
      }
      *p.p2[0]=0;
      p.p2[0]=IR;
      temp.b=*p.p2[0];
      ir_code.c=count.b;
      ir_code.b[0]=(ir_code.c*1536000)/temp.b;
      for(;temp.b!=0{
      *p.p2[0]=temp.b/154;
      p.p2[0]++;
      temp.b=*p.p2[0];
      }
      ir_code.b[1]=0;
      if(p.p2[0]==IR+132){
      p.p2[0]=IR;
      p.p2[0]+=3;
      i.c=0;
      temp.b=*p.p2[0];
      for(;temp.b!=0{
      i.c<<=1;
      if(temp.b>=11){
      i.a[3]++;
      }
      p.p2[0]+=2;
      temp.b=*p.p2[0];
      }
      if(i.a[0]==(~i.a[1])&&i.a[2]==(~i.a[3])){
      ir_code.a[2]=i.a[0];
      ir_code.a[3]=i.a[2];
      }
      else ir_code.b[0]=0;
      }
      else{
      if(p.p2[0]==IR+4){
      p.p2[0]=IR;
      p.p2[0]++;
      temp.b=*p.p2[0];
      if(temp.b<=30){
      ir_code.b[0]=1;
      }
      else ir_code.b[0]=0;
      }
      else ir_code.b[0]=2;
      }
      //if(ir_flag==2)ir_code.b[0]=3;
      }

      void read_ir(void){
      buf1_flag=0;
      REN=1;
      buf2_length=4;
      while(buf2_flag);
      ir_init();
      while(!ir_flag);
      ir_exit();
      ir_jiema();
      buf2=SEND;
      *buf2++=ir_code.a[0];
      *buf2++=ir_code.a[1];
      *buf2++=ir_code.a[2];
      *buf2=ir_code.a[3];
      buf2=SEND;
      buf2_flag=1;
      SBUF=HEAD;
      }
      void delay(void){}

      void start_iic(void){
      SCL=0;
      SDA=1;
      delay();
      delay();
      SCL=1;
      delay();
      SDA=0;
      delay();
      SCL=0;
      delay();
      }
      void stop_iic(void){
      SDA=0;
      delay();
      SCL=1;
      delay();
      SDA=1;
      delay();
      SCL=0;
      delay();
      delay();
      SCL=1;
      delay();
      }

      void send_ack_iic(void){
      SDA=0;
      delay();
      SCL=1;
      delay();
      delay();
      SCL=0;
      delay();
      }

      void send_nack_iic(void){
      SDA=1;
      delay();
      SCL=1;
      delay();
      delay();
      SCL=0;
      delay();
      }

      bit receive_ack_iic(void){
      bit a;
      SDA=1;
      delay();
      SCL=1;
      delay();
      if(SDA) a=1;
      else a=0;
      delay();
      SCL=0;
      delay();
      return a;
      }

      unsigned char read_byte_ack_iic(void){
      unsigned char a;
      SDA=1;
      for(p.a[0]=0;p.a[0]<8;p.a[0]++){
      a<<=1;
      delay();
      SCL=1;
      delay();
      if(SDA) a++;
      delay();
      SCL=0;
      delay();
      }
      send_ack_iic();
      return a;
      }

      unsigned char read_byte_nack_iic(void){
      unsigned char a;
      SDA=1;
      for(p.a[0]=0;p.a[0]<8;p.a[0]++){
      a<<=1;
      delay();
      SCL=1;
      delay();
      if(SDA) a++;
      delay();
      SCL=0;
      delay();
      }
      send_nack_iic();
      return a;
      }



      void reset_iic(void){
      SDA=1;
      for(p.a[0]=0;p.a[0]<10;p.a[0]++){
      SCL=0;
      delay();
      delay();
      SCL=1;
      delay();
      delay();
      }
      }

      bit write_byte_iic(unsigned char a){
      for(p.a[0]=0;p.a[0]<8;p.a[0]++){
      if(a&0x80){
      SDA=1;
      }
      else{
      SDA=0;
      }
      delay();
      SCL=1;
      delay();
      delay();
      SCL=0;
      delay();
      a<<=1;
      }
      return receive_ack_iic();
      }

      unsigned int read_key_data(unsigned char a){
      union{
      unsigned char a[2];
      unsigned int b;
      }key_data;
      reset_iic();
      start_iic();
      write_byte_iic(0xa0);
      write_byte_iic(a);
      start_iic();
      write_byte_iic(0xa1);
      key_data.a[0]=read_byte_ack_iic();
      key_data.a[1]=read_byte_nack_iic();
      stop_iic();
      return key_data.b;
      }

      void write_key_data(unsigned char a){
      reset_iic();
      start_iic();
      write_byte_iic(0xa0);
      write_byte_iic(a);
      write_byte_iic(ir_code.a[2]);
      write_byte_iic(ir_code.a[3]);
      stop_iic();
      }

      void store_ir(void){
      buf1_flag=0;
      REN=1;
      buf1=RECEIVE+1;
      *buf1=(*buf1)<<1;
      write_key_data(*buf1);
      }

      unsigned char yima(void){
      unsigned char a;
      for(a=0;a<100{
      if(ir_code.b[1]==read_key_data(a)){

      break;
      }
      a++;
      a++;
      }
      a>>=1;
      return a;
      }

      void read_key(){
      unsigned char a;
      buf1_flag=0;
      REN=1;
      ir_init();
      while(!ir_flag);
      ir_exit();
      ir_jiema();
      buf2=SEND;
      a=yima();
      if(a==50){
      *buf2=0xff;
      }
      else *buf2=a;
      buf2_length=1;
      buf2_flag=1;
      SBUF=HEAD;
      }










      main(){
      unsigned char ctr;
      delay1s();
      P0=0xff;
      P1=0xff;
      P2=0xff;
      P3=0xff;
      ctr=0;
      buf1=RECEIVE;
      buf2=SEND;
      buf1_length=0;
      buf2_length=0;
      buf1_flag=0;
      buf2_flag=0;
      state1=0;
      state2=0;
      SP=0xe0; //將堆棧指針指向高端
      TL2=0xfb;
      TH2=0xff; //溢出值為5,波特率為115.2Kbps;
      RCAP2H=0xff;
      RCAP2L=0xfb;
      SCON=0x50; //方式1,8位方式,SM0=0,SM1=1,SM2=0,REN=1允許接收
      IE=0x10; //串行中斷允許,全局中斷不允許
      T2CON=0x34; //RCLK=1,TCLK=1,TR2=1 啟動計數器
      EA=1; //開放全局中斷
      free();



      while(1){
      //ir_init();
      //while(!ir_flag);
      //ir_exit();
      //ir_jiema();
      //if(yima()==0) P1_0=1;
      //if(yima()==1) P1_0=0;


      if(buf1_flag){
      buf1=RECEIVE;
      ctr=*buf1;

      switch(ctr){
      case ACK: ack();
      break;
      case NACK: nack();
      break;
      case FREE: free();
      break;
      case BUSY: busy();
      break;
      case DOWNLOAD: download();
      break;
      case UPLOAD: upload();
      break;
      case RUN: run();
      break;
      case READ_IR: read_ir();
      break;
      case READ_KEY: read_key();
      break;
      case STORE_IR: store_ir();
      break;
      default: buf1_flag=0;
      REN=1;
      break;
      }
      }


      }

      }


      void sub(void){
      }

      void ie_0(void){
      }

      void tf_0(void){
      }

      void ie_1(void){
      }

      void tf_1(void){
      }

      void tf_2(void){
      }

      1、 本站不保證以上觀點正確,就算是本站原創作品,本站也不保證內容正確。
      2、如果您擁有本文版權,并且不想在本站轉載,請書面通知本站立即刪除并且向您公開道歉! 以上可能是本站收集或者轉載的文章,本站可能沒有文章中的元件或產品,如果您需要類似的商品請 點這里查看商品列表!
      本站協議。 版權信息。 關于我們。 本站地圖。 營業執照。 發票說明。 付款方式。 聯系方式
      深圳市寶安區西鄉五壹電子商行——粵ICP備16073394號-1;地址:深圳西鄉河西四坊183號;郵編:518102
      E-mail:51dz$163.com($改為@);Tel:(0755)27947428
      工作時間:9:30-12:00和13:30-17:30和18:30-20:30,無人接聽時可以再打手機13537585389
      91嫩草黄片动漫版