導航:首頁 > 操作系統 > 單片機紅外遙控編碼

單片機紅外遙控編碼

發布時間:2023-03-25 16:07:52

A. 單片機,硬體,紅外遙控編碼問題。38KHz是幹嘛用的

學習型遙控常用的載波頻率為38kHz,這是由發射端編碼晶元所使用的455kHz晶振來決定的。

在信號傳輸的過程中,並不是將信號直接進行傳輸,而是將信號負載到一個固定頻率的波上,這個過程稱為載入,這樣的一個固定頻率的波稱為載波頻率。
嚴格的講,就是把一個較低的信號頻率調制到一個相對較高的頻率上去,這被低頻調制的較高頻率就叫載波頻率,也叫基頻。

B. 最簡單51單片機紅外編碼獲取問題

這有個帖子,你看了就明白,看看是怎樣實現輸入晶振頻率自適應解碼。
#define CPU_Fosc 12000000L //輸入主頻,自適應解碼(單位:Hz,范圍:6MHz ~ 40MHz)

紅外線解碼程序+遙控器程序+模擬文件(可定義任意I/O作接收腳,支持長/短按,適應6MHz~40MHz)
http://www.ourdev.cn/thread-5155483-1-1.html

C. 單片機紅外編碼

C51程序代碼:
#include <AT89X51.h>
static bit OP; //紅外發射管的亮滅
static unsigned int count; //延時計數器
static unsigned int endcount; //終止延時計數
static unsigned char flag; //紅外發送標志
char iraddr1; //十六位地址的第一個位元組
char iraddr2; //十六位地址的第二個位元組
void SendIRdata(char p_irdata);
void delay();
void main(void)
{
count = 0;
flag = 0;
OP = 0;
P3_4 = 0;
EA = 1; //允許CPU中斷
TMOD = 0x11; //設定時器0和1為16位模式1
ET0 = 1; //定時器0中斷允許

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

do{
delay();
SendIRdata(12);
}while(1);
}
//定時器0中斷處理
void timeint(void) interrupt 1
{
TH0=0xFF;
TL0=0xE6; //設定時值為38K 也就是每隔26us中斷一次
count++;
if (flag==1)
{
OP=~OP;
}
else
{
OP = 0;
}
P3_4 = 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++)
{
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++)
{
}
}
}

D. 單片機紅外遙控器解碼程中,所有按鍵的地址碼都相同嗎

單片機紅外遙控器編碼一般由引導碼+地址基桐橋碼(16位)+命令碼(16位)組成,在普搏猛通的遙控器上所有的按鍵只是命令輪燃碼不同,地址碼是不變的

E. 紅外遙控器原理 遙控器原理圖

遙控器是一種用來遠控機械的裝置。現代的遙控器,主要是由集成電路電板和用來產生不同訊息的按鈕所組成。下面一起來看看紅外遙控器原理以及遙控器原理圖吧。


紅外遙控器原理


紅外線遙控系統一般由發射器和接收器兩部分組成。發射器由指令鍵、指令信號產生電路、調制電路、驅動電路及紅外線發射器組成。當指令鍵被按下時,指令信號產生電路便產生所需要的控制信號,控制指令信號經調制電路調制後,最終由驅動電路驅動紅外線發射器,發出紅外線遙控指令信號。


接收器由紅外線接收器件、前置放大電路、解調電路、指令信號檢出電路、記憶及驅動電路、執行電路組成。當紅外接收器件收到發射器的紅外指令信號時,它將紅外光信號變成電信號並送到前置放大電路進行放大,再經過解調器後,由信號檢出電路將指令信號檢出,最後由記憶電路和驅動電路驅動執行電路,實現各種操作。


控制信號一般以某些不同的特徵來區分,常用的區分指令信號的特徵是頻率和碼組特徵,即用不同的頻率或者編碼的電信號代表不同的指令信號來實現遙控。所以紅外遙控系統通常按照產生和區分控制指令信號的方式和特徵分類,常分為頻分制紅外線遙控和碼分制紅外線遙控。



1紅外遙控系統發射部分


紅外遙控發射器由鍵盤矩陣、遙控專用集成電路、驅動電路和紅外發光二極體三部分組成,結構如圖1所示。

