;name: PT2221紅外解碼V1.0
;device: pt2221紅外編碼+89S51單片機解碼+紅外一體化接收頭
;Copyright (c) 2007-2008 張興電子設計工作室技術開發部
;author: 張興
;web: http://mcu.5d6d.com
;date: 2007.7.4---14:44
;description: ?PT2221發送的紅外編碼最前面為13.5ms的引導碼,而后為32位的數據,32位數據的前16位為用戶碼,
??;用于區別各個廠家的遙控器的不同,而后16位為數據碼,分前8位和后8位,前后8位互為反碼,用于檢驗
??;這里我們只接收了16位的數據,別的數據則丟掉了,對16的數據在程序中進行了檢驗
??;解碼的結果用兩種方式輸出:1.用串口以9600的波特率發送,2.四位一體數碼管顯示
??;一體化接P3.2,即外部中斷0
??;數碼管:P1口送段碼,P0口低四位送位碼
??;程序中采用11.0592M的晶振,若用12M晶振只需按程序注釋的提示選擇相應程序即可
;edition:V1.0
;***********************************************************************************************
?b_bit equ 20h ;數碼管個位數存放內存位置
?a_bit equ 21h ;數碼管十位數存放內存位置
?ORG 0000H
?AJMP MAIN;轉入主程序
?ORG 0003H ;外部中斷P3.2腳INT0入口地址
?AJMP INT ;轉入外部中斷服務子程序(解碼程序)
;=============以下為主程序進行CPU中斷方式設置===================================
MAIN:?SETB EA ;打開CPU總中斷請求
?SETB IT0 ;設定INT0的觸發方式為脈沖負邊沿觸發
?SETB EX0 ;打開INT0中斷請求
?AJMP $
;============以下為進入P3.2腳外部中斷子程序,也就是解碼程序======================
INT: ?CLR EA ;暫時關閉CPU的所有中斷請求,只處理當前中斷,避免受外部信號干擾
?MOV R6,#10
SB: ?ACALL YS1;調用882微秒延時子程序
?JB P3.2,EXIT;延時882微秒后判斷P3.2腳是否出現高電平如果有就退出解碼程序,(882um就出現高電平說明是干擾信號)
?DJNZ R6, SB;重復10次,目的是檢測在8820微秒內如果出現高電平就退出解碼程序
;=======以上完成對遙控信號的9ms的初始低電平信號的識別======================
?JNB P3.2, $ ;等待高電平避開9毫秒低電平引導脈沖
?ACALL YS2 ;延時4.74毫秒避開4.5毫秒的結果碼
?MOV R7,#16;忽略前16位系統識別碼,PT2221共發送32位數據,前16位為用戶碼,后16為數據碼才是我們需要的
JJJJA:?JNB P3.2,$;等待地址碼第一位的高電平信號
?LCALL YS1;高電平開始后用882微秒的時間尺去判斷信號此時的高低電平狀態
?MOV C,P3.2;將P3.2引腳此時的電平狀態0或1存入C中
?JNC UUUA;如果為0就跳轉到UUUA
?LCALL YS3;檢測到高電平1的話延時1毫秒等待脈沖高電平結束
UUUA: ?DJNZ R7,JJJJA
;==============到此為止,已跳過13.5ms的引導碼和前16位的用戶碼=====================
?MOV R1,#1AH ;設定1AH為起始RAM區
?MOV R2,#2?;接收從1AH到1BH的2個內存,用于存放操作碼和操作反碼,
???;16位數據分前8位和后8位,后8位是前8位的反碼,用于檢驗
PP: ?MOV R3,#8;每組數據為8位
JJJJ: ?JNB P3.2,$;等待地址碼第一位的高電平信號
?LCALL YS1;高電平開始后用882微秒的時間尺去判斷信號此時的高低電平狀態
?MOV C,P3.2;將P3.2引腳此時的電平狀態0或1存入C中
?JNC UUU;如果為0就跳轉到UUU
?LCALL YS3;檢測到高電平1的話延時1毫秒等待脈沖高電平結束,然后把C中的1存入R1
UUU: ?MOV A,@R1;將R1中的數據給A
?RRC A;將C中的值0或1移入A中的最低位
?MOV @R1,A;將A中的數暫時存放在R1數值的內存中
?DJNZ R3,JJJJ;接收滿8位換一個內存
?INC R1;對R1中的值加1,換下一個RAM
?DJNZ R2,PP ;接收完8位數據碼和8位數據反碼,存放在1AH/1BH中
;==================上面的程序已完成了16位數據碼的接收工作,下面進行檢驗==================
?MOV A,1AH
?CPL A;對1AH取反后和1BH比較
?CJNE A,1BH,EXIT;如果不等表示接收數據發生錯誤,放棄
;====================校驗正確則繼續執行下面程序,不正確則作為干擾丟棄===================
?LCALL SEND?;調用串口發送程序,把16位數據碼用串口發送出去
?LCALL DISPLAY?;把16位數據碼送數碼管顯示
?CLR P3.5;P3.5口上的LED閃爍一次,表示解碼成功
?LCALL YS2
?LCALL YS2
?LCALL YS2
?SETB P3.5;
;==================退出子程序,解碼出錯時退出解碼子程序========================
EXIT: ?SETB EA ;允許中斷
?RETI ;退出解碼子程序
;===================串口發送子程序============================================
SEND:?mov a,1AH;將1AH中的十六進制數轉換成16進制
?mov b,#16 ;10進制/16=16進制,此時輸出按鍵的16進制編碼,00~1F
?div ab
?SWAP A
?ADD A,B
?mov 30H,a?;轉換為16進制代碼后存到30H
?MOV TMOD,#20H
?MOV TL1,#0FDH
?MOV TH1,#0FDH
?MOV SCON,#40H
?MOV PCON,0
?CLR TI
?CLR RI
?SETB TR1
?MOV R0,#30H
?MOV A,@R0
?MOV SBUF,A
WAIT:?JNB TI,WAIT
?CLR TI
?RET
;******************************************顯示子程序********************************************
display:mov a,1AH;將1AH中的十六進制數轉換成10進制或16進制
?mov b,#10 ;10進制/10=10進制,此時輸出按鍵對應的鍵號,00~31
?;mov b,#16 ;10進制/16=16進制,此時輸出按鍵的16進制編碼,00~1F
?div ab
?mov a_bit,a ;十位在a
?mov b_bit,b ;個位在b
?mov dptr,#numtab ;指定查表啟始地址
?mov r0,#4
dpl1: ?mov r1,#250 ;顯示1000次
dplop: ?mov a,b_bit ;取個位數
?MOVC A,@A+DPTR ;查個位數的7段代碼
?mov p1,a ;送出個位的7段代碼
?SETB p0.0 ;開個位顯示
?acall d1ms ;顯示1ms
?CLR P0.0
?mov a,a_bit ;取十位數
?MOVC A,@A+DPTR ;查十位數的7段代碼
?mov p1,a ;送出十位的7段代碼
?SETB P0.1 ;開十位顯示
?acall d1ms ;顯示1ms
?CLR P0.1
?CLR P0.2
?CLR P0.3
?djnz r1,dplop ;100次沒完循環
?djnz r0,dpl1 ;4個100次沒完循環
?ret
D1MS:?MOV R4,#250?????? ;延時1ms
????? ?DJNZ R4,$
????? ?RET???????????????????????????????
numtab:?DB?3FH,06H,5BH,4FH,66H,6DH,7DH,07H? ;字形碼表"0","1","2"~"7"
?DB?7FH,6FH,77H,7CH,39H,5EH,79H,71H? ;字形碼表"8","9","A"~"F"
;=============延時子程序1,精確延時882微秒=========================================
;YS1: ?MOV R4,#20 ;12M晶振請用此句延時
YS1: ?MOV R4,#17 ;11.0592M晶振請用此句延時
D1: ?MOV R5,#20
?DJNZ R5,$
?DJNZ R4,D1
?RET
;============延時子程序2,精確延時4740微秒==========================================
YS2: ?MOV R4,#10 ;
;D2: ?MOV R5,#235?;12M晶振請用此句延時
D2: ?MOV R5,#217?;11.0592M晶振請用此句延時
?DJNZ R5,$
?DJNZ R4,D2
?RET
;=============延時程序3,精確延時1000微秒===========================================
YS3: ?MOV R4,#2;
;D3:?MOV R5,#248?;12M晶振請用此句延時
D3:?MOV R5,#230?;11.0592M晶振請用此句延時
?DJNZ R5,$
?DJNZ R4,D3
?RET
;=========================
?END
;device: pt2221紅外編碼+89S51單片機解碼+紅外一體化接收頭
;Copyright (c) 2007-2008 張興電子設計工作室技術開發部
;author: 張興
;web: http://mcu.5d6d.com
;date: 2007.7.4---14:44
;description: ?PT2221發送的紅外編碼最前面為13.5ms的引導碼,而后為32位的數據,32位數據的前16位為用戶碼,
??;用于區別各個廠家的遙控器的不同,而后16位為數據碼,分前8位和后8位,前后8位互為反碼,用于檢驗
??;這里我們只接收了16位的數據,別的數據則丟掉了,對16的數據在程序中進行了檢驗
??;解碼的結果用兩種方式輸出:1.用串口以9600的波特率發送,2.四位一體數碼管顯示
??;一體化接P3.2,即外部中斷0
??;數碼管:P1口送段碼,P0口低四位送位碼
??;程序中采用11.0592M的晶振,若用12M晶振只需按程序注釋的提示選擇相應程序即可
;edition:V1.0
;***********************************************************************************************
?b_bit equ 20h ;數碼管個位數存放內存位置
?a_bit equ 21h ;數碼管十位數存放內存位置
?ORG 0000H
?AJMP MAIN;轉入主程序
?ORG 0003H ;外部中斷P3.2腳INT0入口地址
?AJMP INT ;轉入外部中斷服務子程序(解碼程序)
;=============以下為主程序進行CPU中斷方式設置===================================
MAIN:?SETB EA ;打開CPU總中斷請求
?SETB IT0 ;設定INT0的觸發方式為脈沖負邊沿觸發
?SETB EX0 ;打開INT0中斷請求
?AJMP $
;============以下為進入P3.2腳外部中斷子程序,也就是解碼程序======================
INT: ?CLR EA ;暫時關閉CPU的所有中斷請求,只處理當前中斷,避免受外部信號干擾
?MOV R6,#10
SB: ?ACALL YS1;調用882微秒延時子程序
?JB P3.2,EXIT;延時882微秒后判斷P3.2腳是否出現高電平如果有就退出解碼程序,(882um就出現高電平說明是干擾信號)
?DJNZ R6, SB;重復10次,目的是檢測在8820微秒內如果出現高電平就退出解碼程序
;=======以上完成對遙控信號的9ms的初始低電平信號的識別======================
?JNB P3.2, $ ;等待高電平避開9毫秒低電平引導脈沖
?ACALL YS2 ;延時4.74毫秒避開4.5毫秒的結果碼
?MOV R7,#16;忽略前16位系統識別碼,PT2221共發送32位數據,前16位為用戶碼,后16為數據碼才是我們需要的
JJJJA:?JNB P3.2,$;等待地址碼第一位的高電平信號
?LCALL YS1;高電平開始后用882微秒的時間尺去判斷信號此時的高低電平狀態
?MOV C,P3.2;將P3.2引腳此時的電平狀態0或1存入C中
?JNC UUUA;如果為0就跳轉到UUUA
?LCALL YS3;檢測到高電平1的話延時1毫秒等待脈沖高電平結束
UUUA: ?DJNZ R7,JJJJA
;==============到此為止,已跳過13.5ms的引導碼和前16位的用戶碼=====================
?MOV R1,#1AH ;設定1AH為起始RAM區
?MOV R2,#2?;接收從1AH到1BH的2個內存,用于存放操作碼和操作反碼,
???;16位數據分前8位和后8位,后8位是前8位的反碼,用于檢驗
PP: ?MOV R3,#8;每組數據為8位
JJJJ: ?JNB P3.2,$;等待地址碼第一位的高電平信號
?LCALL YS1;高電平開始后用882微秒的時間尺去判斷信號此時的高低電平狀態
?MOV C,P3.2;將P3.2引腳此時的電平狀態0或1存入C中
?JNC UUU;如果為0就跳轉到UUU
?LCALL YS3;檢測到高電平1的話延時1毫秒等待脈沖高電平結束,然后把C中的1存入R1
UUU: ?MOV A,@R1;將R1中的數據給A
?RRC A;將C中的值0或1移入A中的最低位
?MOV @R1,A;將A中的數暫時存放在R1數值的內存中
?DJNZ R3,JJJJ;接收滿8位換一個內存
?INC R1;對R1中的值加1,換下一個RAM
?DJNZ R2,PP ;接收完8位數據碼和8位數據反碼,存放在1AH/1BH中
;==================上面的程序已完成了16位數據碼的接收工作,下面進行檢驗==================
?MOV A,1AH
?CPL A;對1AH取反后和1BH比較
?CJNE A,1BH,EXIT;如果不等表示接收數據發生錯誤,放棄
;====================校驗正確則繼續執行下面程序,不正確則作為干擾丟棄===================
?LCALL SEND?;調用串口發送程序,把16位數據碼用串口發送出去
?LCALL DISPLAY?;把16位數據碼送數碼管顯示
?CLR P3.5;P3.5口上的LED閃爍一次,表示解碼成功
?LCALL YS2
?LCALL YS2
?LCALL YS2
?SETB P3.5;
;==================退出子程序,解碼出錯時退出解碼子程序========================
EXIT: ?SETB EA ;允許中斷
?RETI ;退出解碼子程序
;===================串口發送子程序============================================
SEND:?mov a,1AH;將1AH中的十六進制數轉換成16進制
?mov b,#16 ;10進制/16=16進制,此時輸出按鍵的16進制編碼,00~1F
?div ab
?SWAP A
?ADD A,B
?mov 30H,a?;轉換為16進制代碼后存到30H
?MOV TMOD,#20H
?MOV TL1,#0FDH
?MOV TH1,#0FDH
?MOV SCON,#40H
?MOV PCON,0
?CLR TI
?CLR RI
?SETB TR1
?MOV R0,#30H
?MOV A,@R0
?MOV SBUF,A
WAIT:?JNB TI,WAIT
?CLR TI
?RET
;******************************************顯示子程序********************************************
display:mov a,1AH;將1AH中的十六進制數轉換成10進制或16進制
?mov b,#10 ;10進制/10=10進制,此時輸出按鍵對應的鍵號,00~31
?;mov b,#16 ;10進制/16=16進制,此時輸出按鍵的16進制編碼,00~1F
?div ab
?mov a_bit,a ;十位在a
?mov b_bit,b ;個位在b
?mov dptr,#numtab ;指定查表啟始地址
?mov r0,#4
dpl1: ?mov r1,#250 ;顯示1000次
dplop: ?mov a,b_bit ;取個位數
?MOVC A,@A+DPTR ;查個位數的7段代碼
?mov p1,a ;送出個位的7段代碼
?SETB p0.0 ;開個位顯示
?acall d1ms ;顯示1ms
?CLR P0.0
?mov a,a_bit ;取十位數
?MOVC A,@A+DPTR ;查十位數的7段代碼
?mov p1,a ;送出十位的7段代碼
?SETB P0.1 ;開十位顯示
?acall d1ms ;顯示1ms
?CLR P0.1
?CLR P0.2
?CLR P0.3
?djnz r1,dplop ;100次沒完循環
?djnz r0,dpl1 ;4個100次沒完循環
?ret
D1MS:?MOV R4,#250?????? ;延時1ms
????? ?DJNZ R4,$
????? ?RET???????????????????????????????
numtab:?DB?3FH,06H,5BH,4FH,66H,6DH,7DH,07H? ;字形碼表"0","1","2"~"7"
?DB?7FH,6FH,77H,7CH,39H,5EH,79H,71H? ;字形碼表"8","9","A"~"F"
;=============延時子程序1,精確延時882微秒=========================================
;YS1: ?MOV R4,#20 ;12M晶振請用此句延時
YS1: ?MOV R4,#17 ;11.0592M晶振請用此句延時
D1: ?MOV R5,#20
?DJNZ R5,$
?DJNZ R4,D1
?RET
;============延時子程序2,精確延時4740微秒==========================================
YS2: ?MOV R4,#10 ;
;D2: ?MOV R5,#235?;12M晶振請用此句延時
D2: ?MOV R5,#217?;11.0592M晶振請用此句延時
?DJNZ R5,$
?DJNZ R4,D2
?RET
;=============延時程序3,精確延時1000微秒===========================================
YS3: ?MOV R4,#2;
;D3:?MOV R5,#248?;12M晶振請用此句延時
D3:?MOV R5,#230?;11.0592M晶振請用此句延時
?DJNZ R5,$
?DJNZ R4,D3
?RET
;=========================
?END
評論
查看更多