|
本帖最后由 qq704661078 于 2015-12-26 23:09 編輯
以前在論壇都持觀望態(tài)度,今天第一次發(fā)帖,希望對大家有所幫助!因本人對匯編語言情有獨(dú)鐘,所以本程序用匯編語言編寫,經(jīng)過測試,MP3和電視機(jī)的遙控都能學(xué)習(xí)對鍵成功,其他遙控因為手頭沒有,所以不敢保證全部支持!P1口作為輸出口,我分別接了8個燈做指示,如果連上8路繼電器,就可紅外控制8路電器的工作,雖然紅外遙控受遙控距離及方向的影響用起來不夠順心,但在房間里是完全夠用了的!紅外接收頭接P3.7腳;8個學(xué)習(xí)鍵是利用P3.0和P3.1輪流輸出低電平與P3.2/3.3/3.4/3.5形成2*4矩陣鍵盤。短按按鍵可分別手動控制輸出端;長按某鍵5秒左右則進(jìn)入學(xué)習(xí)模式,相應(yīng)輸出端的指示燈亮起(學(xué)習(xí)指示燈與輸出指示燈復(fù)用,其實學(xué)習(xí)模式應(yīng)該是閃爍狀態(tài),但我沒寫這方面的程序,有需要的自己加進(jìn)去!),在5秒內(nèi)用遙控器對著接收頭按一次遙控的一個鍵(隨自己愛好),學(xué)習(xí)指示燈熄滅,學(xué)習(xí)成功!如果要刪除遙控鍵,則長按按鍵至學(xué)習(xí)模式后不按遙控器,5秒后學(xué)習(xí)指示燈熄滅,原來學(xué)習(xí)的遙控鍵數(shù)據(jù)被刪除,遙控器不能再控制這一路輸出,有需要了再重新學(xué)習(xí)此路!下面曬幾張我自制的實驗板: 圖片壓縮了,不然發(fā)不上來!!!——板子可插紅外接收頭、315M無線發(fā)射/接收模塊!!!
(1)、插紅外接收頭:
DSC_1025.JPG (82.44 KB, 下載次數(shù): 408)
下載附件
插上紅外接收頭
2015-5-14 18:55 上傳
(2)、背面連接線路:
DSC_1026.JPG (87.32 KB, 下載次數(shù): 373)
下載附件
背面連接線路
2015-5-14 18:55 上傳
(3)、插315M無線接收模塊:
DSC_1027.JPG (85.55 KB, 下載次數(shù): 388)
下載附件
插上315M無線接收模塊
2015-5-14 18:55 上傳
(4)、插315M無線發(fā)射模塊:
DSC_1028.JPG (79.88 KB, 下載次數(shù): 358)
下載附件
插上315M無線發(fā)射模塊
2015-5-14 18:55 上傳
Text1.rar
(3.79 KB, 下載次數(shù): 136)
2015-5-13 23:08 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
程序更新...:
因之前發(fā)布的程序還存在小Bug,正好今天有空,就把最新的程序貼上來吧!此次更新主要解決以下問題:按某個鍵后5S內(nèi)再按另外一個鍵會誤判斷進(jìn)入第二個鍵的學(xué)習(xí)模式...(在按鍵掃描部分加了一些處理動作)
好了,不多說,看程序吧:
;;;STC12C2052/STC12C56**學(xué)習(xí)型紅外遙控8路繼電器
;;;內(nèi)部RC振蕩器約6MHz;;;
;;;寫EEPROM數(shù)據(jù)不能調(diào)公共的"寫",所以每1路的學(xué)習(xí)模式里
;;;都要重復(fù)寫一堆相同的程序,感覺有點(diǎn)浪費(fèi)空間了,郁悶ing...
;;;修改日期2015/10/10;;;
;----------------------
ISP_DATA EQU 0E2H ;定義EEPROM相關(guān)寄存器
ISP_ADDRH EQU 0E3H ;此類寄存器地址需參考所用單片機(jī)的手冊來設(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 ;長按標(biāo)志位
X EQU 01H ;接收完成標(biāo)志位
D EQU 02H ;學(xué)習(xí)模式標(biāo)志位
IRIN EQU P3.7 ;紅外接收頭
K1 EQU P3.2 ;學(xué)習(xí)鍵 (P3.0與P3.1輪流輸出0)
K2 EQU P3.3 ;學(xué)習(xí)鍵 (實現(xiàn)2*4矩陣鍵盤)
K3 EQU P3.4 ;學(xué)習(xí)鍵
K4 EQU P3.5 ;學(xué)習(xí)鍵
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 ;確認(rèn)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程序完成引導(dǎo)碼的確認(rèn)(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 ;減前清進(jìn)/借位c
SUBB A,R2 ;以R2的值判斷此位的高/低(R2<8為0;R2>8為1)
;計數(shù)值<8則此位為0(即8-R2;c=0)
MOV A,@R0
RRC A
MOV @R0,A ;將接收到的一位存入對應(yīng)的鍵值緩存區(qū)
INC R3 ;處理完一位
CJNE R3,#8,LL ;需收集8位
MOV R3,#0 ;收集到1字節(jié)
INC R0 ;需收集4字節(jié)
CJNE R0,#24H,LL ;用戶碼+用戶碼+操作碼+操作反碼
SETB X ;接收完成標(biāo)志位置1
JB D,IEND ;如果D=1說明是學(xué)習(xí)模式跳過鍵值對比
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單片機(jī))
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ù)存到相應(yīng)地址
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ù)存到相應(yīng)地址
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ù)存到相應(yīng)地址
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ù)存到相應(yīng)地址
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ù)存到相應(yīng)地址
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ù)存到相應(yīng)地址
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ù)存到相應(yīng)地址
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ù)存到相應(yīng)地址
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;或快速切換按鍵時,誤判斷進(jìn)入學(xué)習(xí)模式
ACALL DELAY30MS ;延時去抖動
JB K1,KEY3
ACALL OPEN_T0 ;打開T0計時判斷長按
XH1: JBC Z,XUEXI1 ;長按跳轉(zhuǎn)到學(xué)習(xí)1,并清零長按標(biāo)志
JNB K1,XH1
CPL LED1 ;OUT1狀態(tài)取反
RET
XUEXI1: ;學(xué)習(xí)1
MOV DPTR,#00H ;第1扇區(qū)
ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空
MOV P1,#07FH ;LED1
SETB D ;學(xué)習(xí)模式標(biāo)志位置1
ACALL OPEN_T0 ;開T0進(jìn)行等待計時
DZ1: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序
JBC z,XEND1 ;5S后沒接收到新數(shù)據(jù)則退出
JNB X,DZ1 ;接收完成標(biāo)志為0則循環(huán)等待
;寫EEPROM數(shù)據(jù)不能調(diào)公共的"寫",所以只能每次
;學(xué)習(xí)模式里都有一堆程序重復(fù)寫,浪費(fèi)空間了!!!
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 ;退出學(xué)習(xí)模式
SETB LED1 ;關(guān)燈
RET ;退出
KEY3: JB K2,KEY5
CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改)
MOV 45H,#0;或快速切換按鍵時,誤判斷進(jìn)入學(xué)習(xí)模式
ACALL DELAY30MS ;延時去抖動
JB K2,KEY5
ACALL OPEN_T0 ;打開T0計時判斷長按
XH3: JBC Z,XUEXI3 ;長按跳轉(zhuǎn)到學(xué)習(xí)3,并清零長按標(biāo)志
JNB K2,XH3
CPL LED3 ;OUT3狀態(tài)取反
RET
XUEXI3: ;學(xué)習(xí)3
MOV DPTR,#400H ;第3扇區(qū)
ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空
MOV P1,#0DFH ;LED3
SETB D ;學(xué)習(xí)模式標(biāo)志位置1
ACALL OPEN_T0 ;開T0進(jìn)行等待計時
DZ3: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序
JBC z,XEND3 ;5S后沒接收到新數(shù)據(jù)則退出
JNB X,DZ3 ;接收完成標(biāo)志為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 ;退出學(xué)習(xí)模式
SETB LED3 ;關(guān)燈
RET ;退出
KEY5: JB K3,KEY7
CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改)
MOV 45H,#0;或快速切換按鍵時,誤判斷進(jìn)入學(xué)習(xí)模式
ACALL DELAY30MS ;延時去抖動
JB K3,KEY7
ACALL OPEN_T0 ;打開T0計時判斷長按
XH5: JBC Z,XUEXI5 ;長按跳轉(zhuǎn)到學(xué)習(xí)5,并清零長按標(biāo)志
JNB K3,XH5
CPL LED5 ;OUT5狀態(tài)取反
RET
XUEXI5: ;學(xué)習(xí)5
MOV DPTR,#800H ;第5扇區(qū)
ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空
MOV P1,#0F7H ;LED5
SETB D ;學(xué)習(xí)模式標(biāo)志位置1
ACALL OPEN_T0 ;開T0進(jìn)行等待計時
DZ5: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序
JBC z,XEND5 ;5S后沒接收到新數(shù)據(jù)則退出
JNB X,DZ5 ;接收完成標(biāo)志為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 ;退出學(xué)習(xí)模式
SETB LED5 ;關(guān)燈
RET ;退出
KEY7: JB K4,KP30OUT
CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改)
MOV 45H,#0;或快速切換按鍵時,誤判斷進(jìn)入學(xué)習(xí)模式
ACALL DELAY30MS ;延時去抖動
JB K4,KP30OUT
ACALL OPEN_T0 ;打開T0計時判斷長按
XH7: JBC Z,XUEXI7 ;長按跳轉(zhuǎn)到學(xué)習(xí)7,并清零長按標(biāo)志
JNB K4,XH7
CPL LED7 ;OUT7狀態(tài)取反
RET
XUEXI7: ;學(xué)習(xí)7
MOV DPTR,#0C00H ;第7扇區(qū)
ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空
MOV P1,#0FDH ;LED7
SETB D ;學(xué)習(xí)模式標(biāo)志位置1
ACALL OPEN_T0 ;開T0進(jìn)行等待計時
DZ7: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序
JBC z,XEND7 ;5S后沒接收到新數(shù)據(jù)則退出
JNB X,DZ7 ;接收完成標(biāo)志為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 ;退出學(xué)習(xí)模式
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;或快速切換按鍵時,誤判斷進(jìn)入學(xué)習(xí)模式
ACALL DELAY30MS ;延時去抖動
JB K1,KEY4
ACALL OPEN_T0 ;打開T0計時判斷長按
XH2: JBC Z,XUEXI2 ;長按跳轉(zhuǎn)到學(xué)習(xí)2,并清零長按標(biāo)志
JNB K1,XH2
CPL LED2 ;OUT2狀態(tài)取反
RET
XUEXI2: ;學(xué)習(xí)2
MOV DPTR,#200H ;第2扇區(qū)
ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空
MOV P1,#0BFH ;LED2
SETB D ;學(xué)習(xí)模式標(biāo)志位置1
ACALL OPEN_T0 ;開T0進(jìn)行等待計時
DZ2: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序
JBC z,XEND2 ;5S后沒接收到新數(shù)據(jù)則退出
JNB X,DZ2 ;接收完成標(biāo)志為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 ;退出學(xué)習(xí)模式
SETB LED2 ;關(guān)燈
RET ;退出
KEY4: JB K2,KEY6
CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改)
MOV 45H,#0;或快速切換按鍵時,誤判斷進(jìn)入學(xué)習(xí)模式
ACALL DELAY30MS ;延時去抖動
JB K2,KEY6
ACALL OPEN_T0 ;打開T0計時判斷長按
XH4: JBC Z,XUEXI4 ;長按跳轉(zhuǎn)到學(xué)習(xí)4,并清零長按標(biāo)志
JNB K2,XH4
CPL LED4 ;OUT4狀態(tài)取反
RET
XUEXI4: ;學(xué)習(xí)4
MOV DPTR,#600H ;第4扇區(qū)
ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空
MOV P1,#0EFH ;LED4
SETB D ;學(xué)習(xí)模式標(biāo)志位置1
ACALL OPEN_T0 ;開T0進(jìn)行等待計時
DZ4: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序
JBC z,XEND4 ;5S后沒接收到新數(shù)據(jù)則退出
JNB X,DZ4 ;接收完成標(biāo)志為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 ;退出學(xué)習(xí)模式
SETB LED4 ;關(guān)燈
RET ;退出
KEY6: JB K3,KEY8
CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改)
MOV 45H,#0;或快速切換按鍵時,誤判斷進(jìn)入學(xué)習(xí)模式
ACALL DELAY30MS ;延時去抖動
JB K3,KEY8
ACALL OPEN_T0 ;打開T0計時判斷長按
XH6: JBC Z,XUEXI6 ;長按跳轉(zhuǎn)到學(xué)習(xí)6,并清零長按標(biāo)志
JNB K3,XH6
CPL LED6 ;OUT6狀態(tài)取反
RET
XUEXI6: ;學(xué)習(xí)6
MOV DPTR,#0A00H ;第6扇區(qū)
ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空
MOV P1,#0FBH ;LED6
SETB D ;學(xué)習(xí)模式標(biāo)志位置1
ACALL OPEN_T0 ;開T0進(jìn)行等待計時
DZ6: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序
JBC z,XEND6 ;5S后沒接收到新數(shù)據(jù)則退出
JNB X,DZ6 ;接收完成標(biāo)志為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 ;退出學(xué)習(xí)模式
SETB LED6 ;關(guān)燈
RET ;退出
KEY8: JB K4,KP31OUT
CLR TR0;這兩句是為了防止在快速連按按鍵 (2015/10/10修改)
MOV 45H,#0;或快速切換按鍵時,誤判斷進(jìn)入學(xué)習(xí)模式
ACALL DELAY30MS ;延時去抖動
JB K4,KP31OUT
ACALL OPEN_T0 ;打開T0計時判斷長按
XH8: JBC Z,XUEXI8 ;長按跳轉(zhuǎn)到學(xué)習(xí)8,并清零長按標(biāo)志
JNB K4,XH8
CPL LED8 ;OUT8狀態(tài)取反
RET
XUEXI8: ;學(xué)習(xí)8
MOV DPTR,#0E00H ;第8扇區(qū)
ACALL PDSQ ;讀數(shù)判斷扇區(qū)是否為空
MOV P1,#0FEH ;LED8
SETB D ;學(xué)習(xí)模式標(biāo)志位置1
ACALL OPEN_T0 ;開T0進(jìn)行等待計時
DZ8: ACALL IR_IN ;在5S內(nèi)循環(huán)調(diào)用紅外接收程序
JBC z,XEND8 ;5S后沒接收到新數(shù)據(jù)則退出
JNB X,DZ8 ;接收完成標(biāo)志為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 ;退出學(xué)習(xí)模式
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 ;清長按標(biāo)志
CLR X ;接收完成標(biāo)志位清零
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 ;長按標(biāo)志位置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
;-----------------------
END
新程序的hex代碼長度有1089字節(jié),超過1K了,沒法用我的那塊STC12C1052了,1052才1K字節(jié)的ROMo(╯□╰)o......
|
評分
-
查看全部評分
|