當有鍵按下時,系統延時一段時間防止干擾,然後啟動振盪器,鍵編碼器取得鍵碼後從ROM中取得相應的指令代碼(由0和1組成的代碼),遙控器一般採用電池供電,為了節省電量和提高抗干擾能力,指令代碼都是經32~56kHz范圍內的載波調制後輸出到放大電路,驅動紅外發射管發射出940nm的紅外光。當發送結束時振盪器也關閉,系統處於低功耗休眠狀態。載波的頻率、調制頻率在不同的場合會有不同,不過家用電器多採用的是38kHz的,也就是用455kHz的振盪器經過12分頻得到的。


遙控發射器的信號是由一串0和1的二進制代碼組成的,不同的晶元對0和1的編碼有所不同,現有的紅外遙控包括兩種方式:脈沖寬度調制(PWW)和脈沖位置調制(PPM或曼徹斯特編碼)。兩種形式編碼的代表分別是NEC和PHILIPS的RC-5。


2紅外遙控系統接收部分


接收部分是由放大器、限幅器、帶通濾波器、解調器、積分器、比較器等組成的,比如採用較早的紅外接收二極體加專用的紅外處理電路的方法,如CXA20106,此種方法電路復雜,現在一般不採用。但是在實際應用中,以上所有的電路都集成在一個電路中,也就是我們常說的一體化紅外接收頭。一體化紅外接收頭按載波頻率的不同,型號也不一樣。由於與CPU的介面的問題,大部分接收電路都是反碼輸出,也就是說當沒有紅外信號時輸出為1,有信號輸出時為0,它只有三個引腳,分別是+5V電源、地、信號輸出。



系統的設計


1單片機編碼發射部分


①鍵盤部分

紅外遙控器的發射器電路比較簡單,由一個4×4矩形鍵盤、一個PNP驅動三極體、一個紅外線發光二極體和兩個限流電阻組成。要遙控哪台接收器由鍵盤輸入,即由鍵盤輸入要紅外遙控的地址,地址經過編碼、調制後通過紅外發光二極體發射出去。

矩陣鍵盤部分由16個輕觸按鍵按照4行4列排列,將行線所接的單片機的I/O口作為輸出端,而列線所接的作為輸入。當沒有鍵被按下時,所有輸出端都是高電平,代表沒有鍵按下。有鍵按下時,則輸入線就會被拉抵,這樣,通過讀入輸入線的狀態就可以知道是否有鍵被按下。

鍵盤的列線接到P1口的低4位,行線接到P1口的高4位,列線P1.0~P1.3設置為輸入線,行線P1.4~P1.7設置為輸出線。

檢測當前是否有鍵被按下。檢測的方法是使P1.4~P1.7輸出為0,讀取P1.0~P1.3的狀態,若P1.0~P1.3為全1,則無鍵閉合,否則有鍵閉合。

去除鍵抖動。當檢測到有鍵按下後,延時一段時間再做下一步檢測判斷。

若有鍵按下,應該識別出是哪一個鍵閉合。方法是對鍵盤的行線進行掃描。P1.4~P1.7按下面4種組合依次輸出1110,1101,1011,0111,在每組行輸出時讀取P1.0~P1.3,若全為1,則表示0這行沒有鍵輸入,否則有鍵閉合。由此得到閉合鍵的行值和列值,然後採用計算的方法或者查表的方法將閉合鍵的行值和列值轉換成所定義的值。

為了保證每閉合一次CPU僅作一次處理,必須去除鍵釋放時的抖動。產生的鍵值放在發送資料庫區,30H存放的是產生的鍵值,即要遙控的8位地址共1位元組,31H放的是和30H中的相同的8位地址,地址碼重發了一次,主要是加強遙控器的可靠性,如果兩次地址碼不相同,則說明本幀數據有錯,應該丟棄。32H放的是00H(為了編程簡單),33H放的是0FFH,一共32位數據。要發送數據時,只要到那裡讀取數據即可,然後調用發射子程序發送。



②載波部分


根據前面介紹的紅外遙控的基本原理,紅外遙控器編碼調制的方法其實很簡單,只要生成一定時間長的電平就可以。再通過一個38kHz載波調制便可以發射編碼。載波的產生方法有多種,可以由CMOS門電路RC振盪器構成,或者由555時基電路構成等。

