⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 12f629=keelog.asm

📁 12f629单片机解码KEELOG源码,遥控器滚动码常用
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	RLF		ADDRESS,W   ;因微芯原程序用的是93C46读写16字节的方试所以每次地址都要加2.
	MOVWF	ADDR
	CALL	R_EE
	MOVF	OUTBYT,W
	MOVWF	TMP2
	INCF	ADDR,1
	CALL	R_EE
	MOVF	OUTBYT,W
	MOVWF	TMP1	
    RETURN
;**********************************************************************
; 功能    	: 主要的()	      			
; 描述  	: 主程序
;-------------------------------------------------------------------------
MAIN
	MOVLW	1H			; 读学习指示字
	MOVWF	ADDRESS
	CALL	EEREAD	    ;
	BTFSC	TMP2,3		; UPR BIT OF SELFLEARN NIBBLE ZERO
	GOTO	MAIN2		; IF NOT CONTINUE NORMAL PGM FLOW
	BTFSC	TMP2,7		; UPR BIT OF TXNUM NIBBLE ZERO
	GOTO	MAIN2		; IF NOT CONTINUE NORMAL PGM FLOW
	MOVLW	BUSY		; TEST IF LEARN PASS1 WAS ACTIVE 
	XORWF	TMP1,W
	SKPZ				; IF NOT CONTINUE NORMAL PGM FLOW
	GOTO	MAIN2
	SWAPF	TMP2,W		; RECOVER PREVIOUS TX NUMBER
	ANDLW	07H			; MASK ONLY LOWER 3 BITS
	CLRF	TMP1		; RESET SELFLEARN POINTER 
	MOVWF	TXNUM		; ... TO CURRENT TXNUM
	MOVWF	TMP2

	MOVLW	PASS2		; SET PGM IN 2ND PASS OF SELFLRN
	MOVWF	SREG		; .TO ALLOW WRITING OF SER NRS & 
					    ; .LEARN POINTER
	MOVLW	1H			; WRITE LEARN POINTER
	MOVWF	ADDRESS
	CALL	EEWRITE		; UPDATE EEPROM  
	GOTO	WIPE_TX			; WIPE TX (SELFLEARN UNSUCCESFUL)
MAIN2
	MOVLW	NORMAL			; INDICATE NORMAL PROGRAM FLOW
	MOVWF	SREG

M_LOOP	
	BTFSS	SREG,2			; TEST FOR NORMAL STATE
	GOTO	M_LOOP2
	BTFSS	FLAGS,OUT_500	; TST 500MS TIMEOUT AFTR OUTPUT
	BCF		GPIO,LED		; SET LED OFF IF NORMAL PGM FLOW

M_LOOP2
	CALL	TST_LEARN1		; 测试学习钮,
	CALL	RECEIVE			; 收发射信号VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
	SKPNC				    ; CHECK IF TRANSMISSION VALID
	GOTO	M_LOOP			; 如果没有等下次发射.
	MOVLW	0FH				; MAXIMUM SERIAL NUMBER IS 28 BITS
	ANDWF	SER_0,1
	MOVFW	SER_0			; CHECK SERIAL # NOT EQUAL TO ZERO
	IORWF	SER_1,W
	IORWF	SER_2,W
	IORWF	SER_3,W
	SKPNZ					; ... IF ZERO WAIT FOR NEXT TX
	GOTO	M_LOOP
	CALL	CHK_PASS2		; IF ON SECOND PASS OF LEARN 
	SKPZ					; .DON'T CLR,TXNUM HAS LRN POS
	CLRF	TXNUM			; .ELSE POINT TO FIRST TX

; ******* 比较下半部字的序列号 ********
M_SERIAL
	CALL	TX_LOOKUP		; GET TX BASE ADDRESS
	BSF		ADDRESS,1		; ADD 2 TO BASE ADDRESS
	CALL	EEREAD		    ; READ LOW 16BITS OF SER # FROM EE
  
	MOVFW	TMP1			; (TX)接收和存贮器值比较
	XORWF	SER_2,W
	SKPZ					;如果不相等则错误
	GOTO	M_SER_ERR
	MOVFW	TMP2			; (TX)接收和存贮器值比较
	XORWF	SER_3,W
	SKPZ					; 如果不相等则错误
	GOTO	M_SER_ERR
	
