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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 15798|回復: 22
打印 上一主題 下一主題
收起左側

[求助]請問做紅外解碼時,如何自動判別32位還是42位???

[復制鏈接]
跳轉到指定樓層
樓主
ID:25357 發表于 2010-8-8 00:02 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
請問做紅外解碼時,如何自動判別32位還是42位???謝謝。
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1 發表于 2010-8-8 08:20 | 只看該作者
42位是什么格式的?什么芯片產生的波形?
回復

使用道具 舉報

板凳
ID:1 發表于 2010-8-8 08:23 | 只看該作者

這個是32位的圖,你把42位的圖發上來我幫你分析自動判別的方法

回復

使用道具 舉報

地板
ID:25357 發表于 2010-8-8 10:12 | 只看該作者



[此貼子已經被作者于2010-8-8 10:15:55編輯過]
回復

使用道具 舉報

5#
ID:25357 發表于 2010-8-8 10:31 | 只看該作者

還有一個網上的波形,好像不太對。


[此貼子已經被作者于2010-8-8 10:31:21編輯過]
回復

使用道具 舉報

6#
ID:25357 發表于 2010-8-8 15:51 | 只看該作者

這個圖前面的引導碼怎么看?


[此貼子已經被作者于2010-8-8 15:52:13編輯過]
回復

使用道具 舉報

7#
ID:1 發表于 2010-8-8 16:51 | 只看該作者

你這個也是32位的,只是引導碼不同而已,nec格式的是9ms高電平4.5ms低電平,而你發的這個高低都是4.5毫秒,其他的數據格式一樣

回復

使用道具 舉報

8#
ID:25357 發表于 2010-8-9 08:21 | 只看該作者
那如果判斷32還42位呢?
回復

使用道具 舉報

9#
ID:1 發表于 2010-8-9 15:55 | 只看該作者

你發的都是32位的呢,沒有42位的啊,你只要去數數據就知道是多少位了 用戶碼8位,反碼8位,數據碼8位,反碼8位,,4*8=32位

回復

使用道具 舉報

10#
ID:25357 發表于 2010-8-9 23:57 | 只看該作者
4樓沒有看到???不是嗎????
[此貼子已經被作者于2010-8-9 23:58:02編輯過]
回復

使用道具 舉報

11#
ID:1 發表于 2010-8-10 01:58 | 只看該作者

不好意思圖發的太多了我沒注意到4樓, 引導碼+13*2+8*2=42位 沒有錯

 

這個和普通的 日本NEC的uPD6121G的 唯一區別就是用戶碼多了5位,應該是PT2461、LC7461格式的,引導碼+13位用戶碼+13位用戶反碼+8位鍵數據碼+8位鍵數據反碼

 

 

   要判別是32位還是42位,我想可以這么做,先把所有的編碼都保存在數組里,然后取開頭的1->8位 和9->16位比較,看是否互為反碼,如果是就說明這是32位格式的編碼,如果不是再比較1->13位和14->26位,你看這樣行不行.

[此貼子已經被作者于2010-8-10 2:21:35編輯過]
回復

使用道具 舉報

12#
ID:25357 發表于 2010-8-10 08:38 | 只看該作者
貌似可以,但是我想問一下,32位和42位,開頭都有用戶碼和用戶反碼的嗎???
回復

使用道具 舉報

13#
ID:25357 發表于 2010-8-10 11:57 | 只看該作者

請問這個程序有問題嗎???好像解不了42位的,但是我的42位紅外發射也是自己做的,不知道是解碼問題,還是發射問題???謝謝。

 

 


#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char 
#define RdCommand 0x01 //定義ISP的操作命令
#define PrgCommand 0x02
#define EraseCommand 0x03 
#define Error 1
#define Ok 0
#define WaitTime 0x01 //定義CPU的等待時間
sfr ISP_DATA=0xe2;  //寄存器申明
sfr ISP_ADDRH=0xe3;
sfr ISP_ADDRL=0xe4;
sfr ISP_CMD=0xe5;
sfr ISP_TRIG=0xe6;
sfr ISP_CONTR=0xe7;
sbit dula=P2^6;  //申明U1鎖存器的鎖存端
sbit wela=P2^7;  //申明U2鎖存器的鎖存端

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

uchar f;

