機(jī)電之家資源網(wǎng)
單片機(jī)首頁|單片機(jī)基礎(chǔ)|單片機(jī)應(yīng)用|單片機(jī)開發(fā)|單片機(jī)文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發(fā)
培訓(xùn)信息
贊助商
紅外遙控的C程序
紅外遙控的C程序
 更新時(shí)間:2010-1-29 16:44:08  點(diǎn)擊數(shù):0
【字體: 字體顏色

紅外遙控在生產(chǎn)和生活中應(yīng)用越來越廣泛,不同的紅外遙控芯片有不同的發(fā)碼協(xié)議,但一般都是由引導(dǎo)碼,系統(tǒng)碼,鍵碼三部分組成.

引導(dǎo)碼是告訴接收機(jī)準(zhǔn)備接收紅外遙控碼.系統(tǒng)碼是識別碼,不同的遙控芯片有不同的誤別碼,以免搞錯(cuò).

遙控器上不同的按鍵有不同的鍵碼,系統(tǒng)碼和鍵碼都是16位碼,8位正碼,8位反碼.如SC6122的系統(tǒng)碼是FF00,FF和00互為反碼,鍵碼1為

EF10也是互為反碼.關(guān)于SC6122的資料在我們的網(wǎng)頁資料下載上有.

SC6122的引導(dǎo)碼為低電平為9000微秒,高電平為4500微秒.當(dāng)然高電平不可能精確為9000微秒,在8000微秒到10000微秒都看作是正常范圍,

低電平在4000-5000之間都看作是正常范圍.

引導(dǎo)碼后的32位編碼(16位系統(tǒng)碼和16位鍵碼)不管高低電平,載波時(shí)間都是560微秒,但低電平持續(xù)時(shí)間是1125微秒,高電平持續(xù)時(shí)間是2250

微秒,所以低電平除去載波時(shí)間大約是560微秒,高電平除去載波時(shí)間大約是1680微秒.低電平也有一個(gè)波動(dòng)范圍,在400-700之間都看作是正常

的,具體多少可以通過示波器測量出來.高電平也有一個(gè)波動(dòng)范圍,在400-2000之間都看作是正常的,具體多少也是根據(jù)經(jīng)驗(yàn).當(dāng)然范圍越寬,捕

捉紅外線的范圍也越寬,越精確.在捕捉到有高低電平之間,在560-1680之間取一個(gè)中間值1120微秒,認(rèn)為小于1120微秒是低電平,大于1120微

秒是高電平.

下面有兩個(gè)經(jīng)過實(shí)踐能在實(shí)驗(yàn)板上顯示鍵碼的程序,一個(gè)是匯編寫的,一個(gè)是用C寫的,與大家一起探討遙控器.

以下程序能在LCD上顯示系統(tǒng)碼和鍵碼,按不同的按鍵,系統(tǒng)碼不變,變的是鍵碼.有不懂的地方可以在留言本上留言.

RS EQU P2.5                 ;這幾個(gè)是LCD引腳.
RW EQU P2.6
E EQU P2.7

IRR EQU P3.3                ;紅外接收的輸出接P3.3.

BUF EQU 30H ;30H-33H保存解碼結(jié)果


;=============================================
ORG 0000H
AJMP MAIN

;=============================================
ORG 0030H
MAIN:
MOV SP,#70H ;堆棧指針設(shè)到70H的地方

ACALL INIT_LCD                                    ;初始化LCD

MOV R7,#10
ACALL DELAY_MS

MOV DPTR,#MSG1
CALL DISPLAY_LINE1                        ;在第一行顯示 Test8: IR Reader
MOV DPTR,#MSG2
CALL DISPLAY_LINE2                        ;在第二行顯示www.mcuedu.com 


MAIN_LOOP:
JB IRR,$ ;等待接收頭信號為低
ACALL GET_LOW ;測量引導(dǎo)脈沖低電平
CLR C
MOV A,R7
SUBB A,#(8000/50) ;SC6122的引導(dǎo)脈沖低電平為9000US,我們只要測到低電平的值在8000-10000US范圍內(nèi)就認(rèn)為合格的.
JC MAIN_LOOP ;如果小于8000US,不對,重新等待接收

CLR C
MOV A,R7
SUBB A,#(10000/50)
JNC MAIN_LOOP

ACALL GET_HIGH ;測量引導(dǎo)脈沖高電平
CLR C
MOV A,R7
SUBB A,#(4000/50)
JC MAIN_LOOP                    ;如果小于4000US,不對,重新等待接收

CLR C
MOV A,R7
SUBB A,#(5000/50)
JNC MAIN_LOOP                        ;如果大于5000US,不對,重新等待接收


MOV R0,#BUF ;

MOV R5,#8 ;SC6122發(fā)的碼有32位,我們用4個(gè)字節(jié)來存放,每個(gè)字節(jié)有8位

IR_NEXT:

CALL GET_LOW

CLR C
MOV A,R7
SUBB A,#(300/50) ;300US
JC MAIN_LOOP                                ;低電平小于300微秒認(rèn)為不對,重新接收

CLR C
MOV A,R7
SUBB A,#(800/50) ;800US
JNC MAIN_LOOP                                ;低電平大于800微秒認(rèn)為不對,重新接收


ACALL GET_HIGH
CLR C
MOV A,R7
SUBB A,#(300/50) ;300US
JC MAIN_LOOP                                ;高電平小于300微秒認(rèn)為不對,重新接收

CLR C
MOV A,R7
SUBB A,#(2000/50) ;2000US
JNC MAIN_LOOP                                     ;高電平大于2000微秒認(rèn)為不對,重新接收


CLR C
MOV A,R7
SUBB A,#(1120/50) ;                            ;跟中間值1120進(jìn)行比較


RRC A
MOV @R0,A                                    ;通過CY移到間接地址R0中去
DJNZ R5,IR_NEXT                                    ;8位移完了嗎
MOV R5,#8
INC R0
MOV A,R0
XRL A,#(BUF+4)
JNZ IR_NEXT ;如果不到4個(gè)字節(jié),接收下一個(gè)


MOV DPTR,#MSG_6122
ACALL DISPLAY_LINE1 ;顯示格式名稱

ACALL DISPLAY_IR_CODE ;顯示碼


AJMP MAIN_LOOP
;============================================
MSG1: DB " Test8: IR Reader "
MSG2: DB " MSG_6122: DB " Format: SC6122 "
;============================================

;轉(zhuǎn)為ASCII碼在LCD在顯示
TO_ASCII:
CJNE A,#0AH,TO_ASCII_1
TO_ASCII_1:
JC TO_ASCII_2 ;小于10
ADD A,#('A'-10)
RET
TO_ASCII_2:
ADD A,#'0'
RET
;============================================
DISPLAY_IR_CODE:
MOV A,#0C0H ;顯示在第二行
ACALL SEND_COMMAND_BYTE ;設(shè)置DDRAM地址

MOV R0,#BUF
DISPLAY_IR_CODE_NEXT:
MOV A,@R0
SWAP A
ANL A,#0FH                            ;分離出高字節(jié)
ACALL TO_ASCII                                ;轉(zhuǎn)為ASCII碼
ACALL SEND_DATA_BYTE                             ;顯示
MOV A,@R0
ANL A,#0FH                            ;分離出低字節(jié)
ACALL TO_ASCII                                 ;轉(zhuǎn)為ASCII碼
ACALL SEND_DATA_BYTE                            ;顯示
MOV A,#' '
ACALL SEND_DATA_BYTE                                ;顯示空格

INC R0
MOV A,R0
XRL A,#(BUF+4)
JNZ DISPLAY_IR_CODE_NEXT

MOV R0,#8 ;第2行共有20個(gè)字符,前面顯示用了12個(gè),再用8個(gè)空格填滿
DISPLAY_IR_CODE_B:
MOV A,#' '
ACALL SEND_DATA_BYTE
DJNZ R0,DISPLAY_IR_CODE_B

RET


;============================================
;測量低電平時(shí)間,50US采樣一次,R7加1一次,比如低電平時(shí)間為9000US,測得R7的結(jié)果為180(0B4H)
;OUTPUT: R7
GET_LOW:
MOV R7,#00H

GET_LOW_NEXT:
MOV R6,#20 ;在晶振為11.0592M時(shí),延50US需要46個(gè)機(jī)器周期,
DJNZ R6,$ ;這條指令執(zhí)行需要2個(gè)機(jī)器周期

JB IRR,GET_LOW_RTN ;接收頭為高電平,結(jié)束測量
INC R7
MOV A,R7
JNZ GET_LOW_NEXT ;看R7是否有溢出

GET_LOW_RTN:
RET
;============================================
;測量高電平時(shí)間,50US采樣一次,R7加1一次,比如高電平時(shí)間為4500US,測得R7的結(jié)果為90
;OUTPUT: R7
GET_HIGH:
MOV R7,#00H

GET_HIGH_NEXT:
MOV R6,#20 ;在晶振為11.0592M時(shí),延50US需要46個(gè)機(jī)器周期,
DJNZ R6,$ ;這條指令執(zhí)行需要2個(gè)機(jī)器周期

JNB IRR,GET_HIGH_RTN ;接收頭為低電平,結(jié)束測量
INC R7
MOV A,R7
JNZ GET_HIGH_NEXT ;看R7是否有溢出

GET_HIGH_RTN:
RET
;============================================
;============================================

DELAY_MS:
MOV R6,#250
DELAY_MS_NEXT:
NOP
NOP
DJNZ R6,DELAY_MS_NEXT
DJNZ R7,DELAY_MS
RET
;============================================
;INPUT: R7
DELAY:
DJNZ R7,$
RET
;============================================
;向LCD寫一個(gè)命令字節(jié)
;INPUT: ACC
SEND_COMMAND_BYTE:
CLR RS
CLR RW

MOV P0,A

SETB E
NOP
NOP
NOP
NOP
NOP
NOP
CLR E

MOV R7,#100
ACALL DELAY
RET
;===============================================
;向LCD寫一個(gè)數(shù)據(jù)字節(jié)
;INPUT: ACC
SEND_DATA_BYTE:
SETB RS
CLR RW

MOV P0,A

SETB E
NOP
NOP
NOP
NOP
NOP
NOP
CLR E

MOV R7,#100
ACALL DELAY
RET
;======================================================
;初始化LCD
INIT_LCD:
MOV A,#30H
ACALL SEND_COMMAND_BYTE
ACALL SEND_COMMAND_BYTE
ACALL SEND_COMMAND_BYTE
MOV A,#38H ;設(shè)置工作方式
ACALL SEND_COMMAND_BYTE
MOV A,#0CH ;顯示狀態(tài)設(shè)置
ACALL SEND_COMMAND_BYTE
MOV A,#01H ;清屏
ACALL SEND_COMMAND_BYTE
MOV A,#06H ;輸入方式設(shè)置
ACALL SEND_COMMAND_BYTE
RET
;=======================================================
;在第一行顯示
;INPUT: DPTR指向要顯示的內(nèi)容
DISPLAY_LINE1:
MOV A,#080H
DISPLAY_LINE1_A:
ACALL SEND_COMMAND_BYTE ;設(shè)置DDRAM地址
MOV R6,#20
DISPLAY_LINE1_NEXT:
CLR A
MOVC A,@A+DPTR
ACALL SEND_DATA_BYTE
INC DPTR
DJNZ R6,DISPLAY_LINE1_NEXT
MOV R7,#100
ACALL DELAY
RET
;=======================================================
;在第二行顯示
;INPUT: DPTR指向要顯示的內(nèi)容
DISPLAY_LINE2:
MOV A,#0C0H
AJMP DISPLAY_LINE1_A
;=======================================================

END

下面是一個(gè)用C寫的遙控器程序.能在數(shù)碼管上顯示鍵碼.

#include <reg52.h>

#define c(x) (x*110592/120000)

sbit Ir_Pin=P3^3;

unsigned char code Led_Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,
0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};                        //共陽極數(shù)碼顯示碼0-F.
unsigned char code Led_Sel[]={0xe,0xd,0xb,0x7};

unsigned char Led_Buf[4]; //顯示緩沖區(qū)
char Led_Index;                   //位選        

unsigned char Ir_Buf[4]; //用于保存解碼結(jié)果

//==============================================================
//數(shù)碼管掃描
timer0() interrupt 1 using 1
{
TL0=65536-1000;
TH0=(65536-1000)/256; //定時(shí)器0設(shè)定約1000us中斷一次,用于數(shù)碼管掃描
P0=0xff;
P2=Led_Sel[Led_Index];                            //位選
P0=Led_Tab[Led_Buf[Led_Index]];                    //段選

if(++Led_Index>3) Led_Index=0;                    //四個(gè)掃描完了,到第一個(gè)數(shù)碼管
}
//==============================================================
unsigned int Ir_Get_Low()
{
TL1=0;
TH1=0;
TR1=1;
while(!Ir_Pin && (TH1&0x80)==0);               
TR1=0;          
return TH1*256+TL1;
}
//=============================================================
unsigned int Ir_Get_High()
{
TL1=0;
TH1=0;
TR1=1;
while(Ir_Pin && (TH1&0x80)==0);
TR1=0;
return TH1*256+TL1;
}
//==============================================================
main()
{
unsigned int temp;
char i,j;
Led_Index=1;

TMOD=0x11;
TL0=65536-1000;
TH0=(65536-1000)/256; //定時(shí)器0設(shè)定約1000us中斷一次,用于數(shù)碼管掃描
EA=1;
ET0=1;
TR0=1;

Led_Buf[0]=0;
Led_Buf[1]=0;
Led_Buf[2]=0;
Led_Buf[3]=0; //顯示區(qū)設(shè)成0

do{
restart:
while(Ir_Pin);
temp=Ir_Get_Low();
if(temp<c(8500) || temp>c(9500)) continue;//引導(dǎo)脈沖低電平9000
temp=Ir_Get_High();
if(temp<c(4000) || temp>c(5000)) continue;//引導(dǎo)脈沖高電平4500
for(i=0;i<4;i++) //4個(gè)字節(jié)
for(j=0;j<8;j++) //每個(gè)字節(jié)8位
{
temp=Ir_Get_Low();
if(temp<c(200) || temp>c(800)) goto restart;
temp=Ir_Get_High();
if(temp<c(200) || temp>c(2000)) goto restart;
Ir_Buf[i]>>=1;
if(temp>c(1120)) Ir_Buf[i]|=0x80;
}
Led_Buf[0]=Ir_Buf[2]&0xf;
Led_Buf[1]=(Ir_Buf[2]/16)&0xf;
Led_Buf[2]=Ir_Buf[3]&0xf;
Led_Buf[3]=(Ir_Buf[3]/16)&0xf; //顯示結(jié)果
}while(1);
}


  • 上一篇: 實(shí)現(xiàn)存儲器EEPROM AT24C02的數(shù)據(jù)讀寫操作
  • 下一篇: 沒有了
  • 發(fā)表評論   告訴好友   打印此文  收藏此頁  關(guān)閉窗口  返回頂部
    熱點(diǎn)文章
     
    推薦文章
     
    相關(guān)文章
    網(wǎng)友評論:(只顯示最新5條。)
    關(guān)于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機(jī)電之家 | 會(huì)員助手 | 免費(fèi)鏈接

    點(diǎn)擊這里給我發(fā)消息66821730(技術(shù)支持)點(diǎn)擊這里給我發(fā)消息66821730(廣告投放) 點(diǎn)擊這里給我發(fā)消息41031197(編輯) 點(diǎn)擊這里給我發(fā)消息58733127(審核)
    本站提供的機(jī)電設(shè)備,機(jī)電供求等信息由機(jī)電企業(yè)自行提供,該企業(yè)負(fù)責(zé)信息內(nèi)容的真實(shí)性、準(zhǔn)確性和合法性。
    機(jī)電之家對此不承擔(dān)任何保證責(zé)任,有侵犯您利益的地方請聯(lián)系機(jī)電之家,機(jī)電之家將及時(shí)作出處理。
    Copyright 2007 機(jī)電之家 Inc All Rights Reserved.機(jī)電之家-由機(jī)電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術(shù)支持

    主辦:杭州市高新區(qū)(濱江)機(jī)電一體化學(xué)會(huì)
    中國行業(yè)電子商務(wù)100強(qiáng)網(wǎng)站

    網(wǎng)站經(jīng)營許可證:浙B2-20080178-1