; ******* 比较上半部字的序列号 ********
M_SERIAL2
	INCF	ADDRESS	   ; 指向下一地址入口(TX)
	CALL	EEREAD		; READ UP 16BITS OF SER # FROM EE

	MOVFW	TMP1		; COMPARE RX AND EEPROM VALUES
	XORWF	SER_0,W
	SKPZ				; ... IF NOT EQUAL DO ERROR
	GOTO	M_SER_ERR

	MOVFW	TMP2		; COMPARE RX AND EEPROM VALUES
	XORWF	SER_1,W
	SKPZ				; ... IF NOT EQUAL DO ERROR
	GOTO	M_SER_ERR
	
; **************** 测试如果学习激活 *******************
M_PASS	
	MOVLW	PASS1			; TEST IF ON FIRST PASS OF LEARN
	XORWF	SREG,W
	SKPNZ				 
	GOTO	CALC_KEY		; IF EQU GENERATE DECRYPTION KEY

	CALL	CHK_PASS2
	SKPNZ				
	GOTO	M_HOP			; IF EQU DECODE TRANSMISSION

	MOVLW	NORMAL			; TEST FOR NORMAL PROGRAM FLOW
	XORWF	SREG,W
	SKPNZ				
	GOTO	M_HOP			; IF EQU DECODE TRANSMISSION
	GOTO	RESET			; ELSE PGM STATE ERROR => RESET

; ******** 序列号比较错误  **************
M_SER_ERR
	CALL	CHK_PASS2		; CHECK IF IN 2ND STATE OF LEARN
	SKPNZ
	GOTO	RESET			; IF SO WIPE CURRENT TX USING 
                                        ; .RECOVERY
; ******** 寻找下一个序列号的位置 *********
M_NEXT	
	INCF	TXNUM		; POINT TO NEXT TX POSITION
	MOVLW	6H			; TEST FOR LAST POSITION
	SUBWF	TXNUM,W
	SKPC				; ... IF NOT GET NEXT ENTRY
	GOTO	M_SERIAL