在此次設計中採用的是CPU延時,即用定時器中斷完成,用單片機的T0定時產生38kHz載波。設定定時器為方式2,即自動恢復初值的8位計數器。TL0作為8位計數器,TH0作為計數初值寄存器,當TL0計數溢出時,一方面置1溢出標志位TF0,向CPU請求中斷,同時將TH0內容送入TL0,使TL0從初值開始重新加1計數。因此,T0工作於方式2,定時精度比較高。根據計算,設定38KHz的定時初值,採用12kHz晶振的定時初值為0F3H,用11.0592kHz晶振時的初值為0F4H,設定好定時器中斷,在中斷程序中只寫入取反P2.0(CPLP2.0),當要發送數據1時,前面560μs高電平發送時,先打開定時器中斷,再啟動定時器,允許定時器工作,延時560μs再關定時器,後面1690μs的低電平因為不發送信號,所以可以直接置P2.0高電平後,延時1690μs即可;數據0前面的560μs高電平和數據1的一樣,後面560μs的低電平因為不發送信號,所以可以直接置P2.0高電平後,延時560μs即可。




2紅外接收解碼電路


紅外遙控接收採用一體化紅外接收頭,它將紅外接收二極體、放大器、解調、整形等電路安裝在一起,只有三個引腳。紅外接收頭的信號輸出端接單片機的INT0端,單片機中斷INT0在紅外脈沖下降沿時產生中斷。電路如圖3.3所示,圖中增加一隻PNP三極體對輸出信號放大,R和C組成去耦電路抑制電源干擾。


3遙控信號的解碼演算法


平時,遙控器無鍵按下時,紅外發射二極體不發出信號,遙控接收頭輸出信號1,有鍵按下時,0和1的編碼的高電平經遙控接收頭反相後會輸出信號0,由於與單片機的中斷腳相連,將會引起單片機中斷(單片機預先設定為下降沿產生中斷)。


遙控碼發射時由9ms的高電平和4.5ms的低電平表示引導碼,用560μs的高電平和560μs的低電平表示數據「0」,用560μs的高電平和1690μs的低電平表示數據「1」,引導碼後面是4位元組的數據。接收碼是發射碼的反向,所以判斷數據中的高電平的長度是讀出數據的要點,在這里用882μs(560~1690μs之間)作為標尺,如果882μs之後還是高電平則表示是數據1,將1寫入寄存器即可(數據為1時還需要再延時一段時間使電平變低,用來檢測下一個低電平的開始)。882μs後電平為低電平則表示是數據0,則將0寫入寄存器中,之後再等待下一個低電平的到來。


繼續接收下面的數據,當接收到32位數據時,說明一幀數據接收完畢,然後判斷本次接收是否有效,如果兩次地址碼相同並且等於本系統的地址碼,數據碼和數據反碼之和等於0FFH,則接收的本幀數據有效,點亮一隻發光二極體,否則丟棄本次接收到的數據。


接收完畢後,初始化本次接收到的數據,准備下次遙控接收。


以上就是小編為大家介紹的遙控器原理,希望能夠幫助到您。更多關於遙控器原理的相關資訊,請繼續關注土巴兔學裝修。

F. 基於51單片機紅外遙控代碼(C語言)

以下文件是51單片機實現遙控解碼,通過數碼管顯示鍵碼的程序,P0口驅動數碼管段選,p2.6和p2.7為數碼管位選,接收頭連到P3.2口。此程序以通過驗證,可以直接編譯使用,另外還有一個繼電器和蜂鳴器的控制,不用可以屏蔽掉。

;********************************************************************************
;* 描述: *
;* 遙控鍵值讀取器 *
;* 數碼管顯示, P0口為數碼管的數據口 *
;* *
;********************************************************************************
;遙控鍵值解碼-數碼管顯示 *
;********************************************************************************/

#include <reg51.h>
#include <intrins.h>

void IR_SHOW();
void delay(unsigned char x);//x*0.14MS
void delay1(unsigned char ms);
void beep();

