comwarrior
- 30th July 2012, 01:12
OK, been trying to figure this out for over a week now...
I'm trying to create a charge controller/balancer for LI-POL / LI-ION battery packs.
I started with the 16F1824 but it was doing weird things so i switched to an 18F46K22 and hooked up an LCD for diagnostics.
I even tried two known working 18K46K22's just incase it was a damaged chip.
The circuit at the moment is simple. 2 LI-IONs (for testing) linked in series. 5V supply to PIC and LCD VIA L7805CV fed from both battery's in series.
AN0 is the combined voltage from both cells via a 4:1 voltage divider (3K and 1K)
AN1 is the voltage between the two cells via a 2:1 voltage divider (1K and 1K)
The LCD gives me the analogue conversion values and the difference between them. This works perfectly
Atm, all outputs just have LED's hung on them for diagnostics.
I moved the outputs fro PORTC to PORTB and it's still doing the same thing...
When it executed "PORTB = 255" then all the LED's come on as they should.
BUT when i say,
BAT1BLEED = 1
BAT1BLEEDIND = 1
BAT2BLEED = 1
BAT2BLEEDIND = 1
ALARM = 1
Then only the BAT2BLEEDIND LED comes on.
I don't think i have done something stupid, but i'd appreciate another pair of eyes.
Thanks
@ __config _CONFIG1H, _FOSC_INTIO67_1H & _PLLCFG_ON_1H & _PRICLKEN_ON_1H & _FCMEN_ON_1H & _IESO_ON_1H
@ __config _CONFIG2L, _PWRTEN_ON_2L & _BOREN_OFF_2L & _BORV_220_2L
@ __config _CONFIG2H, _WDTEN_ON_2H & _WDTPS_32768_2H
@ __config _CONFIG3H, _CCP2MX_PORTC1_3H & _PBADEN_OFF_3H & _CCP3MX_PORTE0_3H & _HFOFST_OFF_3H & _MCLRE_INTMCLR_3H
@ __config _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
@ __config _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L
@ __config _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
@ __config _CONFIG6L, _WRT0_OFF_6L
@ __config _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
@ __config _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
@ __config _CONFIG7H, _EBTRB_OFF_7H
INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler AD_INT, _ADC_HANDLER, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
DEFINE LCD_DREG PORTD ' LCD data port
DEFINE LCD_DBIT 0 ' LCD data starting bit 0 or 4
DEFINE LCD_RSREG PORTE ' LCD register select port
DEFINE LCD_RSBIT 0 ' LCD register select bit
DEFINE LCD_EREG PORTE ' LCD enable port
DEFINE LCD_EBIT 2 ' LCD enable bit
DEFINE LCD_RWREG PORTE ' LCD read/write port
DEFINE LCD_RWBIT 1 ' LCD read/write bit
DEFINE LCD_BITS 8 ' LCD bus size 4 or 8 data bits
DEFINE LCD_LINES 2 ' Number lines on LCD
DEFINE LCD_COMMANDUS 2000 ' LCD Command delay time in us
DEFINE LCD_DATAUS 50 ' LCD Data delay time in us
Define OSC 64 ' Set clock speed
OSCCON = %01110000
OSCTUNE.6 = 1 ;PLL enable
ANSELA = %11111111
ANSELB = %00000000
ANSELC = %00000000
ANSELD = %00000000
ANSELE = %00000000
TRISA = %11111111
TRISB = 0
TRISC = 0
PORTC = 0
TRISD = 0
PORTD = 0
TRISE = 0
PORTE = 0
CHAN VAR BIT
BAT1 VAR WORD
BAT2 VAR WORD
BAT1TEMP VAR WORD
BAT2TEMP VAR WORD
TEMPWORD VAR WORD
VALIDBATDATA VAR BIT
BAT1BLEEDCOUNT VAR WORD
BAT2BLEEDCOUNT VAR WORD
ALOOP VAR BYTE
BAT1BLEED VAR PORTB.7
BAT1BLEEDIND VAR PORTB.6
BAT2BLEED VAR PORTB.5
BAT2BLEEDIND VAR PORTB.4
ALARM VAR PORTB.3
LCDOUT $FE, 1, "INITIALISING"
PORTB = 255
PAUSE 1000
PORTB = 0
PAUSE 1000
BAT1BLEED = 1
BAT1BLEEDIND = 1
BAT2BLEED = 1
BAT2BLEEDIND = 1
ALARM = 1
PAUSE 1000
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT2BLEED = 0
BAT2BLEEDIND = 0
ALARM = 0
PAUSE 1000
BAT1BLEED = 1
BAT1BLEEDIND = 1
BAT2BLEED = 1
BAT2BLEEDIND = 1
ALARM = 1
PAUSE 1000
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT2BLEED = 0
BAT2BLEEDIND = 0
ALARM = 0
PAUSE 1000
BAT1BLEED = 1
BAT1BLEEDIND = 1
BAT2BLEED = 1
BAT2BLEEDIND = 1
ALARM = 1
PAUSE 1000
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT2BLEED = 0
BAT2BLEEDIND = 0
ALARM = 0
PAUSE 1000
BAT1BLEED = 1
BAT1BLEEDIND = 1
BAT2BLEED = 1
BAT2BLEEDIND = 1
ALARM = 1
PAUSE 1000
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT2BLEED = 0
BAT2BLEEDIND = 0
ALARM = 0
CLEAR
@ INT_ENABLE AD_INT
ADCON2 = %10111110
ADCON1 = %00000000
ADCON0 = %00000011
LCDOUT $FE, 1
MAIN:
BAT1TEMP = BAT1
BAT2TEMP = BAT2
LCDOUT $FE, $80, DEC4 BAT1TEMP, " ", DEC4 BAT2TEMP, " "
IF BAT1TEMP > BAT2TEMP THEN
LCDOUT DEC4 (BAT1TEMP - BAT2TEMP), " "
ELSE
LCDOUT DEC4 (BAT2TEMP - BAT1TEMP), " "
ENDIF
IF BAT2TEMP > BAT1TEMP+5 THEN
BAT2BLEED = 1
BAT2BLEEDIND = 1
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT2BLEEDCOUNT = 0
ELSE
IF BAT2BLEEDCOUNT = 100 THEN
BAT2BLEED = 0
BAT2BLEEDIND = 0
BAT2BLEEDCOUNT = 0
ELSE
BAT2BLEEDCOUNT = BAT2BLEEDCOUNT + 1
ENDIF
ENDIF
IF BAT1TEMP > BAT2TEMP+5 THEN
BAT1BLEED = 1
BAT1BLEEDIND = 1
BAT2BLEED = 0
BAT2BLEEDIND = 0
BAT1BLEEDCOUNT = 0
ELSE
IF BAT1BLEEDCOUNT = 100 THEN
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT1BLEEDCOUNT = 0
ELSE
BAT1BLEEDCOUNT = BAT1BLEEDCOUNT + 1
ENDIF
ENDIF
;IF BAT1 > 819 THEN
; BAT1BLEED = 1
; PORTC.1 = 1
; BAT1BLEEDIND = 1
; BAT2BLEEDIND = 1
; PORTC.2 = 1
; ELSE
; PORTC.2 = 0
; BAT1BLEEDIND = 0
; BAT2BLEEDIND = 0
;ENDIF
;IF BAT1 < 614 THEN
; BAT1BLEED = 0
; PORTC.0 = 0
; BAT2BLEED = 0
; BAT1BLEEDIND = 1
; BAT2BLEEDIND = 1
; ELSE
; PORTC.2 = 0
; BAT1BLEEDIND = 0
; BAT2BLEEDIND = 0
;ENDIF
GOTO MAIN
ADC_HANDLER:
TEMPWORD.LOWBYTE = ADRESL
TEMPWORD.HIGHBYTE = ADRESH
IF CHAN = 0 THEN
ADCON0 = %00000111
BAT1 = TEMPWORD
CHAN = 1
@ INT_RETURN
ENDIF
IF CHAN = 1 THEN
ADCON0 = %00000011
BAT2 = TEMPWORD
CHAN = 0
@ INT_RETURN
ENDIF
@ INT_RETURN
I'm trying to create a charge controller/balancer for LI-POL / LI-ION battery packs.
I started with the 16F1824 but it was doing weird things so i switched to an 18F46K22 and hooked up an LCD for diagnostics.
I even tried two known working 18K46K22's just incase it was a damaged chip.
The circuit at the moment is simple. 2 LI-IONs (for testing) linked in series. 5V supply to PIC and LCD VIA L7805CV fed from both battery's in series.
AN0 is the combined voltage from both cells via a 4:1 voltage divider (3K and 1K)
AN1 is the voltage between the two cells via a 2:1 voltage divider (1K and 1K)
The LCD gives me the analogue conversion values and the difference between them. This works perfectly
Atm, all outputs just have LED's hung on them for diagnostics.
I moved the outputs fro PORTC to PORTB and it's still doing the same thing...
When it executed "PORTB = 255" then all the LED's come on as they should.
BUT when i say,
BAT1BLEED = 1
BAT1BLEEDIND = 1
BAT2BLEED = 1
BAT2BLEEDIND = 1
ALARM = 1
Then only the BAT2BLEEDIND LED comes on.
I don't think i have done something stupid, but i'd appreciate another pair of eyes.
Thanks
@ __config _CONFIG1H, _FOSC_INTIO67_1H & _PLLCFG_ON_1H & _PRICLKEN_ON_1H & _FCMEN_ON_1H & _IESO_ON_1H
@ __config _CONFIG2L, _PWRTEN_ON_2L & _BOREN_OFF_2L & _BORV_220_2L
@ __config _CONFIG2H, _WDTEN_ON_2H & _WDTPS_32768_2H
@ __config _CONFIG3H, _CCP2MX_PORTC1_3H & _PBADEN_OFF_3H & _CCP3MX_PORTE0_3H & _HFOFST_OFF_3H & _MCLRE_INTMCLR_3H
@ __config _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
@ __config _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L
@ __config _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
@ __config _CONFIG6L, _WRT0_OFF_6L
@ __config _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
@ __config _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
@ __config _CONFIG7H, _EBTRB_OFF_7H
INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler AD_INT, _ADC_HANDLER, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
DEFINE LCD_DREG PORTD ' LCD data port
DEFINE LCD_DBIT 0 ' LCD data starting bit 0 or 4
DEFINE LCD_RSREG PORTE ' LCD register select port
DEFINE LCD_RSBIT 0 ' LCD register select bit
DEFINE LCD_EREG PORTE ' LCD enable port
DEFINE LCD_EBIT 2 ' LCD enable bit
DEFINE LCD_RWREG PORTE ' LCD read/write port
DEFINE LCD_RWBIT 1 ' LCD read/write bit
DEFINE LCD_BITS 8 ' LCD bus size 4 or 8 data bits
DEFINE LCD_LINES 2 ' Number lines on LCD
DEFINE LCD_COMMANDUS 2000 ' LCD Command delay time in us
DEFINE LCD_DATAUS 50 ' LCD Data delay time in us
Define OSC 64 ' Set clock speed
OSCCON = %01110000
OSCTUNE.6 = 1 ;PLL enable
ANSELA = %11111111
ANSELB = %00000000
ANSELC = %00000000
ANSELD = %00000000
ANSELE = %00000000
TRISA = %11111111
TRISB = 0
TRISC = 0
PORTC = 0
TRISD = 0
PORTD = 0
TRISE = 0
PORTE = 0
CHAN VAR BIT
BAT1 VAR WORD
BAT2 VAR WORD
BAT1TEMP VAR WORD
BAT2TEMP VAR WORD
TEMPWORD VAR WORD
VALIDBATDATA VAR BIT
BAT1BLEEDCOUNT VAR WORD
BAT2BLEEDCOUNT VAR WORD
ALOOP VAR BYTE
BAT1BLEED VAR PORTB.7
BAT1BLEEDIND VAR PORTB.6
BAT2BLEED VAR PORTB.5
BAT2BLEEDIND VAR PORTB.4
ALARM VAR PORTB.3
LCDOUT $FE, 1, "INITIALISING"
PORTB = 255
PAUSE 1000
PORTB = 0
PAUSE 1000
BAT1BLEED = 1
BAT1BLEEDIND = 1
BAT2BLEED = 1
BAT2BLEEDIND = 1
ALARM = 1
PAUSE 1000
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT2BLEED = 0
BAT2BLEEDIND = 0
ALARM = 0
PAUSE 1000
BAT1BLEED = 1
BAT1BLEEDIND = 1
BAT2BLEED = 1
BAT2BLEEDIND = 1
ALARM = 1
PAUSE 1000
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT2BLEED = 0
BAT2BLEEDIND = 0
ALARM = 0
PAUSE 1000
BAT1BLEED = 1
BAT1BLEEDIND = 1
BAT2BLEED = 1
BAT2BLEEDIND = 1
ALARM = 1
PAUSE 1000
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT2BLEED = 0
BAT2BLEEDIND = 0
ALARM = 0
PAUSE 1000
BAT1BLEED = 1
BAT1BLEEDIND = 1
BAT2BLEED = 1
BAT2BLEEDIND = 1
ALARM = 1
PAUSE 1000
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT2BLEED = 0
BAT2BLEEDIND = 0
ALARM = 0
CLEAR
@ INT_ENABLE AD_INT
ADCON2 = %10111110
ADCON1 = %00000000
ADCON0 = %00000011
LCDOUT $FE, 1
MAIN:
BAT1TEMP = BAT1
BAT2TEMP = BAT2
LCDOUT $FE, $80, DEC4 BAT1TEMP, " ", DEC4 BAT2TEMP, " "
IF BAT1TEMP > BAT2TEMP THEN
LCDOUT DEC4 (BAT1TEMP - BAT2TEMP), " "
ELSE
LCDOUT DEC4 (BAT2TEMP - BAT1TEMP), " "
ENDIF
IF BAT2TEMP > BAT1TEMP+5 THEN
BAT2BLEED = 1
BAT2BLEEDIND = 1
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT2BLEEDCOUNT = 0
ELSE
IF BAT2BLEEDCOUNT = 100 THEN
BAT2BLEED = 0
BAT2BLEEDIND = 0
BAT2BLEEDCOUNT = 0
ELSE
BAT2BLEEDCOUNT = BAT2BLEEDCOUNT + 1
ENDIF
ENDIF
IF BAT1TEMP > BAT2TEMP+5 THEN
BAT1BLEED = 1
BAT1BLEEDIND = 1
BAT2BLEED = 0
BAT2BLEEDIND = 0
BAT1BLEEDCOUNT = 0
ELSE
IF BAT1BLEEDCOUNT = 100 THEN
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT1BLEEDCOUNT = 0
ELSE
BAT1BLEEDCOUNT = BAT1BLEEDCOUNT + 1
ENDIF
ENDIF
;IF BAT1 > 819 THEN
; BAT1BLEED = 1
; PORTC.1 = 1
; BAT1BLEEDIND = 1
; BAT2BLEEDIND = 1
; PORTC.2 = 1
; ELSE
; PORTC.2 = 0
; BAT1BLEEDIND = 0
; BAT2BLEEDIND = 0
;ENDIF
;IF BAT1 < 614 THEN
; BAT1BLEED = 0
; PORTC.0 = 0
; BAT2BLEED = 0
; BAT1BLEEDIND = 1
; BAT2BLEEDIND = 1
; ELSE
; PORTC.2 = 0
; BAT1BLEEDIND = 0
; BAT2BLEEDIND = 0
;ENDIF
GOTO MAIN
ADC_HANDLER:
TEMPWORD.LOWBYTE = ADRESL
TEMPWORD.HIGHBYTE = ADRESH
IF CHAN = 0 THEN
ADCON0 = %00000111
BAT1 = TEMPWORD
CHAN = 1
@ INT_RETURN
ENDIF
IF CHAN = 1 THEN
ADCON0 = %00000011
BAT2 = TEMPWORD
CHAN = 0
@ INT_RETURN
ENDIF
@ INT_RETURN