; **** 序列号没有发现(仅正常模式 (ONLY IN NORMAL / PASS1 ) ****
	MOVLW	PASS1			; TEST IF ON 1ST PASS OF SELFLEARN
	XORWF	SREG,W
	SKPZ				; IF EQUAL CONTINUE 
	GOTO	M_LOOP			; ELSE WAIT FOR NEXT TRANSMISSION
; ****** IF SERIAL NOT IN MAP READ SELFLEARN POINTER ******
	MOVLW	1H			; POINT TO LEARN POINTER
	MOVWF	ADDRESS
	CALL	EEREAD		; READ LEARN POINTER FROM EEPROM

	MOVLW	07H			; MASK TXNUM FROM POINTER
	ANDWF	TMP2,W
	MOVWF	TXNUM

	BTFSS	TXNUM,2			; TXNUM < 4 IS VALID
	GOTO	CALC_KEY		; YES, GENERATE DECRYPTION KEY

	BTFSC	TXNUM,1			; TXNUM > 5 IS INVALID
	CLRF	TXNUM			; ... LEARN POSITION SET TO ZERO
  	GOTO	CALC_KEY		; LEARN CURRENT RECEIVED TX

; ***************解码 *************************
M_HOP	
	CALL	TX_LOOKUP		; LOOK UP TRANSMITTER BASE ADDRESS
	BSF		ADDRESS,2		; ADD 4 TO BASE ADDRESS

	GOTO	READ_KEY		; READ 64 BIT DECODER KEY
M_DEC	
	CALL	DECRYPT			; DECRYPT HOPCODE 
	MOVLW	PASS1			; TEST IF ON 1ST PASS OF SELFLEARN
	XORWF	SREG,W
	SKPNZ				; IF EQU UPDATE BUTTON CODES & 
	GOTO	M_SL_UPDATE		; .DISCR VALUE

	CALL	CHK_PASS2		; TEST IF ON SECOND PASS OF LEARN
	SKPNZ				; IF EQU CHECK DISCR VALUE
	GOTO	M_DIS

	MOVLW	NORMAL			; TEST FOR NORMAL PROGRAM FLOW
	XORWF	SREG,W
	SKPNZ				; IF EQU CHECK DISCR VALUE
	GOTO	M_DIS

	GOTO	RESET			; ELSE PGM STATE ERROR => RESET

; **** 更新按钮代码和识别值****
M_SL_UPDATE
	MOVLW	1H			; 指向学习指示器
	MOVWF	ADDRESS
	CALL	EEREAD		; 从存贮器读学习指示器

	MOVLW	BUSY		;指示学习存贮激活
	MOVWF	TMP1			

	MOVLW	0FH			;覆盖学习指示器
	ANDWF	TMP2,1
	MOVLW	6H			;测试学习指示器是否坏的
	SUBWF	TMP2,W			; TEST FOR INVALID LEARN POINTER
	SKPNC				; TEST FOR INVALID LEARN POINTER
	CLRF	TMP2			; IF INVALID POINT TO 1ST POSITION

	SWAPF	TXNUM,W			; COPY TXNUM INTO UPPER NIBBLE
	IORWF	TMP2,1

	CALL	EEWRITE		; 更新存贮器里的学习指示器

	CALL	BUT_LOOKUP		; 获得按钮代码的基地址
	MOVWF	ADDRESS
	
	MOVFW	FUNC			; 获得当前的按钮代码(学习状态)
	MOVWF	TMP1
	MOVFW	DISC			; 获得当前的识别字代码(学习状态)
	MOVWF	TMP2

	CALL	EEWRITE		; 按钮代码的识别字写入存贮器

	MOVFW	CNTR_HI			;存一个接收计数器,高字节 
	MOVWF	TMP1
	MOVFW	CNTR_LW
	MOVWF	TMP2

	CALL	TX_LOOKUP		;获得发射机的基地址
	CALL	EEWRITE			;当前的16位接收计数器写入存贮器

	BCF		GPIO,LED		;LED OFF TO SHOW 1ST VALID TX REC
	MOVLW	PASS2			;指示PASS2激活
	MOVWF	SREG
	GOTO	M_RESYNC		;进入强制计数器同步

; ************** 测试识别字的值 *****************
M_DIS
	CALL	BUT_LOOKUP		; 指向按钮代码基地址.
	MOVWF	ADDRESS			; 送代码到地址寄存器
	CALL	EEREAD          ;读出按钮代码.

	CALL	CHK_PASS2		; 检查程序状态是否PASS2状态.
	SKPZ
	GOTO	M_DIS2			; IF NOT CHECK ONLY DISCR VALUE

	MOVFW	TMP1			; CHECK BUT CODE IF ON 2ND PASS 
					        ; .OF LEARN
	XORWF	FUNC,W
	ANDLW	0F0H			; MASK BUTTON CODES
	SKPZ			      	; IF EQUAL CONTINUE
	GOTO	RESET			; ELSE LEARN ERROR, FORCE A RESET

M_DIS2
	MOVFW	TMP2			; CHECK DISCRIMINATION VALUE 
	XORWF	DISC,W
	SKPNZ				
	GOTO	M_CNT           ; TMP2=DISC等 ,跳同步检查
	BCF		FLAGS,RESYNC	;清同步标志因TMP2和DISC不相同所以不用同步检查.
	CALL	CHK_PASS2		; 检查是否PASS2状态 
	SKPNZ
	GOTO	RESET			; 是,PASS2状态,重新开始
	GOTO	MAIN			; 不是,到主程序等待下次发射.

; ***************检查同步计数值, CHECK COUNTERS VALID ************
M_CNT
	BTFSS	FLAGS,RESYNC		; 测试同步位
	GOTO	M_CNT1			; IF NOT GET COUNTERS FROM EEPROM

	MOVFW	RAM_HI			; GET PREVIOUS TX COUNTER 
	MOVWF	TMP1
	MOVFW	RAM_LW
	MOVWF	TMP2
	GOTO	M_SUB		; SUBSTRACT FROM CURRENT COUNTER

M_CNT1
	CALL	TX_LOOKUP	; POINT LOWER 16 BIT COUNTER
	CALL	EEREAD		; READ LOWER 16BIT COUNTER FROM EE

	MOVFW	TMP1		; TEMPORY STORE 1ST 16BIT COUNTER
	MOVWF	TMP3
	MOVFW	TMP2
	MOVWF	TMP4

	INCF	ADDRESS		; POINT TO UPPER 16-BIT COUNTER
	CALL	EEREAD			; READ UP 16BIT COUNTER FROM EE

	MOVFW	TMP1		; COMPARE UP BYTES OF EE COUNTER
	XORWF	TMP3,W
	SKPZ				; IF EQUAL COMPARE LOWER
	GOTO	M_CNT3		; IF NOT EQUAL FORCE RESYNC

	MOVFW	TMP2		; COMPARE LOW BYTES OF EE COUNTER
	XORWF	TMP4,W
	SKPNZ				; IF NOT EQUAL FORCE RESYNC
	GOTO	M_SUB		; ELSE SUBSTRACT FROM RECEIVED 
					 	; .COUNTER VALUE

M_CNT3	
	GOTO	M_RESYNC	;强制重新同步, FORCE RESYNC (EE CNTERS INVALID)

; ************ 检查计数器窗口 ***********
M_SUB
	MOVFW	TMP2		; 16 BIT COUNTER SUBSTRACTION
	SUBWF	CNTR_LW,W
	MOVWF	TMP2			
	SKPC				; SKIP IF NO BORROW
	INCF	TMP1		; ... ELSE INCR HI BYTE
	MOVFW	TMP1
	SUBWF	CNTR_HI,W
	MOVWF	TMP1

	MOVFW	TMP1		; CHECK FOR REPEATED CODES 
	IORWF	TMP2,W
	SKPNZ				; IF NOT EQUAL CONTINUE
	GOTO	M_TZERO		; ELSE RESET EVENT COUNTER AND 
					    ; .WAIT FOR NEXT TX

M_CHECK0
	BTFSS	FLAGS,RESYNC	; TEST IF RESYNC ACTIVE
	GOTO	M_CHECK1		; IF NOT CHECK FOR COUNTER VALID

	BCF		FLAGS,RESYNC		; RESET RESYNC FLAG
	MOVFW	TMP1			; TEST IF IN 2 WINDOW (UPPER BYTE)
	SKPZ					; ELSE  ABORT
	GOTO	M_CNT_FAIL
	MOVLW	0FEH			; TEST IF CONSECUTIVE 
	ANDWF	TMP2,W			; .TRANSMISSIONS (LOW BYTE)
	SKPNZ					; IF NOT EQUAL COUNTER INVALID
	GOTO	M_UPDATE		; ELSE CNTR VALID, UPDATE EE CNTRS

M_CNT_FAIL
	CALL	CHK_PASS2		; TEST IF ON SECOND PASS OF LEARN
	SKPNZ				
	GOTO	RESET			; IF SO WIPE CURNT TX (USE RESET)
	GOTO	M_LOOP			; ELSE ABORT 

M_CHECK1
	BTFSC	TMP1,7			; TEST IF IN DARK REGION (> 7FFF)
	GOTO	M_LOOP			; IF SO IGNORE TRANSMISSION

	MOVFW	TMP1			; TEST FOR RESYNC REQUIRED
	SKPZ
	GOTO	M_RESYNC		;差别大过256,重新同步, DIFFERENCE > 256, FORCE RESYNC

	MOVFW	TMP2			; 16 BIT COUNTER ZERO
	SKPNZ					; 
	GOTO	M_LOOP			; COUNTERS EQUAL, IGNORE TX

M_CHECK2
	MOVLW	0F0H			; 测试16的窗口
	ANDWF	TMP2,W
	SKPNZ					; 如果没有ID值重新同步
	GOTO	M_UPDATE		; 否则更新EEPROM计数器

M_RESYNC
	BSF		FLAGS,RESYNC	; 指示需要重新同步
	MOVFW	CNTR_HI			; 存贮当前接收的16位的计数器.
	MOVWF	RAM_HI
	MOVFW	CNTR_LW
	MOVWF	RAM_LW
	GOTO	M_LOOP			; 等下次发射

; ***************** 更新存储器计数器,UPDATE EEPROM COUNTER *****************
M_UPDATE
	CALL	TX_LOOKUP		;获得当前的发射的基地址 GET CURRENT TX BASE ADDRESS
	MOVFW	CNTR_HI			;存储第一个16位的计数器 STORE FIRST 16-BIT RXED COUNTER
	MOVWF	TMP1
	MOVFW	CNTR_LW
	MOVWF	TMP2
	CALL	EEWRITE		;写低位序列号到存贮器, WRITE LSB WORD OF SER NR TO EE

	MOVFW	CNTR_HI			;存储第二个16位的计数器, STORE SECOND 16BIT RXED COUNTER
	MOVWF	TMP1
	MOVFW	CNTR_LW
	MOVWF	TMP2
	CALL	EEWRITE		;写高位序列号到存贮器, WRITE MSB WORD OF SER NR TO EE

	CALL	CHK_PASS2		; 测试如果第二次学习没通过,TEST IF ON SECOND PASS OF LEARN
	SKPNZ					; 如果没有继续,IF NOT CONTINUE
	GOTO	M_PTR			; ELSE UPDATE LEARN POINTER IN EE

	MOVLW	NORMAL			; TEST FOR NORMAL PROGRAM FLOW
	XORWF	SREG,W
	SKPNZ				
	GOTO	M_BUT			; IF EQU CHECK FOR F3 BUTTON
	GOTO	M_LOOP			; ELSE FLASH WAIT FOR NEXT TX

; **** MAYBE UPDATE LEARN POINTER AFTER VAILD SELFLEARN ****
M_PTR
    MOVLW	1H			; POINT TO LEARN POINTER
	MOVWF	ADDRESS
	CALL	EEREAD		; 从存贮器读学习指示器,READ LEARN POINTER FROM EEPROM

	MOVFW	TMP2		;复盖学习指示器,MASK LEARN POINTER
	ANDLW	07H			; 结果存在工作寄存器,和TMP2寄存器.STORE RESULT IN W REGISTER
	MOVWF	TMP2		; AND TMP2 REGISTER

	XORWF	TXNUM,W		; 学习现有的或新发射的.LEARNING EXISTING OR NEW TX
	SKPNZ				; 匹配吗? ,TXNUM EQUAL LRN PNTR FOR NEW TX
	INCF	TMP2		; IF NEW TX INCREMENT LRN POINTER

	MOVLW	6H			; TEST FOR LAST POSITION
	SUBWF	TMP2,W		; TEST FOR LAST POSITION
	SKPNC				; TEST FOR LAST POSITION
	CLRF	TMP2		; IF LAST POS POINT TO FIRST POS
	CLRF	TMP1		; ALWAYS CLR UP BYTE OF LRN POINTR

    MOVLW	1H			; 指向学习的位置.POINT TO LEARN POINTER
	MOVWF	ADDRESS
	CALL	EEWRITE		; 写学习指示器到存贮器.WRITE LEARN POINTER TO EEPROM

	MOVLW	NORMAL		; INDICATE NRMAL PGM FLOW
	MOVWF	SREG
	GOTO	LEARN_OK	; 指示成功

; *************** 测试接收到的按钮代码 ***************
M_BUT
	BCF		FLAGS,OUT_500		; ILEGAL BUTTON CODE, 
							; .RESET 500MS TIMER FLAG

	MOVFW	GPIO			; CHECK FOR TOGGLE OUTPUT ACTIVE
	ANDLW	0FH
	SKPNZ					; IF ACTIVE CHECK FOR NEW BUT CODE
	GOTO	M_ON			; ELSE UPDATE BUTTON OUTPUT

	MOVFW	FUNC			; CHECK FOR NEW BUT CODE WHILE 
	XORWF	OLD_BUT,W		; .OUTPUT PREVIOUS
	ANDLW	0F0H
	SKPNZ					;BTFSC 3,2 为1零跳 IF A NEW BCODE CLR OUTPUT 131MS
	GOTO	M_ON			;ELSE UPDATE OUTPUT

; ***** FORCE OUTPUT DOWN FOR 131 MS BEFORE NEW OUTPUT *****
M_OFF	
	MOVLW	070H			;CLEAR OUTPUTS ON PORTB
	ANDWF	GPIO,1

	MOVLW	130D			;WAIT 131 MS
	MOVWF	CNT1
	CALL	NTQ_LP1
M_ON
	CALL	BUT_LOOKUP		;读收到的按钮代码错误,
	MOVWF	ADDRESS			
	CALL	EEREAD		

	MOVFW	FUNC			;获得接收接钮代码
	XORWF	TMP1			;和存贮器比较  
	SKPZ
	GOTO	M_OUTPUT		;没有学习按钮代码	
	BSF		GPIO,B_LRN		;指示接收的按钮已经学习,

; ******** UPDATE OUTPUT WITH CURRENT BUTTON CODE *********
M_OUTPUT
	MOVFW	FUNC			;存贮当前接收到的按钮代码,
	MOVWF	OLD_BUT
	MOVLW	0F0H			;复盖按钮代码,屏蔽低4位
	ANDWF	FUNC,1
	SWAPF	FUNC,1			;从FUNC寄存器获得按钮代码,高低4位交换.	
	BTFSC	FUNC,0			;改变按钮输出, 
	BSF		FUNC,4			; [ S2 S1 S0 S3 ]
	CLRC				
	RRF		FUNC,W			
	IORWF	GPIO,1			;更新输出按钮代码, 
   	BSF     3,5
   	MOVLW   GPIOS
    MOVWF   TRISIO
    BCF     3,5   
M_END2	
   	BSF     3,5
   	MOVLW	000111B			;设置预分频,(1:256)
	MOVWF   OPTION_REG
    BCF     3,5
M_TZERO
	CLRF	CNT_HI			; 清除TIMERO时间
	CLRF	CNT_LW			
	CLRF	TMR0
M_END	
	GOTO	M_LOOP			; 待下一次发射信号

;--------------------------------------
	END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -