
51黑電子論壇(網(wǎng)址:51hei.com)精選文章:
以前在論壇都持觀望態(tài)度,今天第一次發(fā)帖,希望對大家有所幫助!因本人對匯編語言情有獨鐘,所以本程序用匯編語言編寫,經(jīng)過測試,MP3和電視機的遙控都能學習對鍵成功,其他遙控因為手頭沒有,所以不敢保證全部支持!P1口作為輸出口,我分別接了8個燈做指示,如果連上8路繼電器,就可紅外控制8路電器的工作,雖然紅外遙控受遙控距離及方向的影響用起來不夠順心,但在房間里是完全夠用了的!紅外接收頭接P3.7腳;8個學習鍵是利用P3.0和P3.1輪流輸出低電平與P3.2/3.3/3.4/3.5形成2*4矩陣鍵盤。短按按鍵可分別手動控制輸出端;長按某鍵5秒左右則進入學習模式,相應輸出端的指示燈亮起(學習指示燈與輸出指示燈復用,其實學習模式應該是閃爍狀態(tài),但我沒寫這方面的程序,有需要的自己加進去?。?,在5秒內(nèi)用遙控器對著接收頭按一次遙控的一個鍵(隨自己愛好),學習指示燈熄滅,學習成功!如果要刪除遙控鍵,則長按按鍵至學習模式后不按遙控器,5秒后學習指示燈熄滅,原來學習的遙控鍵數(shù)據(jù)被刪除,遙控器不能再控制這一路輸出,有需要了再重新學習此路!下面曬幾張我自制的實驗板: 圖片壓縮了,不然發(fā)不上來?。?!——板子可插紅外接收頭、315M無線發(fā)射/接收模塊?。。?br>(1)、插紅外接收頭:

(2)、背面連接線路:

(3)、插315M無線接收模塊:

(4)、插315M無線發(fā)射模塊:

程序更新...: 因之前發(fā)布的程序還存在小Bug,正好今天有空,就把最新的程序貼上來吧!此次更新主要解決以下問題:按某個鍵后5S內(nèi)再按另外一個鍵會誤判斷進入第二個鍵的學習模式...(在按鍵掃描部分加了一些處理動作) 好了,不多說,看程序吧:
;;;STC12C2052/STC12C56**學習型紅外遙控8路繼電器 ;;;內(nèi)部RC振蕩器約6MHz;;; ;;;寫EEPROM數(shù)據(jù)不能調(diào)公共的'寫',所以每1路的學習模式里 ;;;都要重復寫一堆相同的程序,感覺有點浪費空間了,郁悶ing... ;;;修改日期2015/10/10;;;
;---------------------- ISP_DATA EQU 0E2H ;定義EEPROM相關(guān)寄存器 ISP_ADDRH EQU 0E3H ;此類寄存器地址需參考所用單片機的手冊來設(shè)置 ISP_ADDRL EQU 0E4H ;STC12C2052和56**系列的地址是E2H~E7H ISP_CMD EQU 0E5H ISP_TRIG EQU 0E6H ISP_CONTR EQU 0E7H
;---------------------- AUXR EQU 08EH ;定時器1T/12T時鐘模式控制 IRCOM EQU 20H ;RAM中接收到的鍵值起始存放地址(20H-23H) Z EQU 00H ;長按標志位 X EQU 01H ;接收完成標志位 D EQU 02H ;學習模式標志位 IRIN EQU P3.7 ;紅外接收頭 K1 EQU P3.2 ;學習鍵 (P3.0與P3.1輪流輸出0) K2 EQU P3.3 ;學習鍵 (實現(xiàn)2*4矩陣鍵盤) K3 EQU P3.4 ;學習鍵 K4 EQU P3.5 ;學習鍵 LED8 EQU P1.0 ;OUT8 LED7 EQU P1.1 ;OUT7 LED6 EQU P1.2 ;OUT6 LED5 EQU P1.3 ;OUT5 LED4 EQU P1.4 ;OUT4 LED3 EQU P1.5 ;OUT3 LED2 EQU P1.6 ;OUT2 LED1 EQU P1.7 ;OUT1
;---------------------- ORG 0000H LJMP START ;跳初始化 ORG 000BH LJMP T0INT ;T0中斷服務(wù)子程序入口 ORG 0030H
;---------------------- START: MOV SP,#5FH MOV R0,#20H LP0: MOV @R0,#00H ;20H-43H清零 INC R0 CJNE R0,#44H,LP0 MOV P3,#0FFH ;P3口置1 MOV AUXR,00H ;T0/12T時鐘模式 MOV TMOD,#01H ;定時器工作模式1(16位) SETB EA ;開總中斷EA SETB ET0 ;開T0中斷ET0 CLR Z CLR X CLR D
;----------------------- MAIN: ;主程序 ACALL IR_IN ACALL KEYP30 ;矩陣鍵盤掃描 ACALL KEYP31 ;矩陣鍵盤掃描 AJMP MAIN
;----------------------- ;(紅外接收譯碼) ;----------------------- IR_IN: JNB IRIN,I2 ;等待 IR 信號出現(xiàn),IRIN=0則跳到I2 AJMP IEND ;如果沒有接收到紅外信號則先跳出
I2: MOV R1,#30 I20: ACALL DEL DJNZ R1,I20 ;延時去抖動 JB IRIN,IR_IN ;確認IR信號,去抖動后IRIN仍為0則往下執(zhí)行 I21: JB IRIN,I3 ;持續(xù)4.5mS的低電平,等IRIN為1后跳到I3 AJMP I21 ;此處循環(huán)等待高電平的到來
I3: MOV R0,#IRCOM MOV R3,#0 ;8位計數(shù)器清0 LL: JNB IRIN,I4 ;持續(xù)4.5mS的高電平,等IRIN為0后跳到I4 AJMP LL ;此處循環(huán)等待低電平的到來 ;;;;;以上I1-I3程序完成引導碼的確認(4.5mS低電平+4.5mS高電平);;;;;
I4: JB IRIN,I5 ;持續(xù)0.565mS的低電平,等IRIN為1后跳到I5 AJMP I4 ;此處循環(huán)等待高電平的到來
I5: MOV R2,#0 ;高電平到來后開始0.14mS計一次數(shù) L1: ACALL DEL JB IRIN, N1 ;IRIN為1則跳N1繼續(xù)計數(shù)
MOV A,#8 ;計算高電平長度 CLR C ;減前清進/借位c SUBB A,R2 ;以R2的值判斷此位的高/低(R2<8為0;r2>8為1) ;計數(shù)值<> MOV A,@R0 RRC A MOV @R0,A ;將接收到的一位存入對應的鍵值緩存區(qū) INC R3 ;處理完一位 CJNE R3,#8,LL ;需收集8位 MOV R3,#0 ;收集到1字節(jié) INC R0 ;需收集4字節(jié) CJNE R0,#24H,LL ;用戶碼+用戶碼+操作碼+操作反碼
SETB X ;接收完成標志位置1 JB D,IEND ;如果D=1說明是學習模式跳過鍵值對比 AJMP DK ;跳到鍵值對比區(qū)
N1: INC R2 ;0.14mS R2加一次 CJNE R2,#30,L1 ;0.14ms 計數(shù)過長則時間到自動離開 IEND: RET
;----------------------- ; DELAY_0.14MS(以12M晶振/12T計算) ;----------------------- DEL: ;IR解碼使用(1+2+128+2+4+4=141uS=0.14mS) MOV R5,#3 ;內(nèi)部約6M/1T,3次;;;12M/1T,6次 DEL0: MOV R6,#2 ;1uS DEL1: MOV R7,#32 ;1uS*2次=2uS DJNZ R7,$ ;32*2uS*2次=128uS nop ;1uS*2次=2uS DJNZ R6,DEL1 ;2uS*2次=4uS DJNZ R5,DEL0 ;(1T單片機) RET ;2uS+(acall的)2uS=4uS
;----------------------- DK: MOV R0,#24H ;內(nèi)部鍵值起始存放地址 MOV DPTR,#00H ;第1扇區(qū)起始地址 MOV R1,#4 ;讀4個字節(jié) DP1: ACALL EEPROMR ;讀一字節(jié) MOV @R0,A ;讀出的數(shù)據(jù)存到相應地址 INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,DP1 ;循環(huán)讀完4字節(jié)
MOV DPTR,#200H ;第2扇區(qū)起始地址 MOV R1,#4 ;讀4個字節(jié) DP2: ACALL EEPROMR ;讀一字節(jié) MOV @R0,A ;讀出的數(shù)據(jù)存到相應地址 INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,DP2 ;循環(huán)讀完4字節(jié)
MOV DPTR,#400H ;第3扇區(qū)起始地址 MOV R1,#4 ;讀4個字節(jié) DP3: ACALL EEPROMR ;讀一字節(jié) MOV @R0,A ;讀出的數(shù)據(jù)存到相應地址 INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,DP3 ;循環(huán)讀完4字節(jié)
MOV DPTR,#600H ;第4扇區(qū)起始地址 MOV R1,#4 ;讀4個字節(jié) DP4: ACALL EEPROMR ;讀一字節(jié) MOV @R0,A ;讀出的數(shù)據(jù)存到相應地址 INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,DP4 ;循環(huán)讀完4字節(jié)
MOV DPTR,#800H ;第5扇區(qū)起始地址 MOV R1,#4 ;讀4個字節(jié) DP5: ACALL EEPROMR ;讀一字節(jié) MOV @R0,A ;讀出的數(shù)據(jù)存到相應地址 INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,DP5 ;循環(huán)讀完4字節(jié)
MOV DPTR,#0A00H ;第6扇區(qū)起始地址 MOV R1,#4 ;讀4個字節(jié) DP6: ACALL EEPROMR ;讀一字節(jié) MOV @R0,A ;讀出的數(shù)據(jù)存到相應地址 INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,DP6 ;循環(huán)讀完4字節(jié)
MOV DPTR,#0C00H ;第7扇區(qū)起始地址 MOV R1,#4 ;讀4個字節(jié) DP7: ACALL EEPROMR ;讀一字節(jié) MOV @R0,A ;讀出的數(shù)據(jù)存到相應地址 INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,DP7 ;循環(huán)讀完4字節(jié)
MOV DPTR,#0E00H ;第8扇區(qū)起始地址 MOV R1,#4 ;讀4個字節(jié) DP8: ACALL EEPROMR ;讀一字節(jié) MOV @R0,A ;讀出的數(shù)據(jù)存到相應地址 INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,DP8 ;循環(huán)讀完4字節(jié)
MOV A,20H ;接收到的用戶碼 CJNE A,24H,D1 ;與內(nèi)部存放的對比 MOV A,21H ;接收到的用戶反碼 CJNE A,25H,D1 ;與內(nèi)部存放的對比 MOV A,22H ;接收到的操作碼 CJNE A,26H,D1 ;與內(nèi)部存放的對比 MOV A,23H ;接收到的操作反碼 CJNE A,27H,D1 ;與內(nèi)部存放的對比 CPL LED1 ;都相同,則取反輸出1狀態(tài)
D1: MOV A,20H ;接收到的用戶碼 CJNE A,28H,D2 ;與內(nèi)部存放的對比 MOV A,21H ;接收到的用戶反碼 CJNE A,29H,D2 ;與內(nèi)部存放的對比 MOV A,22H ;接收到的操作碼 CJNE A,2AH,D2 ;與內(nèi)部存放的對比 MOV A,23H ;接收到的操作反碼 CJNE A,2BH,D2 ;與內(nèi)部存放的對比 CPL LED2 ;都相同,則取反輸出2狀態(tài)
D2: MOV A,20H ;接收到的用戶碼 CJNE A,2CH,D3 ;與內(nèi)部存放的對比 MOV A,21H ;接收到的用戶反碼 CJNE A,2DH,D3 ;與內(nèi)部存放的對比 MOV A,22H ;接收到的操作碼 CJNE A,2EH,D3 ;與內(nèi)部存放的對比 MOV A,23H ;接收到的操作反碼 CJNE A,2FH,D3 ;與內(nèi)部存放的對比 CPL LED3 ;都相同,則取反輸出3狀態(tài)
D3: MOV A,20H ;接收到的用戶碼 CJNE A,30H,D4 ;與內(nèi)部存放的對比 MOV A,21H ;接收到的用戶反碼 CJNE A,31H,D4 ;與內(nèi)部存放的對比 MOV A,22H ;接收到的操作碼 CJNE A,32H,D4 ;與內(nèi)部存放的對比 MOV A,23H ;接收到的操作反碼 CJNE A,33H,D4 ;與內(nèi)部存放的對比 CPL LED4 ;都相同,則取反輸出4狀態(tài)
D4: MOV A,20H ;接收到的用戶碼 CJNE A,34H,D5 ;與內(nèi)部存放的對比 MOV A,21H ;接收到的用戶反碼 CJNE A,35H,D5 ;與內(nèi)部存放的對比 MOV A,22H ;接收到的操作碼 CJNE A,36H,D5 ;與內(nèi)部存放的對比 MOV A,23H ;接收到的操作反碼 CJNE A,37H,D5 ;與內(nèi)部存放的對比 CPL LED5 ;都相同,則取反輸出5狀態(tài)
D5: MOV A,20H ;接收到的用戶碼 CJNE A,38H,D6 ;與內(nèi)部存放的對比 MOV A,21H ;接收到的用戶反碼 CJNE A,39H,D6 ;與內(nèi)部存放的對比 MOV A,22H ;接收到的操作碼 CJNE A,3AH,D6 ;與內(nèi)部存放的對比 MOV A,23H ;接收到的操作反碼 CJNE A,3BH,D6 ;與內(nèi)部存放的對比 CPL LED6 ;都相同,則取反輸出6狀態(tài)
D6: MOV A,20H ;接收到的用戶碼 CJNE A,3CH,D7 ;與內(nèi)部存放的對比 MOV A,21H ;接收到的用戶反碼 CJNE A,3DH,D7 ;與內(nèi)部存放的對比 MOV A,22H ;接收到的操作碼 CJNE A,3EH,D7 ;與內(nèi)部存放的對比 MOV A,23H ;接收到的操作反碼 CJNE A,3FH,D7 ;與內(nèi)部存放的對比 CPL LED7 ;都相同,則取反輸出7狀態(tài)
D7: MOV A,20H ;接收到的用戶碼 CJNE A,40H,DEND ;與內(nèi)部存放的對比 MOV A,21H ;接收到的用戶反碼 CJNE A,41H,DEND ;與內(nèi)部存放的對比 MOV A,22H ;接收到的操作碼 CJNE A,42H,DEND ;與內(nèi)部存放的對比 MOV A,23H ;接收到的操作反碼 CJNE A,43H,DEND ;與內(nèi)部存放的對比 CPL LED8 ;都相同,則取反輸出8狀態(tài) DEND: RET
;----------------------- KEYP30:CLR P3.0 ;P3.0與P3.1輪流輸出0,實現(xiàn)矩陣鍵盤
KEY1: JB K1,KEY3 CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改) MOV 45H,#0;或快速切換按鍵時,誤判斷進入學習模式 ACALL DELAY30MS ;延時去抖動 JB K1,KEY3 ACALL OPEN_T0 ;打開T0計時判斷長按 XH1: JBC Z,XUEXI1 ;長按跳轉(zhuǎn)到學習1,并清零長按標志 JNB K1,XH1 CPL LED1 ;OUT1狀態(tài)取反 RET XUEXI1: ;學習1 MOV DPTR,#00H ;第1扇區(qū) ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空 MOV P1,#07FH ;LED1 SETB D ;學習模式標志位置1 ACALL OPEN_T0 ;開T0進行等待計時 DZ1: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序 JBC z,XEND1 ;5S后沒接收到新數(shù)據(jù)則退出 JNB X,DZ1 ;接收完成標志為0則循環(huán)等待 ;寫EEPROM數(shù)據(jù)不能調(diào)公共的'寫',所以只能每次 ;學習模式里都有一堆程序重復寫,浪費空間了!?。? MOV DPTR,#00H ;第1扇區(qū)起始地址;存入新鍵值 MOV R0,#20H ;RAM中接收到的鍵值起始存放地址 MOV R1,#4 ;寫4個字節(jié) LP1: MOV A,@R0 ACALL EEPROMW ;寫一字節(jié) INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,LP1 ;循環(huán)寫完4字節(jié) XEND1: CLR D ;退出學習模式 SETB LED1 ;關(guān)燈 RET ;退出
KEY3: JB K2,KEY5 CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改) MOV 45H,#0;或快速切換按鍵時,誤判斷進入學習模式 ACALL DELAY30MS ;延時去抖動 JB K2,KEY5 ACALL OPEN_T0 ;打開T0計時判斷長按 XH3: JBC Z,XUEXI3 ;長按跳轉(zhuǎn)到學習3,并清零長按標志 JNB K2,XH3 CPL LED3 ;OUT3狀態(tài)取反 RET XUEXI3: ;學習3 MOV DPTR,#400H ;第3扇區(qū) ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空 MOV P1,#0DFH ;LED3 SETB D ;學習模式標志位置1 ACALL OPEN_T0 ;開T0進行等待計時 DZ3: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序 JBC z,XEND3 ;5S后沒接收到新數(shù)據(jù)則退出 JNB X,DZ3 ;接收完成標志為0則循環(huán)等待
MOV DPTR,#400H ;第3扇區(qū)起始地址;存入新鍵值 MOV R0,#20H ;RAM中接收到的鍵值起始存放地址 MOV R1,#4 ;寫4個字節(jié) LP3: MOV A,@R0 ACALL EEPROMW ;寫一字節(jié) INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,LP3 ;循環(huán)寫完4字節(jié) XEND3: CLR D ;退出學習模式 SETB LED3 ;關(guān)燈 RET ;退出
KEY5: JB K3,KEY7 CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改) MOV 45H,#0;或快速切換按鍵時,誤判斷進入學習模式 ACALL DELAY30MS ;延時去抖動 JB K3,KEY7 ACALL OPEN_T0 ;打開T0計時判斷長按 XH5: JBC Z,XUEXI5 ;長按跳轉(zhuǎn)到學習5,并清零長按標志 JNB K3,XH5 CPL LED5 ;OUT5狀態(tài)取反 RET XUEXI5: ;學習5 MOV DPTR,#800H ;第5扇區(qū) ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空 MOV P1,#0F7H ;LED5 SETB D ;學習模式標志位置1 ACALL OPEN_T0 ;開T0進行等待計時 DZ5: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序 JBC z,XEND5 ;5S后沒接收到新數(shù)據(jù)則退出 JNB X,DZ5 ;接收完成標志為0則循環(huán)等待
MOV DPTR,#800H ;第5扇區(qū)起始地址;存入新鍵值 MOV R0,#20H ;RAM中接收到的鍵值起始存放地址 MOV R1,#4 ;寫4個字節(jié) LP5: MOV A,@R0 ACALL EEPROMW ;寫一字節(jié) INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,LP5 ;循環(huán)寫完4字節(jié) XEND5: CLR D ;退出學習模式 SETB LED5 ;關(guān)燈 RET ;退出
KEY7: JB K4,KP30OUT CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改) MOV 45H,#0;或快速切換按鍵時,誤判斷進入學習模式 ACALL DELAY30MS ;延時去抖動 JB K4,KP30OUT ACALL OPEN_T0 ;打開T0計時判斷長按 XH7: JBC Z,XUEXI7 ;長按跳轉(zhuǎn)到學習7,并清零長按標志 JNB K4,XH7 CPL LED7 ;OUT7狀態(tài)取反 RET XUEXI7: ;學習7 MOV DPTR,#0C00H ;第7扇區(qū) ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空 MOV P1,#0FDH ;LED7 SETB D ;學習模式標志位置1 ACALL OPEN_T0 ;開T0進行等待計時 DZ7: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序 JBC z,XEND7 ;5S后沒接收到新數(shù)據(jù)則退出 JNB X,DZ7 ;接收完成標志為0則循環(huán)等待
MOV DPTR,#0C00H ;第7扇區(qū)起始地址;存入新鍵值 MOV R0,#20H ;RAM中接收到的鍵值起始存放地址 MOV R1,#4 ;寫4個字節(jié) LP7: MOV A,@R0 ACALL EEPROMW ;寫一字節(jié) INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,LP7 ;循環(huán)寫完4字節(jié) XEND7: CLR D ;退出學習模式 SETB LED7 ;關(guān)燈 RET ;退出
KP30OUT: SETB P3.0 RET
;----------------------- KEYP31:CLR P3.1 ;P3.0與P3.1輪流輸出0,實現(xiàn)矩陣鍵盤
KEY2: JB K1,KEY4 CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改) MOV 45H,#0;或快速切換按鍵時,誤判斷進入學習模式 ACALL DELAY30MS ;延時去抖動 JB K1,KEY4 ACALL OPEN_T0 ;打開T0計時判斷長按 XH2: JBC Z,XUEXI2 ;長按跳轉(zhuǎn)到學習2,并清零長按標志 JNB K1,XH2 CPL LED2 ;OUT2狀態(tài)取反 RET XUEXI2: ;學習2 MOV DPTR,#200H ;第2扇區(qū) ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空 MOV P1,#0BFH ;LED2 SETB D ;學習模式標志位置1 ACALL OPEN_T0 ;開T0進行等待計時 DZ2: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序 JBC z,XEND2 ;5S后沒接收到新數(shù)據(jù)則退出 JNB X,DZ2 ;接收完成標志為0則循環(huán)等待
MOV DPTR,#200H ;第2扇區(qū)起始地址;存入新鍵值 MOV R0,#20H ;RAM中接收到的鍵值起始存放地址 MOV R1,#4 ;寫4個字節(jié) LP2: MOV A,@R0 ACALL EEPROMW ;寫一字節(jié) INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,LP2 ;循環(huán)寫完4字節(jié) XEND2: CLR D ;退出學習模式 SETB LED2 ;關(guān)燈 RET ;退出
KEY4: JB K2,KEY6 CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改) MOV 45H,#0;或快速切換按鍵時,誤判斷進入學習模式 ACALL DELAY30MS ;延時去抖動 JB K2,KEY6 ACALL OPEN_T0 ;打開T0計時判斷長按 XH4: JBC Z,XUEXI4 ;長按跳轉(zhuǎn)到學習4,并清零長按標志 JNB K2,XH4 CPL LED4 ;OUT4狀態(tài)取反 RET XUEXI4: ;學習4 MOV DPTR,#600H ;第4扇區(qū) ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空 MOV P1,#0EFH ;LED4 SETB D ;學習模式標志位置1 ACALL OPEN_T0 ;開T0進行等待計時 DZ4: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序 JBC z,XEND4 ;5S后沒接收到新數(shù)據(jù)則退出 JNB X,DZ4 ;接收完成標志為0則循環(huán)等待
MOV DPTR,#600H ;第4扇區(qū)起始地址;存入新鍵值 MOV R0,#20H ;RAM中接收到的鍵值起始存放地址 MOV R1,#4 ;寫4個字節(jié) LP4: MOV A,@R0 ACALL EEPROMW ;寫一字節(jié) INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,LP4 ;循環(huán)寫完4字節(jié) XEND4: CLR D ;退出學習模式 SETB LED4 ;關(guān)燈 RET ;退出
KEY6: JB K3,KEY8 CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改) MOV 45H,#0;或快速切換按鍵時,誤判斷進入學習模式 ACALL DELAY30MS ;延時去抖動 JB K3,KEY8 ACALL OPEN_T0 ;打開T0計時判斷長按 XH6: JBC Z,XUEXI6 ;長按跳轉(zhuǎn)到學習6,并清零長按標志 JNB K3,XH6 CPL LED6 ;OUT6狀態(tài)取反 RET XUEXI6: ;學習6 MOV DPTR,#0A00H ;第6扇區(qū) ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空 MOV P1,#0FBH ;LED6 SETB D ;學習模式標志位置1 ACALL OPEN_T0 ;開T0進行等待計時 DZ6: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序 JBC z,XEND6 ;5S后沒接收到新數(shù)據(jù)則退出 JNB X,DZ6 ;接收完成標志為0則循環(huán)等待
MOV DPTR,#0A00H ;第6扇區(qū)起始地址;存入新鍵值 MOV R0,#20H ;RAM中接收到的鍵值起始存放地址 MOV R1,#4 ;寫4個字節(jié) LP6: MOV A,@R0 ACALL EEPROMW ;寫一字節(jié) INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,LP6 ;循環(huán)寫完4字節(jié) XEND6: CLR D ;退出學習模式 SETB LED6 ;關(guān)燈 RET ;退出
KEY8: JB K4,KP31OUT CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改) MOV 45H,#0;或快速切換按鍵時,誤判斷進入學習模式 ACALL DELAY30MS ;延時去抖動 JB K4,KP31OUT ACALL OPEN_T0 ;打開T0計時判斷長按 XH8: JBC Z,XUEXI8 ;長按跳轉(zhuǎn)到學習8,并清零長按標志 JNB K4,XH8 CPL LED8 ;OUT8狀態(tài)取反 RET XUEXI8: ;學習8 MOV DPTR,#0E00H ;第8扇區(qū) ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空 MOV P1,#0FEH ;LED8 SETB D ;學習模式標志位置1 ACALL OPEN_T0 ;開T0進行等待計時 DZ8: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序 JBC z,XEND8 ;5S后沒接收到新數(shù)據(jù)則退出 JNB X,DZ8 ;接收完成標志為0則循環(huán)等待
MOV DPTR,#0E00H ;第8扇區(qū)起始地址;存入新鍵值 MOV R0,#20H ;RAM中接收到的鍵值起始存放地址 MOV R1,#4 ;寫4個字節(jié) LP8: MOV A,@R0 ACALL EEPROMW ;寫一字節(jié) INC R0 ;內(nèi)存地址加一 INC DPTR ;地址指針加一 DJNZ R1,LP8 ;循環(huán)寫完4字節(jié) XEND8: CLR D ;退出學習模式 SETB LED8 ;關(guān)燈 RET ;退出
KP31OUT: SETB P3.1 RET
;----------------------- DELAY30MS: ;6M/1T模式延時約30mS MOV R7,#6 DL1: MOV R6,#100 DL0: MOV R5,#150 DJNZ R5,$ DJNZ R6,DL0 DJNZ R7,DL1 RET
;----------------------- OPEN_T0: ;打開T0計時 MOV TH0,#3CH ;定時器0初值 MOV TL0,#0B0H ;內(nèi)部約6MHz(100ms) CLR Z ;清長按標志 CLR X ;接收完成標志位清零 SETB TR0 ;打開T0 RET
;----------------------- T0INT: ;T0中斷(判斷長按) MOV TH0,#3CH ;重裝初值 MOV TL0,#0B0H ;內(nèi)部約6MHz(100ms) INC 45H ;中斷計數(shù)約100ms一次 MOV A,45H CJNE A,#30,TOUT1 ;100ms*30=3s MOV 45H,#0 ;中斷計數(shù)滿30清零 SETB Z ;長按標志位置1 CLR TR0 ;關(guān)閉T0 TOUT1: RETI
;----------------------- PDSQ: ACALL EEPROMR ;讀1個字節(jié)判斷扇區(qū)是否為空 CJNE A,#0FFH,ERASE;扇區(qū)不為空則擦除扇區(qū) RET
;----------------------- ;EEPROM相關(guān)操作 ;----------------------- ERASE:;擦除 MOV ISP_ADDRH,DPH ;送高地址 MOV ISP_ADDRL,DPL ;送低地址 MOV ISP_CONTR,#83H ;允許ISP/IAP操作(6~12MHz) MOV ISP_CMD,#03H ;扇區(qū)擦除 ACALL ISPCF ;觸發(fā)IAP ACALL ISP_DISABLE ;禁止ISP/IAP操作 RET ;---------------------- EEPROMW:;寫 MOV ISP_DATA,A ;ACC里是要寫入的數(shù)據(jù) MOV ISP_ADDRH,DPH ;送高地址 MOV ISP_ADDRL,DPL ;送低地址 MOV ISP_CONTR,#83H ;允許ISP/IAP操作(6~12MHz) MOV ISP_CMD,#02H ;送寫命令 ACALL ISPCF ;觸發(fā)IAP ACALL ISP_DISABLE ;禁止ISP/IAP操作 RET ;---------------------- EEPROMR: ;讀 MOV ISP_ADDRH,DPH ;送高地址 MOV ISP_ADDRL,DPL ;送低地址 MOV ISP_CONTR,#83H ;允許ISP/IAP操作(6~12MHz) MOV ISP_CMD,#01H ;送讀命令 ACALL ISPCF ;觸發(fā)IAP MOV A,ISP_DATA ;讀出的數(shù)據(jù)放到ACC ACALL ISP_DISABLE ;禁止ISP/IAP操作 RET ;---------------------- ISPCF: ;觸發(fā)ISP/IAP MOV ISP_TRIG, #46H ;以MCU型號來定;STC12C2052(46H/0B9H) MOV ISP_TRIG, #0B9H ;11F和15F系列相同(5AH/0A5H) NOP RET ;---------------------- ISP_DISABLE: ;禁止ISP/IAP操作(出于安全考慮才要) MOV ISP_CONTR,#00H MOV ISP_CMD,#00H MOV ISP_TRIG,#00H MOV ISP_ADDRH,#0FFH MOV ISP_ADDRL,#0FFH RET ;-----------------------
|