#define Imax 14000    //此處為晶振為11.0592時的取值, 
#define Imin 8000    //如用其它頻率的晶振時,
#define Inum1 1450    //要改變相應的取值。
#define Inum2 700 
#define Inum3 3000 

uchar Im[6]={0x00,0x00,0x00,0x00,0x00,0x00};
uchar Im1[2]={0x00,0x00};
uchar Im2[3]={0x00,0x00,0x00};
uchar show[6]={0,0,0,0,0,0};
//uchar Eim[4]={0,0,0,0};
unsigned long m,Tc;
unsigned char IrOK;
uchar IR;//分辨32位還是42位


void delay(uchar i)
{
  uchar j,k; 
  for(j=i;j>0;j--)
    for(k=125;k>0;k--);
}

void display()
{
   dula=0;
   P0=table[show[0]];
   dula=1;
   dula=0;
   
   wela=0;
   P0=0xfe;
   wela=1;
   wela=0;
   delay(5);
   
   P0=table[show[1]];
   dula=1;
   dula=0;
   
   P0=0xfd;
   wela=1;
   wela=0;
   delay(5);


   
}

  /* ================ 打開 ISP,IAP 功能 ================= */
void ISP_IAP_enable(void)
{
 EA = 0;       /* 關中斷   */
 ISP_CONTR = ISP_CONTR & 0x18;       /* 0001,1000 */
 ISP_CONTR = ISP_CONTR | WaitTime; /* 寫入硬件延時 */
 ISP_CONTR = ISP_CONTR | 0x80;       /* ISPEN=1  */
}
/* =============== 關閉 ISP,IAP 功能 ================== */
void ISP_IAP_disable(void)
{
 ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */
 ISP_TRIG = 0x00;
 EA   =   1;   /* 開中斷 */
}
/* ================ 公用的觸發代碼 ==================== */
void ISPgoon(void)
{
 ISP_IAP_enable();   /* 打開 ISP,IAP 功能 */
 ISP_TRIG = 0x46;  /* 觸發ISP_IAP命令字節1 */
 ISP_TRIG = 0xb9;  /* 觸發ISP_IAP命令字節2 */
 _nop_();
}
/* ==================== 字節讀 ======================== */
unsigned char byte_read(unsigned int byte_addr)
{
 ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址賦值 */
 ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
 ISP_CMD   = ISP_CMD & 0xf8;   /* 清除低3位  */
 ISP_CMD   = ISP_CMD | RdCommand; /* 寫入讀命令 */
 ISPgoon();       /* 觸發執行  */
 ISP_IAP_disable();    /* 關閉ISP,IAP功能 */
 return (ISP_DATA);    /* 返回讀到的數據 */
}
/* ================== 扇區擦除 ======================== */
void SectorErase(unsigned int sector_addr)
{
 unsigned int iSectorAddr;
 iSectorAddr = (sector_addr & 0xfe00); /* 取扇區地址 */
 ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
 ISP_ADDRL = 0x00;
 ISP_CMD = ISP_CMD & 0xf8;   /* 清空低3位  */
 ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3  */
 ISPgoon();       /* 觸發執行  */
 ISP_IAP_disable();    /* 關閉ISP,IAP功能 */
}
/* ==================== 字節寫 ======================== */
void byte_write(unsigned int byte_addr, unsigned char original_data)
{
 ISP_ADDRH = (unsigned char)(byte_addr >> 8);  /* 取地址  */
 ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
 ISP_CMD  = ISP_CMD & 0xf8;    /* 清低3位 */
 ISP_CMD  = ISP_CMD | PrgCommand;  /* 寫命令2 */
 ISP_DATA = original_data;   /* 寫入數據準備 */
 ISPgoon();       /* 觸發執行  */
 ISP_IAP_disable();     /* 關閉IAP功能 */
}

 


