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

📄 input_module.asm

📁 这个开发机器人项目源码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
IntStart movwf SavedW               ; Save W movf STATUS,w bcf STATUS,RP0             ; Make sure we're on Page 0 movwf SavedStatus          ; Save STATUS movf FSR,w movwf SavedFSR             ; Save FSR movf PCLATH,w movwf SavedPCLATH          ; Save PCLATH clrf PCLATH                ; Execution page 0 btfss INTCON,RBIF          ; IR signal? goto NotIR                 ; Jump if interrupt source is not IR; IR signal movf PORTB,w               ; Read Port B movwf PortBState           ; and save the state of Port B bcf INTCON,RBIF            ; Clear Port B interrupt flag bsf IRInterrupt,0; Check if we're already receiving from RF source.; If we are, and we're in state 1-3, override. movf RemoteReceiveState,f btfsc STATUS,Z goto HandleRemote          ; No need to override state=0 movlw 4 subwf RemoteReceiveState,w btfsc STATUS,Z goto HandleRemote          ; Don't override state=4 movlw 5 subwf RemoteReceiveState,w btfsc STATUS,Z goto HandleRemote          ; Don't override state=5 btfss RemoteReceiveMask,0  ; RF or IR? goto HandleRemote          ; IR; At this point, we've established that we're in the middle of receiving ; an RF packet (or RF noise). movlw 0x0F0 andwf PortBState,w xorlw 0x0F0 btfsc STATUS,Z goto HandleRemote          ; IR bits all high -no need to override RF; IR low signal seen - IR overrides RF remote clrf RemoteReceiveState    ; Go back to state 0 bcf INTCON,T0IE            ; Disable timer interruptHandleRemote movf RemoteReceiveState,w addwf PCL, f               ; Jump according to value in wIrJumpTable goto AwaitingLeaderStart   ; RemoteReceiveState = 0 goto AwaitingIRLeaderEnd   ; RemoteReceiveState = 1 goto AwaitingIRSyncBit     ; RemoteReceiveState = 2 goto AwaitingIRDataBit     ; RemoteReceiveState = 3 goto AwaitingScanCodeTx    ; RemoteReceiveState = 4 goto AwaitingIRStop        ; RemoteReceiveState = 5 IF ((HIGH($)) != (HIGH(IrJumpTable)))     ERROR("IR Jump Table crosses page boundary!") ENDIFAwaitingLeaderStart         ; State = 0 movf PortBState,w btfsc PortBState,0         ; RF In leader? goto NotRFIn; RF In Leader started movf IRInterrupt,f btfss STATUS,Z goto NotRFIn               ; Servicing IR interrupt - ignore bit 0 of port B movlw 0x01                 ; Only look at bit 0 goto LeaderStartedNotRFIn movf IRInterrupt,f btfsc STATUS,Z goto FinishISR             ; Servicing RF interrupt - nothing more to do btfsc PortBState,4         ; IR detector # 1 leader? goto NotIR1                ; Jump if no leader detected on IR # 1; IR # 1 Leader started movlw 0x10                 ; Only look at bit 4 goto LeaderStartedNotIR1 btfsc PortBState,5         ; IR detector # 2 leader? goto NotIR2; IR # 2 Leader started movlw 0x20                 ; Only look at bit 5 goto LeaderStartedNotIR2 btfsc PortBState,6         ; IR detector # 3 leader? goto NotIR3; IR # 3 Leader started movlw 0x40                 ; Only look at bit 6 goto LeaderStartedNotIR3 btfsc PortBState,7         ; IR detector # 4 leader? goto NotIR4; IR # 4 Leader started movlw 0x80                 ; Only look at bit 7 goto LeaderStartedNotIR4; All 4 IR detector signals high; remain in state 0 goto FinishISRLeaderStarted movwf RemoteReceiveMask     btfsc RemoteReceiveMask,0  ; RF or IR? goto Leader2               ; RF; IR bcf INTCON,INTE            ; Disable RF interruptsLeader2 movlw 8                    ; Each frame has 12 bits, but we only want 1st 8 movwf RemoteReceiveBitCount clrf RemoteReceiveByte movlw 1 movwf RemoteReceiveState   ; Next state is 1 movlw 0x100 - (ONE_MS_DELAY * 3) movwf TMR0                 ; Set timeout to 3ms bcf INTCON,T0IF bsf INTCON,T0IE            ; Enable timer interrupt goto FinishISRAwaitingIRLeaderEnd         ; State = 1 movf PortBState,w andwf RemoteReceiveMask,w  ; Only interested in one remote signal btfsc STATUS,Z             ; signal gone high?; Signal low goto FinishISR             ; ignore signals from other sensors; Signal high movlw 0x100 - (ONE_MS_DELAY * 3) + (ONE_MS_DELAY * 15/10) subwf TMR0,w btfss STATUS,C goto CodeNotRecognised     ; Start bit too short (<1.5ms) - abort packetNextStateSync movlw 2 movwf RemoteReceiveState   ; Next state is 2 (wait for end of sync) movlw 0x100 - (ONE_MS_DELAY * 1) movwf TMR0                 ; Set timeout to 1ms bcf INTCON,T0IF bsf INTCON,T0IE            ; Enable timer interrupt goto FinishISRAwaitingIRSyncBit           ; State = 2 movf PortBState,w andwf RemoteReceiveMask,w  ; Only interested in one remote signal btfss STATUS,Z             ; signal gone low?; Signal high goto FinishISR             ; ignore signals from other sensors; Signal Low movlw 0x100 - (ONE_MS_DELAY * 1) + (ONE_MS_DELAY/2) subwf TMR0,w btfss STATUS,C goto CodeNotRecognised     ; Sync too short (< 0.5ms) - abort packet movlw 3 movwf RemoteReceiveState   ; Next state is 3 (wait for end of data bit) movlw 0x100 - (ONE_MS_DELAY * 2) movwf TMR0                 ; Set timeout to 2ms bcf INTCON,T0IF bsf INTCON,T0IE            ; Enable timer interrupt goto FinishISRAwaitingIRDataBit           ; State = 3 movf PortBState,w andwf RemoteReceiveMask,w  ; Only interested in one remote signal btfsc STATUS,Z             ; signal gone high?; Signal low goto FinishISR             ; ignore signals from other sensors; Signal high movlw 0x100 - (ONE_MS_DELAY * 2) + (ONE_MS_DELAY/2) subwf TMR0,w btfss STATUS,C goto CodeNotRecognised     ; data bit too short (< 0.5ms) - abort packet movlw 0x100 - (ONE_MS_DELAY * 2) + (ONE_MS_DELAY) subwf TMR0,w; At this point, the Carry flag is set for data=1 and clear for data=0 rrf RemoteReceiveByte,f    ; Shift Carry flag into received byte register decfsz RemoteReceiveBitCount,f goto NextStateSync; All bits received bcf INTCON,T0IE            ; Disable timer interrupt btfss RemoteReceiveMask,0  ; RF or IR? goto CheckIRCode           ; IR goto CheckRFCode           ; RFCheckIRCode movf RemoteReceiveByte,w andlw 0x0E0 sublw 0x080 btfss STATUS,Z goto CodeNotRecognised     ; Top 3 bits not correct in IR received byte goto CheckCommandCodeCheckRFCode; RF - check Robot ID Code movf RemoteReceiveByte,w andlw 0xE0 movwf ReceivedRobotCode call GetRobotCodeFromEEPROM subwf ReceivedRobotCode,w btfss STATUS,Z goto CodeNotRecognised     ; Different Robot IDCheckCommandCode call IRScanCode2Table iorlw 0 btfsc STATUS,Z goto CodeNotRecognised; Valid IR codeValidCode movwf ScanCode2 call IRScanCode1Table movwf ScanCode1 goto RemoteDoneCodeNotRecognised; IR/RF Code not recognised, different RF Robot ID, or timing error. clrf RemoteReceiveState    ; Set next state back to 0 bcf INTCON,T0IE            ; Disable timer interrupt call IsRFEnabled btfsc STATUS,Z bsf INTCON,INTE            ; Enable RB0/INT Pin interrupt goto FinishISRRemoteDone  movlw 4                    ; Next state is 4 (wait for scan code send) movwf RemoteReceiveState    goto FinishISRAwaitingScanCodeTx          ; State = 4 goto FinishISR             ; Ignore remote signals until scan code sentAwaitingIRStop              ; State = 5 movf PortBState,w andwf RemoteReceiveMask,w  ; Only interested in one remote signal btfss STATUS,Z             ; signal gone low?; Signal high goto FinishISR             ; ignore signals from other sensors or going hi; Signal Low movlw REMOTE_STOP_DELAY movwf RemoteStopCounter    ; IR activity sensed - reset counter movlw 0x100 - ONE_MS_DELAY movwf TMR0                 ; Set timeout to 1ms goto FinishISRNotIR btfss INTCON,T0IF          ; Timer timeout? goto NotTimer              ; Jump if interrupt source is not Timer btfss INTCON,T0IE          ; Is timer enabled? goto NotTimer              ; No; Timer timeoutResetRemoteRx bcf INTCON,T0IF            ; Clear Timer interrupt flag movf RemoteReceiveState,w sublw 5 btfss STATUS,Z goto NotAwaitingIRStop; Awaiting IR Stop decfsz RemoteStopCounter,f ; Have we seen 50ms of "silence" yet? goto ContinueIRStop        ; NoNotAwaitingIRStop           ; Yes clrf RemoteReceiveState    ; Back to state 0 bcf INTCON,T0IE            ; Disable timer interrupt call IsRFEnabled btfsc STATUS,Z bsf INTCON,INTE                ; Enable RB0/INT Pin interrupt goto FinishISRContinueIRStop movlw 0x100 - ONE_MS_DELAY movwf TMR0                 ; Set timeout to 1ms goto FinishISRNotTimer btfss INTCON,INTF          ; RF signal? goto NotRF                 ; Jump if interrupt source is not RF btfss INTCON,INTE          ; RF enabled? goto NotRF                 ; No; RF signal movf PORTB,w               ; Read Port B movwf PortBState           ; and save the state of Port B btfss PortBState,0 goto RFInLow; RF In is High bsf STATUS,RP0 bcf OPTION_REG^0x080,INTEDG    ; Interrupt when RB0 goes High to Low bcf STATUS,RP0 goto RFInDoneRFInLow bsf STATUS,RP0 bsf OPTION_REG^0x080,INTEDG    ; Interrupt when RB0 goes Low to High bcf STATUS,RP0RFInDone bcf INTCON,INTF            ; Clear RF interrupt flag clrf IRInterrupt goto HandleRemoteNotRF; It should not be possible to reach here as we've tested for all possible; interrupt sources! FinishISR movf SavedPCLATH,w movwf PCLATH               ; Restore PCLATH movf SavedFSR,w movwf FSR                  ; Restore FSR movf SavedStatus,w movwf STATUS               ; Restore STATUS swapf SavedW,f swapf SavedW,w             ; Restore W (without affecting Z,C flags,etc) retfie; ----------------------------------------------------------------------; Main Program start pointMainStart call CheckEEPROMSettings   ; Check if nonvolatile settings are valid call InitIO                ; Initialize IO ports clrf RemoteReceiveState    ; Waiting for IR or RF remote leader call InitTimer             ; Initialize Timer; Perform dummy "Basic Assurance Test" (BAT) to satisfy protocol call BAT call InitInterrupts        ; Initialize interrupts; Look for keypad keypressWaitForKeyDownLoop bsf STATUS,RP0 bsf STROBE1_DIRECTION      ; Strobe 1 Hi-Z bsf STROBE2_DIRECTION      ; Strobe 2 Hi-Z bcf STATUS,RP0 ; Check for remote data movlw 4 subwf RemoteReceiveState,w btfss STATUS,Z             ; Any remote scan codes to send? goto NoRemoteData; Send remote scan code bcf INTCON,GIE call SendScanCode movlw REMOTE_STOP_DELAY movwf RemoteStopCounter     movlw 5 movwf RemoteReceiveState   ; Change remote state to 5 movlw 0x100 - ONE_MS_DELAY movwf TMR0                 ; Set timeout to 1ms bsf INTCON,T0IE            ; Enable timer interrupt bsf INTCON,GIENoRemoteData call Delay10ms btfsc KEYBOARD_DATA        ; Check if host wants to talk to us goto WaitDown1 bcf INTCON,GIE call ReceiveFromHost bsf INTCON,GIE addwf PCL, f               ; Jump according to value in w; Next 3 instructions constitute a jump table goto WaitForKeyDownLoop    ; w=0 goto WaitForKeyDownLoop    ; w=1: Reset bcf INTCON,GIE             ; w=2: Resend IF ((HIGH($)) != (HIGH($-3)))     ERROR("Table crosses page boundary!") ENDIF call SendScanCode bsf INTCON,GIE goto WaitForKeyDownLoopWaitDown1 call Delay10ms btfsc KEYBOARD_DATA        ; Check if host wants to talk to us goto WaitDown2 bcf INTCON,GIE call ReceiveFromHost bsf INTCON,GIE addwf PCL, f               ; Jump according to value in w; Next 3 instructions constitute a jump table goto WaitForKeyDownLoop    ; w=0 goto WaitForKeyDownLoop    ; w=1: Reset bcf INTCON,GIE             ; w=2: Resend IF ((HIGH($)) != (HIGH($-3)))     ERROR("Table crosses page boundary!") ENDIF call SendScanCode           bsf INTCON,GIE goto WaitForKeyDownLoopWaitDown2   bcf STROBE1 bsf STATUS,RP0 bcf STROBE1_DIRECTION      ; Energize Strobe 1 bcf STATUS,RP0 btfsc KEYPAD_COL1 goto KeyWaitCol2A movlw ESCAPE_SCAN_CODE1 movwf ScanCode1 movlw ESCAPE_SCAN_CODE2

⌨️ 快捷键说明

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