📄 12f629=keelog.asm
字号:
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 + -