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

📄 sonar_array_module.asm

📁 这个开发机器人项目源码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; Sonars 1,3,5,7,9,11,13,15 movf CurrentChanM1,w           ; Sonar number in range 0 to 15 movwf FSR rlf FSR,f rlf FSR,f                      ; Multiply by 4 movlw b'11111100' andwf FSR,f                    ; Make sure 2 LSbits clear movlw SonarDataTable addwf FSR,f                    ; Add to table start address movf CCPR2L,w movwf INDF incf FSR,f movf CCPR2H,w movwf INDF incf FSR,f movf Timer0,w movwf INDFFinishCCP2 return; ---------------------------------------------------------------------- nop        ; Padding to prevent table crossing page boundary nop nop nop nop nop; ----------------------------------------------------------------------ProcessI2C btfsc SSPCON,SSPOV             ; Check overflow bit bcf SSPCON,SSPOV               ; Make sure overflow bit is clear bsf STATUS,RP0                 ; Select Page 1 movf SSPSTAT^0x080,w           ; Get I2C status (SSPSTAT register) bcf STATUS,RP0                 ; Back to page 0 andlw b'00101101'              ; Mask for interesting bits in SSPSTAT movwf SspStatSaved             ; Save the result in a variable movlw b'00001001'               subwf SspStatSaved,w btfss STATUS,Z                 ; Is it I2C State 1 (Write, last byte address)? goto I2CNotState1; Write, last byte is address (I2C State 1) movf SSPBUF,w                  ; Read receive buffer byte (clear BF) movwf I2CRxByte                ; Save received byte clrf SMBusState                ; Expecting SMBus command code next goto FinishI2C                 ; Nothing more to do in this stateI2CNotState1 movlw b'00101001'              ; Is it I2C State 2 (Write, last byte data)? subwf SspStatSaved,w btfss STATUS,Z goto I2CNotState2              ; No; Write, last byte data (I2C State 2) movf SSPBUF,w                  ; Read receive buffer byte (clear BF) movwf I2CRxByte                ; Save received byte movlw HIGH($+4) movwf PCLATH movf SMBusState,w addwf PCL,f                    ; Jump table for SMBus state goto I2CState2SMBusState0 goto I2CState2SMBusState1 goto I2CState2SMBusState2 goto I2CState2SMBusState3 goto I2CState2SMBusState4 goto I2CState2SMBusState5 IF ((HIGH($)) != (HIGH($-6)))     ERROR("Table crosses page boundary!") ENDIFI2CState2SMBusState0            ; SMBus State 0 (expecting command byte next) movf I2CRxByte,w movwf SMBusCommand             ; Save SMBus command code sublw SET_TIMER_ZERO_COMMAND btfss STATUS,Z goto NotSetTimerZeroCommand; Set Timer Zero command (Send Byte) clrf Timer0 movlw 256 - 125 movwf TMR0 clrf SMBusState goto FinishI2CNotSetTimerZeroCommand movf SMBusCommand,w sublw SET_SONAR_POWER_ON_COMMAND btfss STATUS,Z goto NotSetSonarPowerOnCommand; Set Sonar Power On Command (Send Byte) bsf SonarPowerState,0 clrf SMBusState goto FinishI2CNotSetSonarPowerOnCommand movf SMBusCommand,w sublw SET_SONAR_POWER_OFF_COMMAND btfss STATUS,Z goto NotSetSonarPowerOffCommand; Set Sonar Power Off Command (Send Byte) clrf SonarPowerState call ClearSonarDataTable clrf SMBusState goto FinishI2CNotSetSonarPowerOffCommand movf SMBusCommand,w sublw SET_NUM_SONARS_COMMAND btfss STATUS,Z goto NotSetNumSonarsCommand; Set Num Sonars Command movlw 1 movwf SMBusState               ; Next SMBus state = 1 goto FinishI2CNotSetNumSonarsCommand movf SMBusCommand,w sublw GET_NUM_SONARS_COMMAND btfss STATUS,Z goto NotGetNumSonarsCommand; Get Num Sonars Command movlw 1 movwf SMBusState               ; Next SMBus state = 1 goto FinishI2CNotGetNumSonarsCommand movf SMBusCommand,w sublw GET_SONAR_POWER_STATE_COMMAND btfss STATUS,Z goto NotGetSonarPowerStateCommand; Get Sonar Power State Command movlw 1 movwf SMBusState               ; Next SMBus state = 1 goto FinishI2CNotGetSonarPowerStateCommand; Assume it's a GET_SONAR_READING_COMMAND movlw 2 movwf SMBusState               ; Next SMBus state = 2 goto FinishI2CI2CState2SMBusState1            ; SMBus state 1 (transferring data byte) movf SMBusCommand,w sublw SET_NUM_SONARS_COMMAND btfss STATUS,Z goto NotSetNumSonarsCommand2; Set Num Sonars Command movf I2CRxByte,w movwf NumEnabledChans call WriteNumEnabledChansEEPROM clrf SMBusState        goto FinishI2CNotSetNumSonarsCommand2 clrf SMBusState          goto FinishI2CI2CState2SMBusState2            ; SMBus state 2 (transferring num data bytes) clrf SMBusState goto FinishI2CI2CState2SMBusState3            ; SMBus state 3 (1st data byte in block) clrf SMBusState goto FinishI2CI2CState2SMBusState4            ; SMBus state 4 (2nd data byte in block) clrf SMBusState goto FinishI2CI2CState2SMBusState5            ; SMBus state 5 (3rd data byte in block) clrf SMBusState goto FinishI2CI2CNotState2 movlw b'00001100'              ; I2C state 3 (Read, last byte address)? subwf SspStatSaved,w btfss STATUS,Z goto I2CNotState3              ; No; Read, last byte address (I2C State 3) movlw HIGH($+4) movwf PCLATH movf SMBusState,w addwf PCL,f                    ; SMBus state jump table goto I2CState3SMBusState0 goto I2CState3SMBusState1 goto I2CState3SMBusState2 goto I2CState3SMBusState3 goto I2CState3SMBusState4 goto I2CState3SMBusState5 IF ((HIGH($)) != (HIGH($-6)))     ERROR("Table crosses page boundary!") ENDIFI2CState3SMBusState0 movlw 0                        ; Shouldn't be here, but the master is call WriteI2C                  ; expecting data, so we must oblige. goto FinishI2C                 I2CState3SMBusState1            ; SMBus state 1 (transferring data byte) movf SMBusCommand,w sublw GET_NUM_SONARS_COMMAND btfss STATUS,Z goto NotGetNumSonarsCommand3; Get Num Sonars Command movf NumEnabledChans,w call WriteI2C clrf SMBusState goto FinishI2CNotGetNumSonarsCommand3 movf SMBusCommand,w sublw GET_SONAR_POWER_STATE_COMMAND btfss STATUS,Z goto NotGetSonarPowerState3; Get Sonar Power State movf SonarPowerState,w call WriteI2C clrf SMBusState goto FinishI2CNotGetSonarPowerState3  movlw 0                        ; Shouldn't be here, but the master is call WriteI2C                  ; expecting data, so we must oblige. goto FinishI2C                 I2CState3SMBusState2            ; SMBus state 2 (num bytes) movf SMBusCommand,w sublw GET_SONAR_READING_COMMAND_MAX btfss STATUS,C                 ; Skip if command <= maximum reading command goto I2CState3SMBusState2NotValid; SMBusCommand <= GET_SONAR_READING_COMMAND_MAX; Now check minimum movlw GET_SONAR_READING_COMMAND_MIN subwf SMBusCommand,w btfss STATUS,C                 ; Skip if command >= minimum reading command goto I2CState3SMBusState2NotValid; SMBusCommand >= GET_SONAR_READING_COMMAND_MIN; Sonar reading command is valid movlw 3 call WriteI2C movlw 3 movwf SMBusState               ; Next byte to transfer should be data goto FinishI2C I2CState3SMBusState2NotValid movlw 0                        ; Shouldn't be here, but the master is call WriteI2C                  ; expecting data, so we must oblige. goto FinishI2C                 I2CState3SMBusState3            ; SMBus state 3 (1st data - block read) movlw 0                        ; Shouldn't be here, but the master is call WriteI2C                  ; expecting data, so we must oblige. goto FinishI2C                 I2CState3SMBusState4            ; SMBus state 4 (2nd data - block read) movlw 0                        ; Shouldn't be here, but the master is call WriteI2C                  ; expecting data, so we must oblige. goto FinishI2C                 I2CState3SMBusState5            ; SMBus state 5 (3rd data - block read) movlw 0                        ; Shouldn't be here, but the master is call WriteI2C                  ; expecting data, so we must oblige. goto FinishI2C                 I2CNotState3 movlw b'00101100'              ; I2C state 4 (Read, last byte data)? subwf SspStatSaved,w btfss STATUS,Z goto I2CNotState4              ; No; Read, last byte data (I2C State 4) movlw HIGH($+4) movwf PCLATH movf SMBusState,w addwf PCL,f                    ; SMBus state jump table goto I2CState4SMBusState0 goto I2CState4SMBusState1 goto I2CState4SMBusState2 goto I2CState4SMBusState3 goto I2CState4SMBusState4 goto I2CState4SMBusState5 IF ((HIGH($)) != (HIGH($-6)))     ERROR("Table crosses page boundary!") ENDIFI2CState4SMBusState0 movlw 0                        ; Shouldn't be here, but the master is call WriteI2C                  ; expecting data, so we must oblige. goto FinishI2C                 I2CState4SMBusState1 movlw 0                        ; Shouldn't be here, but the master is call WriteI2C                  ; expecting data, so we must oblige. goto FinishI2C                 I2CState4SMBusState2 movlw 0                        ; Shouldn't be here, but the master is call WriteI2C                  ; expecting data, so we must oblige. goto FinishI2C                 I2CState4SMBusState3            ; SMBus state 3 (1st data - block read) btfss SonarPowerState,0 goto I2CState4SMBusState3PowerOff decf SMBusCommand,w            ; Sonar number in range 0 to 15 movwf FSR rlf FSR,f rlf FSR,f                      ; Multiply by 4 movlw b'11111100' andwf FSR,f                    ; Make sure 2 LSbits clear movlw SonarDataTable addwf FSR,f                    ; Add to table start address movf INDF,w movwf SonarBuffer0             ; Capture current sonar reading incf FSR,f movf INDF,w movwf SonarBuffer1 incf FSR,f movf INDF,w movwf SonarBuffer2SendFirstDataByte movf SonarBuffer0,w call WriteI2C movlw 4 movwf SMBusState goto FinishI2C                 I2CState4SMBusState3PowerOff clrf SonarBuffer0              ; When power's off, send 0,0,0 clrf SonarBuffer1 clrf SonarBuffer2 goto SendFirstDataByteI2CState4SMBusState4            ; SMBus state 4 (2nd data - block read) movf SonarBuffer1,w call WriteI2C movlw 5 movwf SMBusState goto FinishI2C                 I2CState4SMBusState5            ; SMBus state 5 (3rd data - block read) movf SonarBuffer2,w call WriteI2C clrf SMBusState goto FinishI2C                 I2CNotState4 movlw b'00101000'              ; Nack received from master after reading data? subwf SspStatSaved,w btfss STATUS,Z goto FinishI2C                 ; No. Impossible state.; Nack received from master (I2C State 5) clrf SMBusState                ; SMBus state is expecting command nextFinishI2C return; ----------------------------------------------------------------------WriteI2C bsf STATUS,RP0 btfsc SSPSTAT^0x080,BF         ; Buffer full? goto $-1                       ; Spin until it isn't bcf STATUS,RP0 bcf SSPCON,WCOL                ; Clear write collision flag movwf SSPBUF btfsc SSPCON,WCOL              ; Did collision occur? goto $-3 bsf SSPCON,CKP                 ; Release clock  return; ----------------------------------------------------------------------ClearSonarDataTable movlw SonarDataTable movwf FSR movlw 64 movwf CounterClearLoop clrf INDF incf FSR,f decfsz Counter,f goto ClearLoop return; ----------------------------------------------------------------------; Global interrupts are assumed to be disabled before this subroutine is calledWriteNumEnabledChansEEPROM bsf STATUS,RP1 bcf STATUS,RP0 movwf EEDATA^0x100 movlw NUM_ENABLED_CHANS_EE_ADDR movwf EEADR^0x100 bsf STATUS,RP0 bcf EECON1^0x180,EEPGD bsf EECON1^0x180,WREN movlw 0x055 movwf EECON2^0x180 movlw 0x0AA movwf EECON2^0x180 bsf EECON1^0x180,WR btfsc EECON1^0x180,WR goto $-1 bcf EECON1^0x180,WREN bcf STATUS,RP0 bcf STATUS,RP1 return; ----------------------------------------------------------------------GetNumEnabledChansEEPROM bsf STATUS,RP1 bcf STATUS,RP0 movlw NUM_ENABLED_CHANS_EE_ADDR movwf EEADR^0x100 bsf STATUS,RP0 bcf EECON1^0x180,EEPGD bsf EECON1^0x180,RD bcf STATUS,RP0 movf EEDATA^0x100,w bcf STATUS,RP1 return; ----------------------------------------------------------------------Delay10us nop nop nop nop nop nop nop nop nop nop return; ----------------------------------------------------------------------InitInterrupts; Enable interrupts.  bsf STATUS,RP0 bcf STATUS,RP1 bsf PIE1^0x080,SSPIE           ; Enable I2C interrupt bsf PIE1^0x080,CCP1IE          ; Enable CCP1 interrupt bsf PIE2^0x080,CCP2IE          ; Enable CCP2 interrupt bcf STATUS,RP0 clrf INTCON bsf INTCON,PEIE                ; Enable unmasked peripheral interrupts  bsf INTCON,T0IE                ; Enable timer 0 interrupt bsf INTCON,GIE                 ; Global Interrupt Enable return; ----------------------------------------------------------------------InitCapture movlw b'00000101'              ; Capture mode every rising edge. movwf CCP1CON movwf CCP2CON bcf PIR1,CCP1IF                ; Clear any possible false interrupt. bcf PIR2,CCP2IF                ; Clear any possible false interrupt. return; ----------------------------------------------------------------------InitTimer; Configure timer 0 bsf STATUS,RP0 bcf STATUS,RP1 bcf OPTION_REG^0x080,T0CS      ; Select Timer 0 Mode bcf OPTION_REG^0x080,PSA       ; Assign prescaler to Timer 0 bcf OPTION_REG^0x080,PS0 bsf OPTION_REG^0x080,PS1 bcf OPTION_REG^0x080,PS2       ; Set timer 0 prescaler bcf STATUS,RP0 movlw 256 - 125 movwf TMR0 movlw 25 movwf Timer0tmp; Set timer 1 to 1 microsecond period bcf T1CON,T1CKPS0 bcf T1CON,T1CKPS1              ; Set timer 1 prescaler bcf T1CON,T1OSCEN              ; Disable built-in oscillator bcf T1CON,TMR1CS               ; Use Fosc/4 as source for timer 1 bsf T1CON,TMR1ON               ; Turn on timer 1 return; ----------------------------------------------------------------------InitIO; Initialize port A, B and C clrf PORTA clrf PORTB clrf PORTC bsf STATUS,RP0 bcf STATUS,RP1 movlw b'00000110' movwf ADCON1^0x80              ; Not using ADC - set to I/O clrf TRISA^0x080 clrf TRISB^0x080  movlw b'00011110' movwf TRISC^0x080 bcf STATUS,RP0 return; ----------------------------------------------------------------------InitI2C clrf SMBusState bcf SSPCON,SSPM3               ; SSPM<3:0> = 0110 bsf SSPCON,SSPM2               ; (7-bit address slave mode) bsf SSPCON,SSPM1 bcf SSPCON,SSPM0 bsf SSPCON,CKP                 ; SCK release control: Enable Clock bcf SSPCON,SSPOV               ; Make sure overflow bit is clear movf SSPBUF,w                  ; Read SSPBUF to ensure buffer flag BF is clear movlw I2C_ADDRESS << 1 bsf STATUS,RP0 bcf STATUS,RP1 movwf SSPADD^0x080             ; I2C slave address of this device bcf SSPSTAT^0x080,CKE          ; Select I2C input levels bsf SSPSTAT^0x080,SMP          ; Slew rate control disabled bcf STATUS,RP0 bsf SSPCON,SSPEN               ; Enable I2C return; ----------------------------------------------------------------------; End end

⌨️ 快捷键说明

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