📄 power_management_module.asm
字号:
movf Timer0,w btfss STATUS,Z goto $-2 ; Delay 1/6s bcf EXT_SUPPLY_RELAY ; turn off external supply relay bsf GREEN_LED ; turn off green LED movlw TURN_OFF_EXT_COMMAND ; tell docking station ext supply off call BeamToDockingStation movlw TMR0_ONE_SEC * 1 movwf Timer0 movlw 1 movwf State ; Go to state 1 next goto MainLoopState3SwitchesClosed movf Timer1,w btfss STATUS,Z goto State3VoltageOK; Vb less than Vo for >= 1 minute movlw TURN_OFF_CHARGER_COMMAND ; tell docking station to stop charging call BeamToDockingStation movlw TMR0_ONE_SEC / 6 movwf Timer0 movf Timer0,w btfss STATUS,Z goto $-2 ; Delay 1/6s bcf CHARGER_RELAY ; turn off charging relay movlw TMR0_ONE_SEC / 6 movwf Timer0 movf Timer0,w btfss STATUS,Z goto $-2 ; Delay 1/6s bcf EXT_SUPPLY_RELAY ; turn off external supply relay bsf GREEN_LED ; turn off green LED movlw TURN_OFF_EXT_COMMAND ; tell docking station ext supply off call BeamToDockingStation bcf RED_LED ; turn on red LED movlw 2 movwf ErrorCode movlw 4 movwf State ; Change to state 4 goto MainLoopState3VoltageOK movf Vo,w subwf Vb,w ; Calculate Vb-Vo btfss STATUS,C goto MainLoop ; Vb < Vo; Vb >= Vo movlw TMR1_ONE_SEC * 60 movwf Timer1 goto MainLoop; --- Error StateState4 goto MainLoop; ----------------------------------------------------------------------; Subroutines; ----------------------------------------------------------------------; Global interrupts are assumed to be disabled before this subroutine is calledWriteGoodExtVoltageEeprom bsf STATUS,RP1 bcf STATUS,RP0 movwf EEDATA^0x100 movlw GOOD_EXT_VOLTAGE_EE_ADDR movwf EEADR^0x100 bsf STATUS,RP0 bsf STATUS,RP1 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; ----------------------------------------------------------------------GetGoodExtVoltageEeprom bsf STATUS,RP1 bcf STATUS,RP0 movlw GOOD_EXT_VOLTAGE_EE_ADDR movwf EEADR^0x100 bsf STATUS,RP0 bsf STATUS,RP1 bcf EECON1^0x180,EEPGD bsf EECON1^0x180,RD bsf STATUS,RP1 bcf STATUS,RP0 movf EEDATA^0x100,w bcf STATUS,RP0 bcf STATUS,RP1 return; ----------------------------------------------------------------------BeamToDockingStation movwf IRData call SendCode call SendCode call SendCode call Delay10ms call Delay10ms call Delay10ms return; ----------------------------------------------------------------------SendCode; Send HI for 10ms call IROff ; HI call Delay10ms call IROn ; LO call Delay0_7ms call Delay0_7ms call Delay0_7ms ; Start bit - low for 2.1ms call IROff ; HI movf IRData,w movwf SendBuffer movlw 8 movwf BitCountSendLoop call Delay0_7ms ; Sync gap - high for 0.7ms call IROn ; LO rrf SendBuffer,f btfss STATUS,C goto SendZero; Send One call Delay0_7ms call Delay0_7ms goto SentBitSendZero call Delay0_7msSentBit call IROff ; HI decfsz BitCount,f goto SendLoop call Delay10ms call Delay10ms ; Finish with 20ms delay return; ----------------------------------------------------------------------ReadVoltages movlw b'01011001' ; Select AN3 (batt voltage) movwf ADCON0; Wait required acquisition time call ADCDelay bsf ADCON0,GO_DONE ; Start conversion btfsc ADCON0,GO_DONE goto $-1 movf ADRESH,w ; Get result movwf Vb movlw b'01001001' ; Select AN1 (ext voltage) movwf ADCON0; Wait required acquisition time call ADCDelay bsf ADCON0,GO_DONE ; Start conversion btfsc ADCON0,GO_DONE goto $-1 movf ADRESH,w ; Get result movwf Ve movlw b'01000001' ; Select AN0 (charge voltage) movwf ADCON0; Wait required acquisition time call ADCDelay bsf ADCON0,GO_DONE ; Start conversion btfsc ADCON0,GO_DONE goto $-1 movf ADRESH,w ; Get result movwf Vc movlw b'01000000' ; Shut off ADC movwf ADCON0 return; ----------------------------------------------------------------------ReadSwitches movf PORTB,w andlw SWITCH_MASK movwf SwitchState return; ----------------------------------------------------------------------ADCDelay ; 20 microsecond delay nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop return; ----------------------------------------------------------------------Delay10ms movlw HIGH((10000 / 5) + 256) movwf HiCount movlw LOW((10000 / 5) + 256)DelayLoop2 addlw 0x0FF btfsc STATUS, Z decfsz HiCount, f goto DelayLoop2 return; ----------------------------------------------------------------------Delay0_7ms movlw HIGH((700 / 5) + 256) movwf HiCount movlw LOW((700 / 5) + 256)DelayLoop3 addlw 0x0FF btfsc STATUS, Z decfsz HiCount, f goto DelayLoop3 return; ----------------------------------------------------------------------IROn movlw b'00101100' movwf CCP1CON return; ----------------------------------------------------------------------IROff movlw b'00100000' movwf CCP1CON return; ----------------------------------------------------------------------InitClock bsf STATUS,RP0 bcf STATUS,RP1 movlw 0x060 ; Select 4MHz internal clock. movwf OSCCON^0x080 bcf STATUS,RP0 return; ----------------------------------------------------------------------InitInterrupts; Enable interrupts. bsf STATUS,RP0 bcf STATUS,RP1 bsf PIE1^0x080,TMR1IE ; Enable timer 1 interrupt bsf PIE1^0x080,SSPIE ; Enable I2C interrupt bcf STATUS,RP0 clrf INTCON bsf INTCON,PEIE ; Enable unmasked peripheral interrupts bsf INTCON,TMR0IE ; Enable timer 0 interrupt bsf INTCON,GIE ; Global Interrupt Enable return; ----------------------------------------------------------------------InitTimer; Set timer 0 to 1/15s period 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 bsf OPTION_REG^0x080,PS0 bsf OPTION_REG^0x080,PS1 bsf OPTION_REG^0x080,PS2 ; Set timer 0 prescaler bcf STATUS,RP0; Set timer 1 to 1/4s period bcf T1CON,T1CKPS0 bsf 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; Set timer 2 with PR2 for 40kHz IR frequency generation bsf STATUS,RP0 bcf STATUS,RP1 movlw 24 movwf PR2^0x080 bcf STATUS,RP0 ; Set up CCP for PWM movlw 12 movwf CCPR1L movlw b'00100000' ; PWM off initially - call IROn to turn on movwf CCP1CON movlw b'00000100' movwf T2CON return; ----------------------------------------------------------------------InitIO; Set port A and B data directions movlw b'00010100' ; Initialize data bits movwf PORTA clrf PORTB bsf STATUS,RP0 bcf STATUS,RP1 bcf OPTION_REG^0x080,NOT_RBPU ; Enable Port B internal pull-up resistors. movlw b'00101011' ; Set Port A data direction bits. movwf TRISA^0x080 movlw b'11010011' ; Set Port B data direction bits. movwf TRISB^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^0x80 ; I2C slave address of this device bcf STATUS,RP0 bsf SSPCON,SSPEN ; Enable I2C return; ----------------------------------------------------------------------InitADC bsf STATUS,RP0 bcf STATUS,RP1 movlw b'00000100' movwf ADCON1^0x80 bcf STATUS,RP0 return; ----------------------------------------------------------------------; End end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -