當一個鍵按下超過36ms,振蕩器使芯片激活,如果這個鍵按下且延遲大約108ms,這108ms發射代碼由一個起始碼(9ms),一個結果碼(4.5ms),低8位地址碼(9ms~18ms),高8位地址碼(9ms~18ms),8位數據碼(9ms~18ms)和這8位數據的反碼(9ms~18ms)組成。如果鍵按下超過108ms仍未松開,接下來發射的代碼(連發代碼)將僅由起始碼(9ms)和結束碼(2.5ms)組成。
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的結果碼完成后才能讀碼。
3.從上述兩點,我們可得到解碼程序的流程圖。
這樣接收到的僅僅是普通的代碼,要得到標準的鍵值,還必須進行代碼識別和代碼轉換,下面是從代碼接收到獲得標準值的子程。
KREM;與接收頭相連的I/O口
1AH,1BH,1CH,1DH;存放代碼的4個連續單元
YAO_KONG: CLR EA
JNB KREM,REMOT1
SJMP REM_BAK ;平時KREM為高電平,所以當KREM=1時,
;表示無鍵按下,應立即返回
REMOT1: JNB KREM,$ ;等待9ms的起始碼發送完
MOV R2,#32 ;32表示代碼共32位,也可以送24,這樣
;接收到的24位碼將不包括數據代碼的
;反代碼
;-----------------------------------------
;代碼接收
BYTE1: MOV R3,#250
BYTE2: MUL AB ;延時約6ms,可以稍長或稍短,但不能
;小于4.5ms,也不能太長。太長連擊時
;將影響程序運行速度
JNB KREM,BYTE3;
DJNZ R3,BYTE2 ;由于結果碼為4.5ms,如果小于4.5ms,
;結果碼未發送完,讀得的碼值將出錯
BYTE3: JNB KREM,$ ;等待高電平,保證讀每一位的起點一致
;-----------------------------------------------
MOV R3,#150
DJNZ R3,$ ;延時0.9ms,延時范圍為0.56ms~1.12ms
;----------------------------------------
MOV C,KREM
MOV R3,#4
MOV R0,#1DH
BYTE4: MOV A,@R0
RLC A
MOV @R0,A
DEC R0
DJNZ R3,BYTE4
DJNZ R2,BYTE1
;至此32位代碼已全部接收完成,并存放在1AH~1DH中,
;依次為低8位地址碼,高8位地址碼,8位數據碼,
;8位數據的反代碼
;----------------------------------------------------
;代碼識別
MOV A,1AH
XRL A,#03 ;3為地址低8位的值,對于不同的遙控器
;有不同的地址值
JNZ REM_BAK
MOV A,1BH
XRL A,#0FCH ;FCH為地址高8位的值
JNZ REM_BAK
MOV A,1CH
CPL A
XRL A,1DH ;如果地址碼不對或接收到的數據碼兩單元
;不反向均當錯碼,本程序當無鍵按下處理
JNZ REM_BAK
;--------------------------------------------
;代碼轉換
MOV R2,#21 ;21為遙控器面板按鍵數
MOV DPTR,#TAB_REMOT
LOOKUP_1: MOV A,R2
MOVC A,@A+DPTR
XRL A,1CH
JZ REM_BAK0
DJNZ R2,LOOPUP_1
REM_BAK0: MOV A,R2 ;R2中的值即為標準的鍵值
SJMP END_YK
REM_BAK: CLR A
END_YK: SETB EA
RET
;=====================================================================
;代碼轉換表,表中的值為面板上相應鍵的代碼
;對于不同的遙控器,表中的值應做相應的改變
TAB_REMOT:
DB 00H
; VCD DVD AUX TUNER ST/M TSV-4 6
DB 0C0H, 0D0H, 0E8H, 0F0H, 0E0H, 0C8H
; UP DOWN FM/AM MEMORY A/B 11
DB 00H, 20H, 48H, 68H, 58H
; 1 2 3 4 5 6 17
DB 0D8H, 0F8H, 40H, 60H, 50H, 70H
; AUTO VOL+ VOL- MUTE 21
DB 28H , 10H , 30H , 78H
;=================================================================
說明:此程序可在需要的地方任意調用(LCALL YA0_KONG),返回后,累加器中的值即為標準的鍵值,如果A=0則不予處理(可能原因有:無鍵按下,錯碼或非本機所用的遙控器的操作),程序中的延時均以4MHz的晶振為準,若用不同的晶振,只需改變相應值,符合注釋中的延時時間即可。
4. 從上述解碼過程我們不難發現,對于連發代碼,解碼得的值1AH~1DH全為0FFH,所以軟件如果需要處理連擊,我們只須在代碼識別前判斷1AH~1DH是否全為0FFH,是則有連擊現象,這樣建一個連擊標志,再返回,軟件根據這個標志,結合上一次讀得的鍵值便可進行相應的連擊操作,直到按鍵松開,連擊標志才被清除。具體操作如下:
在代碼識別前插入
MOV A,1AH
ANL A,1BH
ANL A,1CH
ANL A,1DH
XRL A,#0FFH
JNZ DAN_JI
SETB FLAG_LIANJI ;建連擊標志
SJMP END_YK
DAN_JI: NOP
另外子程的最后幾條指令改成
REM_BAK0: MOV A,R2
SJMP END_YK0
REM_BAK: CLRA
END_YK0: CLR FLAG_LIANJI ;清連擊標志
END_YK: SETB EA
四.應用實例
讀者也許會問,只要解得遙控器的代碼就可以了,轉換成1~n標準值有什么優點呢?看了后面的簡單實例,不難發現它有如下好處:
①. 在應用系統中,帶遙控器的儀器,一般都帶按鍵,而且二者功能相同,轉換成標準值后,遙控按鍵散轉表格可以與鍵盤散轉表格復用,這樣能節省一定的空間。
②. HT622 1/2最大可支持32或64個按鍵,一般系統只使用其中的一部分,這樣可能會使遙控器按鍵的代碼毫無規律,為了處理這樣的代碼,軟件人員要么想方設法通過復雜的算法找出那些代碼不是規律的規律,要么干脆不管那么多,排列一大堆“CJNE A,#DATA,NEXT”指令判斷,使鍵值判斷變得拖沓冗長。使用前述方法則清楚明了,簡單易行。
③. 對于不同的遙控器,本程序只要改變代碼轉換表即可,對再開發大有益處。
1.實例電路

程序清單及說明:
KREM EQU P0.0
L1 EQU P1.0
L2 EQU P1.1
L3 EQU P1.2
L4 EQU P1.3
L5 EQU P1.4
L6 EQU P1.5
L7 EQU P1.6
L8 EQU P1.7
L9 EQU P3.4
L10 EQU P3.5
L11 EQU P3.6
L12 EQU P2.0
L13 EQU P2.1
L14 EQU P2.2
L15 EQU P2.3
L16 EQU P2.4
L17 EQU P2.5
L18 EQU P2.6
L19 EQU P2.7
L20 EQU P0.6
L21 EQU P0.5
;-----------------------------------------
ORG 0000H
AJMP START0
ORG 0030H
START0: MOV SP,#60H
START: ACALL YAO_KONG ;調用解碼子程
JZ START
;----------------------------------------
RL A
MOV DPTR,#TAB_KEY
JMP @A+DPTR
;---------------------------------------
TAB_KEY: AJMP START
AJMP KEY1
AJMP KEY2
AJMP KEY3
AJMP KEY4
AJMP KEY5
AJMP KEY6
AJMP KEY7
AJMP KEY8
AJMP KEY9
AJMP KEY10
AJMP KEY11
AJMP KEY12
AJMP KEY13
AJMP KEY14
AJMP KEY15
AJMP KEY16
AJMP KEY17
AJMP KEY18
AJMP KEY19
AJMP KEY20
AJMP KEY21
;-------------------------------------
KEY1: ACALL CLEAR_IO
SETB L1
AJMP START
;-------------------------------------
KEY2: ACALL CLEAR_IO
SETB L2
AJMP START
;------------------------------------
KEY3: ACALL CLEAR_IO
SETB L3
AJMP START
;-----------------------------------
KEY4: ACALL CLEAR_IO
SETB L4
AJMP START
;----------------------------------
KEY5: ACALL CLEAR_IO
SETB L5
AJMP START
;----------------------------------
KEY6: ACALL CLEAR_IO
SETB L6
AJMP START
;----------------------------------
KEY7: ACALL CLEAR_IO
SETB L7
AJMP START
;----------------------------------
KEY8: ACALL CLEAR_IO
SETB L8
AJMP START
;----------------------------------
KEY9: ACALL CLEAR_IO
SETB L9
AJMP START
;----------------------------------
KEY10: ACALL CLEAR_IO
SETB L10
AJMP START
;----------------------------------
KEY11: ACALL CLEAR_IO
SETB L11
AJMP START
;----------------------------------
KEY12: ACALL CLEAR_IO
SETB L12
AJMP START
;----------------------------------
KEY13: ACALL CLEAR_IO
SETB L13
AJMP START
;----------------------------------
KEY14: ACALL CLEAR_IO
SETB L14
AJMP START
;----------------------------------
KEY15: ACALL CLEAR_IO
SETB L15
AJMP START
;----------------------------------
KEY16: ACALL CLEAR_IO
SETB L16
AJMP START
;----------------------------------
KEY17: ACALL CLEAR_IO
SETB L17
AJMP START
;----------------------------------
KEY18: ACALL CLEAR_IO
SETB L18
AJMP START
;----------------------------------
KEY19: ACALL CLEAR_IO
SETB L19
AJMP START
;----------------------------------
KEY20: ACALL CLEAR_IO
SETB L20
AJMP START
;----------------------------------
KEY21: ACALL CLEAR_IO
SETB L21
AJMP START
;----------------------------------
CLEAR_IO: MOV P0,#0
MOV P1,#0
MOV P2,#0
MOV P3,#0
RET
;------------------------------------
END
① 該程序是應用“HT6221解碼成標準鍵值”的典型例子。KEY1、KEY2……KEY21分別表示不同的功能模塊,也就是說根據解得的鍵值按照需要做具體的事。以示明顯,。這里分別用L1、L2……L21共21個發光管代替程序要做的事,當不同的鍵按下時,對應的發光管亮,其余的管均滅。
② 如果讀者有興趣,不防一試。需要注意的是,實驗前必須把你手上的遙控器的代碼填在代碼轉換表的相應位置,代碼的得來不難。在“代碼識別”前設一斷點,運行程序,按不同的鍵,程序運行到斷點停下時,“1CH”單元的內容即為當前按鍵的代碼。同時應該用1AH中的內容替換程序中的低8位地址“3”,1BH中的內容替換程序中高8位地址“0FCH”。如此做好后,便大功告成,這時有且只有你手上的遙控器可以控制發光管了。