sbit IRIN = P3^2;
sbit BEEP = P3^7;
sbit RELAY= P1^3;
sbit GEWEI= P2^7;
sbit SHIWEI= P2^6;

unsigned char IRCOM[8];
unsigned char code table[16] =
{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
main()
{
IE = 0x81; //允許總中斷中斷,使能 INT0 外部中斷
TCON = 0x1; //觸發方式為脈沖負邊沿觸發
delay(1);

IRIN=1;
BEEP=1;
RELAY=1;
for(;;)
{
IR_SHOW();
}

} //end main

void IR_IN() interrupt 0 using 0
{
unsigned char i,j,k,N=0;
EA = 0;
I1:
for (i=0;i<4;i++)
{
if (IRIN==0) break;
if (i==3) {EA =1;return;}
}
delay(20);
if (IRIN==1) goto I1; //確認IR信號出現
while (!IRIN) //等 IR 變為高電平
{delay(1);}

for (j=0;j<4;j++)
{
for (k=0;k<8;k++)
{
while (IRIN) //等 IR 變為低電平
{delay(1);}
while (!IRIN) //等 IR 變為高電平
{delay(1);}
while (IRIN) //計算IR高電平時長
{
delay(1);
N++;
if (N>=30) {EA=1;return;}
}
IRCOM[j]=IRCOM[j] >> 1;
if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}
N=0;
}//end for k
}//end for j

if (IRCOM[2]!=~IRCOM[3]) {EA=1;return;}
IRCOM[5]=IRCOM[2] & 0x0F;
IRCOM[6]=IRCOM[2] & 0xF0;
IRCOM[6]=IRCOM[6] >> 4;
beep();
EA = 1;

}

void IR_SHOW()
{
P0 = table[IRCOM[5]];
GEWEI = 0;
SHIWEI = 1;
delay1(4);
P0 = table[IRCOM[6]];
SHIWEI = 0;
GEWEI = 1;
delay1(4);
}

void beep()
{
unsigned char i;
for (i=0;i<100;i++)
{
delay(5);
BEEP=!BEEP;
}
BEEP=1;
}

void delay(unsigned char x)//x*0.14MS
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}

void delay1(unsigned char ms)
{
unsigned char i;
while(ms--)
{
for(i = 0; i<120; i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}

G. 51單片機紅外遙控程序

#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcden = P2^7;
sbit lcdrs = P2^6;
sbit lcdwr = P2^5;
sbit IR = P3^2;
uchar IRCOM[6];//數組,用於存儲紅外編碼
uchar code table1[] = "remote control";
uchar code table2[] = "CODE:";
void delayms(uchar x)// 延時x*0.14ms
{
uchar i;
while(x--)
for(i=0;i<13;i++){}
}
void delay(uchar x) //延時xms
{
uchar i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
/****************************LCD部分***********************************************/
void write_com(uchar com)
{
lcden = 0;
lcdrs = 0;
lcdwr = 0;
P0 = com;
delay(5);
lcden = 1;
delay(5);
lcden = 0; //別忘了lcden拉低
}
void write_date(uchar date)
{
lcden = 0;
lcdrs = 1;
lcdwr = 0;
P0 = date;
delay(5);
lcden = 1;
delay(5);
lcden = 0;
}
void lcd_init(void)
{
lcden = 0;
lcdrs = 0;
lcdwr = 0;
delay(5);
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
/*****************main()************************/
void main(void)
{
uchar count=0;
IR = 1;
lcd_init();
write_com(0x80);
while(table1[count]!='\0')
{
write_date(table1[count]);
count++;
delay(5);
}
count = 0;
write_com(0x80+0x40);
while(table2[count]!='\0')
{
write_date(table2[count]);
count++;
delay(5);
}

IE = 0x81; //開中斷
TCON = 0x01;//脈沖負邊沿觸發
while(1);

}
/*********************紅外中斷**************************/
void IR_time() interrupt 0
{
uchar i,j,TimeNum=0;//TimeNum用來計IR高電平次數 從而判斷是0還是1
EX0 = 0; //關閉中斷
delayms(5);
if(1 == IR)
{
EX0 = 1;
return;
}
while(!IR) //跳過9ms前導低電平
delayms(1);
for(i=0;i<4;i++)
{
for(j=0;j<8;j++)
{
while(IR) //跳過4.5ms的前導高電平
delayms(1);
while(!IR) //跳過0.56ms的低電平
delayms(1);

while(IR)
{
TimeNum++; //計時高電平時間從而判斷讀取的是0還是1
delayms(1);
}
if(TimeNum>=30)//按鍵按下時間過長 跳過
{
EX0 = 1;
return;
}
IRCOM[i] = IRCOM[i]>>1;
if(TimeNum >= 8) //8*0.14ms 這時讀取的是1;
{
IRCOM[i] = IRCOM[i]|0x80;
}
TimeNum = 0;
}
}
if(IRCOM[2]!=~IRCOM[3])//判斷八位數據和八位數據反碼是否相等
{
EX0 = 1;
return;
}
IRCOM[4] = IRCOM[2]&0x0f;//取低四位
IRCOM[5] = IRCOM[2]>>4; //IRCOM[5]取IRCOM[2]高四位
if(IRCOM[4] > 9) //轉換成字元
{
IRCOM[4] = IRCOM[4] + 0x37;
}
else
IRCOM[4] = IRCOM[4] + 0x30;
if(IRCOM[5] > 9)
{
IRCOM[5] = IRCOM[5] + 0x37;
}
else
IRCOM[5] = IRCOM[5] + 0x30;
delay(5);
write_com(0x80 + 0x40 + 5);
write_date(IRCOM[5]);
write_date(IRCOM[4]);
EX0 = 1; //重新開啟外部中斷
}

H. 單片機紅外解碼

紅外解碼程序!

/*-----------------------------------------------
名稱:遙控器紅外解碼液晶顯示
------------------------------------------------*/
#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();
}
}
}

I. 51單片機紅外遙控程序是什麼

#includex0dx0a#includex0dx0a#define uchar unsigned charx0dx0a#define uint unsigned intx0dx0asbit lcden = P2^7;x0dx0asbit lcdrs = P2^6;x0dx0asbit lcdwr = P2^5;x0dx0asbit IR = P3^2;x0dx0auchar IRCOM[6];//數組,用於存儲紅外編碼x0dx0auchar code table1[] = "remote control";x0dx0auchar code table2[] = "CODE:";x0dx0avoid delayms(uchar x)// 延時x*0.14msx0dx0a{x0dx0auchar i;x0dx0awhile(x--)x0dx0afor(i=0;i<13;i++){}x0dx0a}x0dx0avoid delay(uchar x)//延時xmsx0dx0a{x0dx0auchar i,j;x0dx0afor(i=x;i>0;i--)x0dx0afor(j=110;j>0;j--);x0dx0a}x0dx0a/****************************LCD部分***********************************************/x0dx0avoid write_com(uchar com)x0dx0a{x0dx0alcden = 0;x0dx0alcdrs = 0;x0dx0alcdwr = 0;x0dx0aP0 = com;x0dx0adelay(5);x0dx0alcden = 1;x0dx0adelay(5);x0dx0alcden = 0;//別忘了lcden拉低x0dx0a}x0dx0avoid write_date(uchar date)x0dx0a{x0dx0alcden = 0;x0dx0alcdrs = 1;x0dx0alcdwr = 0;x0dx0aP0 = date;x0dx0adelay(5);x0dx0alcden = 1;x0dx0adelay(5);x0dx0alcden = 0;x0dx0a}x0dx0avoid lcd_init(void)x0dx0a{x0dx0alcden = 0;x0dx0alcdrs = 0;x0dx0alcdwr = 0;x0dx0adelay(5);x0dx0awrite_com(0x38);x0dx0awrite_com(0x0c);x0dx0awrite_com(0x06);x0dx0awrite_com(0x01);x0dx0a}x0dx0a/*****************main()************************/x0dx0avoid main(void)x0dx0a{x0dx0auchar count=0;x0dx0aIR = 1;x0dx0alcd_init();x0dx0awrite_com(0x80);x0dx0awhile(table1[count]!='\0')x0dx0a{x0dx0awrite_date(table1[count]);x0dx0acount++;x0dx0adelay(5);x0dx0a}x0dx0acount = 0;x0dx0awrite_com(0x80+0x40);x0dx0awhile(table2[count]!='\0')x0dx0a{x0dx0awrite_date(table2[count]);x0dx0acount++;x0dx0adelay(5);x0dx0a}x0dx0ax0dx0aIE = 0x81; //開中斷x0dx0aTCON = 0x01;//脈沖負邊沿觸發x0dx0awhile(1);x0dx0ax0dx0a}x0dx0a/*********************紅外中斷**************************/x0dx0avoid IR_time() interrupt 0 x0dx0a{x0dx0auchar i,j,TimeNum=0;//TimeNum用來計IR高電平次數 從而判斷是0還是1x0dx0aEX0 = 0; //關閉中斷x0dx0adelayms(5);x0dx0aif(1 == IR)x0dx0a{x0dx0aEX0 = 1;x0dx0areturn;x0dx0a}x0dx0awhile(!IR) //跳過9ms前導低電平x0dx0adelayms(1);x0dx0afor(i=0;i<4;i++)x0dx0a{x0dx0afor(j=0;j<8;j++)x0dx0a{x0dx0awhile(IR) //跳過4.5ms的前導高電平x0dx0adelayms(1);x0dx0awhile(!IR) //跳過0.56ms的低電平x0dx0adelayms(1);x0dx0ax0dx0awhile(IR) x0dx0a{x0dx0aTimeNum++; //計時高電平時間從而判斷讀取的是0還是1x0dx0adelayms(1);x0dx0a}x0dx0aif(TimeNum>=30)//按鍵按下時間過長 跳過x0dx0a{x0dx0aEX0 = 1;x0dx0areturn;x0dx0a}x0dx0aIRCOM[i] = IRCOM[i]>>1;x0dx0aif(TimeNum >= 8) //8*0.14ms 這時讀取的是1;x0dx0a{x0dx0aIRCOM[i] = IRCOM[i]|0x80;x0dx0a}x0dx0aTimeNum = 0;x0dx0a}x0dx0a}x0dx0aif(IRCOM[2]!=~IRCOM[3])//判斷八位數據和八位數據反碼是否相等x0dx0a{x0dx0aEX0 = 1;x0dx0areturn;x0dx0a}x0dx0aIRCOM[4] = IRCOM[2]&0x0f;//取低四位x0dx0aIRCOM[5] = IRCOM[2]>>4; //IRCOM[5]取IRCOM[2]高四位x0dx0aif(IRCOM[4] > 9) //轉換成字元x0dx0a{x0dx0aIRCOM[4] = IRCOM[4] + 0x37;x0dx0a}x0dx0aelsex0dx0aIRCOM[4] = IRCOM[4] + 0x30;x0dx0aif(IRCOM[5] > 9)x0dx0a{x0dx0aIRCOM[5] = IRCOM[5] + 0x37;x0dx0a}x0dx0aelsex0dx0aIRCOM[5] = IRCOM[5] + 0x30;x0dx0adelay(5);x0dx0awrite_com(0x80 + 0x40 + 5);x0dx0awrite_date(IRCOM[5]);x0dx0awrite_date(IRCOM[4]);x0dx0aEX0 = 1; //重新開啟外部中斷x0dx0a}

閱讀全文

與單片機紅外遙控編碼相關的資料

熱點內容
cocos2dluapdf 瀏覽:491
假的加密鎖靠譜嗎 瀏覽:176
經營聖手伺服器怎麼調 瀏覽:749
arduino手機編程 瀏覽:481
西醫pdf下載 瀏覽:29
後浪電影學院pdf 瀏覽:813
程序員怎麼做到不被人嫉妒 瀏覽:669
cmd新建文件夾md命令 瀏覽:570
php數組中的數值排序 瀏覽:832
安卓手機怎麼避免小孩內購 瀏覽:171
聯想伺服器出現黃色嘆號怎麼辦 瀏覽:991
約翰編譯器製作教程 瀏覽:130
大地pdf 瀏覽:109
pdfplus 瀏覽:577
匯編O命令 瀏覽:970
plt轉pdf 瀏覽:365
魔獸60宏命令大全 瀏覽:479
php志願者網站源碼 瀏覽:875
貿易pdf 瀏覽:497
dbug命令 瀏覽:352