⑴ 單片機 紅外解碼
紅外線遙控是目前使用最廣泛的一種通信和遙控手段。由於紅外線遙控裝置具有體積小、功耗低、功能強、
成本低等特點,因而,繼彩電、錄像機之後,在錄音機、音響設備、空凋機以及玩具等其它小型電器裝置上也紛
紛採用紅外線遙控。工業設備中,在高壓、輻射、有毒氣體、粉塵等環境下,採用紅外線遙控不僅完全可靠而且
能有效地隔離電氣干擾。
1 紅外遙控系統
通用紅外遙控系統由發射和接收兩大部分組成。應用編/解碼專用集成電路晶元來進行控制操作,如圖1 所示。
發射部分包括鍵盤矩陣、編碼調制、LED 紅外發送器;接收部分包括光、電轉換放大器、解調、解碼電路。
遙控發射器及其編碼
遙控發射器專用晶元很多,根據編碼格式可以分成兩大類,這里我們以運用比較廣泛,解碼比較容易的一類
來加以說明,現以日本NEC 的uPD6121G 組成發射電路為例說明編碼原理(一般家庭用的DVD、VCD、音響都使用
這種編碼方式)。當發射器按鍵按下後,即有遙控碼發出,所按的鍵不同遙控編碼也不同。這種遙控碼具有以下
特徵:
採用脈寬調制的串列碼,以脈寬為0.565ms、間隔0.56ms、周期為1.125ms 的組合表示二進制的「0」;以脈
寬為0.565ms、間隔1.685ms、周期為2.25ms 的組合表示二進制的「1」.
上述「0」和「1」組成的32 位二進制碼經38kHz 的載頻進行二次調制以提高發射效率,達到降低電源功耗的
目的。然後再通過紅外發射二極體產生紅外線向空間發射
UPD6121G 產生的遙控編碼是連續的32 位二進制碼組,其中前16 位為用戶識別碼,能區別不同的電器設備,
防止不同機種遙控碼互相干擾。該晶元的用戶識別碼固定為十六進制01H;後16 位為8 位操作碼(功能碼)及其
反碼。UPD6121G 最多額128 種不同組合的編碼。
遙控器在按鍵按下後,周期性地發出同一種32 位二進制碼,周期約為108ms。一組碼本身的持續時間隨它包
含的二進制「0」和「1」的個數不同而不同,大約在45~63ms 之間.
2 遙控發射器及其編碼
遙控發射器專用晶元很多,根據編碼格式可以分成兩大類,這里我們以運用比較廣泛,解碼比較容易的一類
來加以說明,現以日本NEC 的uPD6121G 組成發射電路為例說明編碼原理(一般家庭用的DVD、VCD、音響都使用
這種編碼方式)。當發射器按鍵按下後,即有遙控碼發出,所按的鍵不同遙控編碼也不同。這種遙控碼具有以下
特徵:
採用脈寬調制的串列碼,以脈寬為0.565ms、間隔0.56ms、周期為1.125ms 的組合表示二進制的「0」;以脈
寬為0.565ms、間隔1.685ms、周期為2.25ms 的組合表示二進制的「1」
上述「0」和「1」組成的32 位二進制碼經38kHz 的載頻進行二次調制以提高發射效率,達到降低電源功耗的
目的。然後再通過紅外發射二極體產生紅外線向空間發射。
UPD6121G 產生的遙控編碼是連續的32 位二進制碼組,其中前16 位為用戶識別碼,能區別不同的電器設備,
防止不同機種遙控碼互相干擾。該晶元的用戶識別碼固定為十六進制01H;後16 位為8 位操作碼(功能碼)及其
反碼。UPD6121G 最多額128 種不同組合的編碼。
遙控器在按鍵按下後,周期性地發出同一種32 位二進制碼,周期約為108ms。一組碼本身的持續時間隨它包
含的二進制「0」和「1」的個數不同而不同,大約在45~63ms 之間。
遙控信號接收
接收電路可以使用一種集紅外線接收和放大於一體的一體化紅外線接收器,不需要任何外接元件,就能完成
從紅外線接收到輸出與TTL 電平信號兼容的所有工作,而體積和普通的塑封三極體大小一樣,它適合於各種紅外
線遙控和紅外線數據傳輸。
接收器對外只有3 個引腳:Out、GND、Vcc 與單片機介面非常方便
① 脈沖信號輸出接,直接接單片機的IO 口。
② GND 接系統的地線(0V);
③ Vcc 接系統的電源正極(+5V);
⑵ c51單片機紅外NEC編碼解碼!
這個程序太簡單了,我之前寫過紅外發射程序的,接收程序也很簡單,你這個項目我2個小時都能幫你解決,但是89C52單片機發射38K不準需要把晶振加大,提高單片機的運行速度。
你的項目只要主機A發射紅外協議後面加一個地址,單片機B接收的時候全部進入接收狀態,判接收的地址是否符合對於單片機B的地址,如果地址符合,那就先回應一個數據例如:55FF55,主機接收到55FF55後後面開始接收數據,把接收到的數據直接寫入單片機內EEPRM裡面!
⑶ 單片機控制紅外遙控編碼解碼中定時器和外部中斷的作用是什麼紅外遙控編碼解碼的大致步驟是什麼
同時使用上定時器 跟 外中斷 的紅外程序,只有解碼程序。而且該方式,只能解析 使用不同時間長度代表數據「0」、「1」 的波形(如數據『1』的時間長度 2倍於數據『0』的時間)。
解析原理:外部中斷接 紅外輸入,當有 紅外信號的時候,該引腳會有波形輸入(N多下降沿),觸發外部中斷,通過記錄 每2次中斷的時間間隔,可以判斷此段時間對應的數據(0/1)。一般「數據」長度為32位數據
注意點:
①初次產生外中斷的時候,並無 時間記錄,不需要進行時間判斷;
②第二次中斷與第一次中斷 之間 的時間,是 紅外的引導碼,該時間一般多倍於數據時間(一般為ms級時間);
③第三次中斷與第二次中斷的時間,即為 第一個數據 的時間;
④第34次中斷與第33次中斷的時間間隔,即為 第32個數據的時間;
⑤後面 可能存在 停止位,是否存在,由遙控器決定;不過,一般都直接忽略該位,除非該位是由自己製作的遙控器 發出 的校驗位;
⑥後面 可能存在 連發碼,是否存在,由遙控器決定;
另外:一般紅外數據的每個位元組都是LSB在前,MSB在後的( 低位先發,高位後發)
軟體要處理以下情況:
①干擾的處理,有些紅外接收頭不僅僅對38KHz頻率光有反應,可能對人體紅外、日光燈紅外一樣有反應,那就存在干擾。如果它只產生一次干擾,就會使系統卡在引導碼接收階段;
②引導碼時間過短、過長 的處理;
③接收數據位數不足的處理;
④完成32位數據接收後,處理接收爛尾:後面不會有中斷(如果需接收停止位、連發碼,就增加對應數據長度),需要停止計時。
⑤進行數據校對,一般第一位元組跟第二位元組互為反碼,第三位元組跟第四位元組互為反碼,而且第一位元組 代表 一個地址、一個密碼,只有地址、密碼正確,才能算合法的操作。
⑷ 單片機紅外解碼程序問題,完全不能理解
「我並非一點基礎也沒有」
很遺憾,從你提的這三個問題來看,你的基礎比0隻多出一點點。
(1)Tc是個16位整型。這是16位整型的基本演算法。Tc保存的是抓出的脈寬。
(2)引導碼就是指定寬度的脈沖,數據碼是短一些的脈沖——所以才會那麼大費周章地抓脈寬判斷是引導碼還是用戶碼。接收是否反相要查你所用接收頭的手冊,有可能跟你的程序是相反的。
(3)m不是位元組序號而是位序號。注意前面的/8。
加油啊
⑸ 遙控器紅外用單片機解碼問題。
那不可能肯定是你解碼,數據轉換問題,你把讀出來的編碼轉化成10進制就不會出現這樣的問題了,沒有看到你的程序是什麼樣的,一般你這樣的情況是16進制出問題。
不如鍵碼
0x05;
鍵碼
0xE5;
這兩個編碼就會一樣,因為沒有計算高8位,低8位相同,這樣就會出現你所說的那種問題。
⑹ 單片機紅外解碼
過後就不不能明白你明白你們,
⑺ 單片機的紅外遙控的原理
1、發送端由單片機和紅外發光二極體組成。
單片機控制紅外發光二極體發射38KHz左右的紅外光,這個紅外光就可能起到傳遞信號的作用。你可以在你的程序中規定發射紅外線時表示二進制的一個位『1』無紅外線時表示二進制的『0』。這樣你就可以發出一系列由『1』和『0』所級成的信號。
2、接收端是由紅外接收二極體和單片機組成。
前面我們讓發射端發出信號,現在接收頭就開始收信號。
⑻ 單片機紅外解碼
紅外解碼程序!
/*-----------------------------------------------
名稱:遙控器紅外解碼液晶顯示
------------------------------------------------*/
#include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
#include<stdio.h>
#include<intrins.h>
#define TURE 1
#define FALSE 0
sbit IR=P3^2; //紅外介面標志
sbit RS = P2^4;//Pin4
sbit RW = P2^5;//Pin5
sbit E = P2^6;//Pin6
#define Data P0//數據埠
unsigned int hour,minute,second,count;
char code Tab[16]="0123456789ABCDEF";
char data TimeNum[]=" ";
char data Test1[]=" ";
/******************************************************************/
/* 變數聲明 */
/******************************************************************/
unsigned char irtime;//紅外用全局變數
bit irpro_ok,irok;
unsigned char IRcord[4]; //處理後的紅外碼,分別是 客戶碼,客戶碼,數據碼,數據碼反碼
unsigned char irdata[33]; //33個高低電平的時間數據
/******************************************************************/
/* 函數聲明 */
/******************************************************************/
void Ir_work(void);
void Ircordpro(void);
void ShowString (unsigned char line,char *ptr);
/******************************************************************/
/* 定時器0中斷服務函數 */
/******************************************************************/
void tim0_isr (void) interrupt 1 using 1//定時器0中斷服務函數
{
irtime++; //用於計數2個下降沿之間的時間
}
/******************************************************************/
/* 外部中斷0函數 */
/******************************************************************/
void ex0_isr (void) interrupt 0 using 0//外部中斷0服務函數
{
static unsigned char i; //接收紅外信號處理
static bit startflag; //是否開始處理標志位
if(startflag)
{
if(irtime<63&&irtime>=33)//引導碼 TC9012的頭碼,9ms+4.5ms
i=0;
irdata[i]=irtime;//存儲每個電平的持續時間,用於以後判斷是0還是1
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
else
{irtime=0;startflag=1;}
}
/******************************************************************/
/* 定時器0初始化 */
/******************************************************************/
void TIM0init(void)//定時器0初始化
{
TMOD=0x02;//定時器0工作方式2,TH0是重裝值,TL0是初值
TH0=0x00; //重載值
TL0=0x00; //初始化值
ET0=1; //開中斷
TR0=1;
}
/******************************************************************/
/* 外部中斷初始化 */
/******************************************************************/
void EX0init(void)
{
IT0 = 1; //指定外部中斷0下降沿觸發,INT0 (P3.2)
EX0 = 1; //使能外部中斷
EA = 1; //開總中斷
}
/******************************************************************/
/* 紅外鍵值處理 */
/******************************************************************/
void Ir_work(void) //紅外鍵值散轉程序
{
TimeNum[5] = Tab[IRcord[0]/16]; //處理客戶碼並顯示
TimeNum[6] = Tab[IRcord[0]%16];
TimeNum[8] = Tab[IRcord[1]/16]; //處理客戶碼並顯示
TimeNum[9] = Tab[IRcord[1]%16];
TimeNum[11] = Tab[IRcord[2]/16]; //處理數據碼並顯示
TimeNum[12] = Tab[IRcord[2]%16];
TimeNum[14] = Tab[IRcord[3]/16]; //處理數據反碼並顯示
TimeNum[15] = Tab[IRcord[3]%16];
ShowString(1,TimeNum);//顯示處理過後的碼值
irpro_ok=0; //處理完成後清楚標志位
}
/******************************************************************/
/* 紅外解碼函數處理 */
/******************************************************************/
void Ircordpro(void)//紅外碼值處理函數
{
unsigned char i, j, k;
unsigned char cord,value;
k=1;
for(i=0;i<4;i++) //處理4個位元組
{
for(j=1;j<=8;j++) //處理1個位元組8位
{
cord=irdata[k];
if(cord>7)//大於某值為1,這個和晶振有絕對關系,這里使用12M計算,此值可以有一定誤差
{
value=value|0x80;
}
else
{
value=value;
}
if(j<8)
{
value=value>>1;
}
k++;
}
IRcord[i]=value;
value=0;
} irpro_ok=1;//處理完畢標志位置1
}
/******************************************************************/
/* 微秒延時函數 */
/******************************************************************/
void DelayUs(unsigned char us)//delay us
{
unsigned char uscnt;
uscnt=us>>1;/* Crystal frequency in 12MHz*/
while(--uscnt);
}
/******************************************************************/
/* 毫秒函數聲明 */
/******************************************************************/
void DelayMs(unsigned char ms)//delay Ms
{
while(--ms)
{
DelayUs(250);
DelayUs(250);
DelayUs(250);
DelayUs(250);
}
}
/******************************************************************/
/* 寫入命令函數 */
/******************************************************************/
void WriteCommand(unsigned char c)
{
DelayMs(5);//操作前短暫延時,保證信號穩定
E=0;
RS=0;
RW=0;
_nop_();
E=1;
Data=c;
E=0;
}
/******************************************************************/
/* 寫入數據函數 */
/******************************************************************/
void WriteData(unsigned char c)
{
DelayMs(5); //操作前短暫延時,保證信號穩定
E=0;
RS=1;
RW=0;
_nop_();
E=1;
Data=c;
E=0;
RS=0;
}
/******************************************************************/
/* 寫入位元組函數 */
/******************************************************************/
void ShowChar(unsigned char pos,unsigned char c)
{
unsigned char p;
if (pos>=0x10)
p=pos+0xb0; //是第二行則命令代碼高4位為0xc
else
p=pos+0x80; //是第二行則命令代碼高4位為0x8
WriteCommand (p);//寫命令
WriteData (c); //寫數據
}
/******************************************************************/
/* 寫入字元串函數 */
/******************************************************************/
void ShowString (unsigned char line,char *ptr)
{
unsigned char l,i;
l=line<<4;
for (i=0;i<16;i++)
ShowChar (l++,*(ptr+i));//循環顯示16個字元
}
/******************************************************************/
/* 初始化函數 */
/******************************************************************/
void InitLcd()
{
DelayMs(15);
WriteCommand(0x38); //display mode
WriteCommand(0x38); //display mode
WriteCommand(0x38); //display mode
WriteCommand(0x06); //顯示游標移動位置
WriteCommand(0x0c); //顯示開及游標設置
WriteCommand(0x01); //顯示清屏
}
/******************************************************************/
/* 主函數 */
/******************************************************************/
void main(void)
{
EX0init(); //初始化外部中斷
TIM0init();//初始化定時器
InitLcd(); //初始化液晶
DelayMs(15);
sprintf(Test1," haixiang MCU "); //顯示第一行固定信息
ShowString(0,Test1);
sprintf(TimeNum,"Code ");//顯示第二行固定信息
ShowString(1,TimeNum);
while(1)//主循環
{
if(irok) //如果接收好了進行紅外處理
{
Ircordpro();
irok=0;
}
if(irpro_ok) //如果處理好後進行工作處理,如按對應的按鍵後顯示對應的數字等
{
Ir_work();
}
}
}
⑼ 關於51單片機紅外解碼程序,哪位大俠幫我看下
我以前做的一個項目,紅外遙控開關,解碼部分的code,供參考
6121碼,外部中斷0,at89s52
void int0() interrupt 0 //外部中斷1服務函數,紅外解碼程序
{
static uchar wei; //定義靜態變數
static uchar pp; //定義靜態變數
if(tt<56&&tt>50) {d2=0; tt=0;pp=0;wei=0;}//起始信號符合,將d2標記為0,各變數清零
if(tt>11)tt=0;
if(d2==0&&tt>=4)
{
buf[pp]>>=1;
if(tt>5) buf[pp]|=0x80; //如果時間大於780us ,則視為收到數據1
wei++;
if(wei==8)
{
pp++;
wei=0;
if(pp==4) { pp=0; d2=1;} //接收滿4個位元組,標志位清除
} //在 d2為0期間進入中斷8次,說明已經收到一個位元組數據,位元組號加1
}
tt=0;//每次進入中斷都清零
}
void timer1() interrupt 3 //紅外解碼計時
{
tt++;
}