//外部中斷解碼程序
void intersvr1(void) interrupt 2 using 1
{

 Tc=TH0*256+TL0;   //提取中斷時間間隔時長
 TH0=0; 
    TL0=0;         //定時中斷重新置零
 if((Tc>Imin)&&(Tc<Imax))
      { 
  m=0;
        f=1;
  return;
      }       //找到啟始碼
   if(f==1)
      {
        if(Tc>Inum1&&Tc<Inum3) 
    {
   Im[m/8]=Im[m/8]>>1|0x80; m++; 
       }
      if(Tc>Inum2&&Tc<Inum1) 
        {
         Im[m/8]=Im[m/8]>>1; m++; //取碼
  }
 if(m>=16)
 {
    if(Im[0]!=~Im[1])  //判定32位或42位
  {
   if(m==42)
   m=0;
   f=0;
   if((Im[3]<<2|Im[4]>>6)==~(Im[4]<<2|Im[5]>>6))
   {
   IrOK=1;
   IR=42;
   Im2[0]=Im[0];
   Im2[1]=Im[1]>>3;
   Im2[2]=Im[3]<<2|Im[4]>>6 ;
   }
   else
   IrOK=0;
  }
 
   else {
    if(m==32) 
   {
         m=0;  
         f=0;
         if(Im[2]==~Im[3]) 
      {
           IrOK=1;
     IR=32; 
     Im1[0]=Im[0];
     Im1[1]=Im[2];
   }
        else IrOK=0;   //取碼完成后判斷讀碼是否正確
     }
  }
 }


   }
 
}


/*演示主程序*/
void main(void)
{
    unsigned int  a;
   
 m=0;
    f=0;
 EA=1;
 
 IT1=1;EX1=1;
 
 TMOD=0x11;  
 TH0=0;TL0=0;
 TR0=1;//ET0=1;

 while(1)
 {
 
       if(IrOK==1) 
    {
      SectorErase(0x2000);//擦除扇區
         if(IR==32)
    {
   byte_write(0x2000,Im1[1]);//重新寫入數據  
   byte_write(0x2001,Im1[0]);
       }
      if(IR==42) 
    {
   byte_write(0x2000,Im2[2]);//重新寫入數據  
      byte_write(0x2001,Im2[0]);
      byte_write(0x2002,Im2[1]);

   }
    }
       
     Im[2]=byte_read(0x2000); 
           show[1]=Im[2] & 0x0F;     //取鍵碼的低四位
           show[0]=Im[2] >> 4;   

           IrOK=0;      
  
           for(a=100;a>0;a--)
          {
    display();
   }
 
 }
}


回復

使用道具 舉報

14#
ID:1 發表于 2010-8-10 17:20 | 只看該作者

你這個程序能解32位的嗎,測試成功了沒有?

 

告訴你個辦法測試你的42位發射器,你可以用51hei單片機開發板制作一個紅外波形分析器
http://www.zg4o1577.cn/bbs/dpj-4524-1.html

來看發射出來的波形是否正確,

 

只有在你的發射波形正確的前提下你再進行解碼試驗,不然那是毫無意義的.

回復

使用道具 舉報

15#
ID:25357 發表于 2010-8-10 20:31 | 只看該作者
32位的已經測試成功。。。但是我想用rtx51 tiny來寫,結果顯示不出來。
回復

使用道具 舉報

16#
ID:22246 發表于 2010-8-10 23:33 | 只看該作者
你發個基于51hei開發板的 42位的紅外 發射程序吧,我沒有這樣的發射器所以只能用51hei開發板來代替,這樣才能調試你的接受程序,至于移植到rtx51 tiny出現問題,這肯定移植過程不小心出了錯誤,仔細找找.
回復

使用道具 舉報

17#
ID:25357 發表于 2010-8-11 00:47 | 只看該作者

我也看不出這個42位發射的程序對 不對。

 


#include <AT89X51.h> 
static bit OP;        //紅外發射管的亮滅
static unsigned int count;       //延時計數器
static unsigned int endcount; //終止延時計數
static unsigned char flag;      //紅外發送標志
char iraddr1;  
char iraddr2; 
char iraddr3;  
char iraddr4;  

void SendIRdata(char p_irdata);
void delay();
void main(void) 
{
  count = 0;
  flag = 0;
  OP = 0;
  P2_3 = 0;
  EA = 1; //允許CPU中斷 
  TMOD = 0x11; //設定時器0和1為16位模式1 
  ET0 = 1; //定時器0中斷允許 

  TH0 = 0xFF; 
  TL0 = 0xE5; //設定時值0為38K 也就是每隔26us中斷一次  
  TR0 = 1;//開始計數
  iraddr1=0xb3;
  iraddr2=0x8a;
  iraddr1=0xa9;
  iraddr2=0x02;

  do{
      delay();
      SendIRdata(0x36);// 在此填入發射數據
  }while(1);
} 
//定時器0中斷處理 
void timeint(void) interrupt 1 
{ 
  TH0=0xFF; 
  TL0=0xE5; //設定時值為38K 也就是每隔26us中斷一次
  count++;
  if (flag==1)
  {
    OP=~OP;
  }
  else
  {
    OP = 0;
  }
  P2_3 = OP;
} 

void SendIRdata(char p_irdata)
{
  int i;
  char irdata=p_irdata;
  //發送9ms的起始碼
  endcount=223;
  flag=1;
  count=0;
  do{}while(count<endcount);
  //發送4.5ms的結果碼
  endcount=117;
  flag=0;
  count=0;
  do{}while(count<endcount);
  
  irdata=iraddr1;
  for(i=0;i<8;i++)
  {
     //先發送0.56ms的38KHZ紅外波(即編碼中0.56ms的低電平)
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
 
     if(irdata-(irdata/2)*2)  //判斷二進制數個位為1還是0
     {
       endcount=41;  //1為寬的高電平
     }
    else
     {
     endcount=15;   //0為窄的高電平
     }
    flag=0;
    count=0;
    do{}while(count<endcount);
    irdata=irdata>>1;
  }

  irdata=iraddr2;
  for(i=0;i<8;i++)
  {
     //先發送0.56ms的38KHZ紅外波(即編碼中0.56ms的低電平)
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
 
     if(irdata-(irdata/2)*2)  //判斷二進制數個位為1還是0
     {
       endcount=41;  //1為寬的高電平
     }
    else
     {
     endcount=15;   //0為窄的高電平
     }
    flag=0;
    count=0;
    do{}while(count<endcount);
    irdata=irdata>>1;
  }

  irdata=iraddr3;
  for(i=0;i<8;i++)
  {
     //先發送0.56ms的38KHZ紅外波(即編碼中0.56ms的低電平)
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
 
     if(irdata-(irdata/2)*2)  //判斷二進制數個位為1還是0
     {
       endcount=41;  //1為寬的高電平
     }
    else
     {
     endcount=15;   //0為窄的高電平
     }
    flag=0;
    count=0;
    do{}while(count<endcount);
    irdata=irdata>>1;
  }
  //發送26位 的后2位
  irdata=iraddr4;
  for(i=0;i<2;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
     if(irdata-(irdata/2)*2)
     {
        endcount=41;
     }
     else
     {
       endcount=15;
     }
     flag=0;
     count=0;
     do{}while(count<endcount);
     irdata=irdata>>1;
  }
  //發送八位數據
  irdata=p_irdata;
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
     if(irdata-(irdata/2)*2)
     {
         endcount=41;
     }
     else
     {
       endcount=15;
     }
     flag=0;
     count=0;
     do{}while(count<endcount);
     irdata=irdata>>1;
  }
  //發送八位數據的反碼
  irdata=~p_irdata;
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
     if(irdata-(irdata/2)*2)
     {
         endcount=41;
     }
     else
     {
       endcount=15;
     }
     flag=0;
     count=0;
     do{}while(count<endcount);
     irdata=irdata>>1;
  }
  endcount=10;
  flag=1;
  count=0;
  do{}while(count<endcount);
  flag=0;
}
void delay()
{
  int i,j;
  for(i=0;i<400;i++)
  {
    for(j=0;j<100;j++)
    {
    }
  }
}
回復

使用道具 舉報

18#
ID:1 發表于 2010-8-11 02:46 | 只看該作者

程序應該沒有問題我看了,你發送了26位用戶碼分了4次發送的,見下的4行
iraddr1=0xb3;
iraddr2=0x8a;
iraddr1=0xa9;
iraddr2=0x02;

化為2進制為
10110011
10001010
10101001
10

再組合為2個13位 得到
0101010110011
1010101001100

這2組互為反碼,說明應該是正確的.

 

但是程序也有缺點,下面這個語句又是乘法又是除法,執行起來恐怕時間要花上10us吧,而載波的周期才26us.這里要改進.

 if(irdata-(irdata/2)*2)  //判斷二進制數個位為1還是0

