Log in

View Full Version : 18F46K22 being dyslexic



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

Darrel Taylor
- 30th July 2012, 01:38
READ-MODIFY-WRITE (R-M-W).
Especially at 64Mhz.

Use LATB instead of PORTB

comwarrior
- 30th July 2012, 01:48
Never had an issue with using PORT at 64MHz... but i gave it a go...

Modified code to...



BAT1BLEED VAR LATB.7
BAT1BLEEDIND VAR LATB.6
BAT2BLEED VAR LATB.5
BAT2BLEEDIND VAR LATB.4
ALARM VAR LATB.3


And, i get BAT2BLEEDIND and ALARM LED's on during initialisation phase, and then the ALARM LED only comes on when it's running. Which is odd since that section of code for the alarm LED has been commented out.

The batteries are sufficiently unbalanced to cause it to try to balance them. The LCD readings are,
0346 0377 0031

Oh, i forgot to mention I'm running the last release of 2.60 with PBPL

comwarrior
- 30th July 2012, 02:06
ok, i modified the cod to use a temporary byte variable in ram and then write the var to LATB as follows...



TEMPPORTC VAR BYTE

BAT1BLEED VAR TEMPPORTC.7
BAT1BLEEDIND VAR TEMPPORTC.6
BAT2BLEED VAR TEMPPORTC.5
BAT2BLEEDIND VAR TEMPPORTC.4
ALARM VAR TEMPPORTC.3




IF BAT2TEMP > BAT1TEMP+5 THEN
BAT2BLEED = 1
BAT2BLEEDIND = 1
BAT1BLEED = 0
BAT1BLEEDIND = 0
BAT2BLEEDCOUNT = 0
LATB = TEMPPORTC
ELSE


for diagnostics i modified the LCD command to the following...



LCDOUT $FE, $80, DEC4 BAT1TEMP, " ", DEC4 BAT2TEMP, " "
IF BAT1TEMP > BAT2TEMP THEN
LCDOUT DEC4 (BAT1TEMP - BAT2TEMP), " "
ELSE
LCDOUT DEC4 (BAT2TEMP - BAT1TEMP), " "
ENDIF
LCDOUT $FE, $C0, BIN8 TEMPPORTC


the second line on the LCD reads

00110000
But, again, only the ALARM LED is on...
So, the temp var is correct, but it's not setting to port correctly????

comwarrior
- 30th July 2012, 02:13
Apologies for the multiple posts, I'm just documenting what I've done for diagnostics...

Just for fun i decided to read the LATB register back and display it on the LCD...



LCDOUT $FE, $C0, BIN8 TEMPPORTC, " ", BIN8 LATB


and the LCD reads...



00110000 00110000


so... it's setting LATB correctly... but it's not giving me the output???? :confused:

Darrel Taylor
- 30th July 2012, 22:38
Reading the LATB register does not show the actual state of the pins.
Reading PORTB does, so you might want to add PORTB to your LCD readout like in the image below.

I've run your program in Proteus and everything seems fine.
I did add PORTB to the LCD, it's on the third line.

Obviously, a simulator doesn't prove that it will work on real hardware, but Proteus is really really good.

http://support.melabs.com/DT/comwarrior.png

If your LAT register shows 1's, and the TRIS register is 0's then the PORT register should show the same values as the LAT register.

Charles Linquis
- 2nd August 2012, 03:01
Darrel, I'm getting lamer and lazier every day. I have Proteus, but never got it to work with PBP. Do you have a 'quick-start' guide of some sort to get me started?

Darrel Taylor
- 2nd August 2012, 22:14
Darrel, I'm getting lamer and lazier every day. I have Proteus, but never got it to work with PBP. Do you have a 'quick-start' guide of some sort to get me started?

Hi Charles,

I didn't, but I just recorded a simple demo that should get you going.
Unscripted, umms and sniffles included. :)

http://support.melabs.com/DT/ProteusDemo/ProteusDemo.html

Charles Linquis
- 3rd August 2012, 22:37
Darrel,










Thanks! That got me going. Now I just have to learn to use Proteus' schematic capture. I normally use Altium.

Why didn't LabCenter do this? You should sell your efforts to them. And then you should do more on other topics.
Debugging/simulation in all its forms seems like fertile ground.

comwarrior
- 7th August 2012, 14:07
hi guys, thank you for the help...
yes tried port and lat alternates same results.

i wrote a test sequence to test all the IO pins sequentially... and i marked on the data sheet which pins were not doing what they were supposed to and then noticed a paturn.

I read the device registers for things like MSSP, EUSARTS, PWM etc etc and found that after a cold start these registers were not in the states they were supposed to be acording to the datasheet. So basically, their was hardware turned on that should be off that was taking control of the pins.
I modified the program to reset any register that wasn't in it's proper state. once i did this everything worked perfectly.
I went through the remains of the last batch of 46K22's (~15) and found that every single one had the same issue, but once the registers were reset they never had an issue.

So, thursday last week i sent a large email bug report to microchip detailing what was wrong and what it looks like that is the problem. I also included the chip batch numbers.
As of yet, i have only received the standard acknowledgement of email... which i find to be quite disappointing for such a large company.

I also searched micro-chips documentation and forums etc for any other report of this issue and i seem to be the first / the only one...
So, in the event someone else has a similar issue, this details how to diagnose it and then fix it.

EDIT:
It's a shame that PBP3 didn't come with a simulator... it was also quite disappointing.

Darrel Taylor
- 7th August 2012, 16:56
So which registers don't have the correct power-on value?

I don't have a 46K22 to look at.

Dave
- 7th August 2012, 17:05
Comwarrior, I have been watching this thread quite closly because I have been using the 18F46K22's for quite some time. I have never noticed a problem with them being "Dyslexic". However, I have never ASSUMED the state of ANY registers of ANY PIC's I have used in the past. How could you assume the state to be as printed in the documentation when there is nothing like a BIOS to set them after a power on sequence or a power disturbance. Poweron states are slightly better than random as far as I have seen in the past so I have ALWAYS set ALL register states after poweron or reset.... You should too..... Never assume anything...

Darrel Taylor
- 7th August 2012, 19:00
Dave,

No, All registers have a defined power-on state. And those states are clearly listed in the datasheet. There's nothing random about it.
I've never seen a chip power-up with in-correct states before, so i would like to see what comwarrior found.

People should NOT try to initialize every register at the beginning of the program.
This creates many more problems then it will ever solve, since most people will not bother to read the datasheet to find out what they should set them to.

comwarrior,
What revision is the datasheet you are using?