[此貼子已經被作者于2010-8-11 2:51:52編輯過]
回復

使用道具 舉報

19#
ID:25357 發表于 2010-8-11 08:28 | 只看該作者

謝謝你的提醒,我把   if(irdata-(irdata/2)*2)  //判斷二進制數個位為1還是0      改為    if(irdata&0x01) 了。但是,測試了一個,還是接收不到42位的。

回復

使用道具 舉報

20#
ID:1 發表于 2010-8-11 14:47 | 只看該作者

那應該是你的解碼程序有問題了 仔細調試下 看問題出來哪里

回復

使用道具 舉報

21#
ID:27770 發表于 2011-1-12 13:02 | 只看該作者

看見大家在討論 32 位和 42 位的問題,也說幾句:

1.如果你接收的是有標準格式的數據碼(不是什么硬性標準,僅僅是市場擁有量有一定規模的),當然需要會出現這種 32 位或 42 位 或 更多其它數值位數的問題(實際上并不是僅僅只有這 2 種位數哦!).測試時可以借助一些工具(紅外線碼接收分析,本論壇就有簡單可靠),或者無限制長度進行接收.弄清楚位數,查找數據碼與引導頭的區別.有些品種一直按著遙控器會重復發送數據.

2.如果是非標準的代碼,方法也如上面差不多.但是變數更多,不要主觀認為引導頭必須=9ms,沒有這個規定!也不要認為發射頻率就是 38KHZ,也有 36KHZ 到 43KHZ 之間的.不要認為就是多少位,實際多少位都可以的,任意人家安排的----有點破解密碼的味道!

3.紅外線除了我們通常說的遙控器之外,也有用來通信的,作為傳送數據使用----本來就是傳送數據嘛!遙控器的特色是以可以代表一個特定的按鍵為主,傳送數據的用途時,就沒有這種限制了.-----開發人員怎么考慮,怎么安排,完完全全你是不知道的.----例如:做一個 5  位數值顯示的溫度表,加上校驗碼,引導頭等等,你說會是多少位?

再例如:與 PC 機的 RS232 通信,沒有位數限制.發多少就送多少,就接收多少,它再也不用位數來判斷是否發送完成了.

4.代碼的 0 與 1 .串行數據沒有其它辦法,它只有使用時間長短來代表 0 與 1.這個時間,不同廠家使用完全可以不按照通常"標準"遙控器來做的.只要它自己可以配套就行了!-------也有抗干擾好處呢!引導頭,結束標志,都可以脫離標準方式的.-----如果打算徹底弄明白,需要花費許多時間與精力.

今天就寫這些.------僅供參考!

回復

使用道具 舉報

22#
ID:72947 發表于 2015-2-2 00:17 | 只看該作者
前天解了個萬能彩電遙控,就是用戶碼并不規則,前后并不是反碼...
回復

使用道具 舉報

23#
ID:73792 發表于 2015-2-23 16:56 | 只看該作者
學習學習。。。。。。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲福利| 国产高清在线 | 久久久久久久夜 | 国产精品无码专区在线观看 | 国产一区二区三区免费观看在线 | 91精品国产日韩91久久久久久 | 91在线综合 | 另类一区 | 国产目拍亚洲精品99久久精品 | 国产日韩欧美精品 | 中文字幕精品一区二区三区精品 | 暖暖日本在线视频 | 中文字幕一区二区三区在线观看 | 日本字幕在线观看 | 国产在线观看一区二区三区 | 日本在线免费看最新的电影 | 91视频久久 | 国产精品一区在线观看 | 久久精品一区 | 精品国产乱码久久久久久1区2区 | 国产精品www| 国产精品污www在线观看 | 亚洲一二三在线观看 | 亚洲成人一区 | 麻豆视频在线免费看 | 国产成人高清视频 | 亚洲成人二区 | 亚洲综合一区二区三区 | 国产精品www| 欧美日韩不卡 | 91麻豆蜜桃一区二区三区 | 国户精品久久久久久久久久久不卡 | 日本一区二区影视 | 中文字幕av网 | 亚洲一区国产精品 | 91传媒在线观看 | 久久91精品久久久久久9鸭 | 久久青 | 四虎影视免费观看 | 在线中文一区 | 亚洲国产一区二区三区 |