18F46K22 being dyslexic


+ Reply to Thread
Results 1 to 13 of 13
  1. #1

    Default 18F46K22 being dyslexic

    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

    Code:
    @ __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

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: 18F46K22 being dyslexic

    READ-MODIFY-WRITE (R-M-W).
    Especially at 64Mhz.

    Use LATB instead of PORTB
    DT

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: 18F46K22 being dyslexic

    Never had an issue with using PORT at 64MHz... but i gave it a go...

    Modified code to...

    Code:
    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

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: 18F46K22 being dyslexic

    ok, i modified the cod to use a temporary byte variable in ram and then write the var to LATB as follows...

    Code:
    TEMPPORTC VAR BYTE
    
    BAT1BLEED VAR TEMPPORTC.7
    BAT1BLEEDIND VAR TEMPPORTC.6
    BAT2BLEED VAR TEMPPORTC.5
    BAT2BLEEDIND VAR TEMPPORTC.4
    ALARM VAR TEMPPORTC.3
    Code:
    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...

    Code:
    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
    Code:
    00110000
    But, again, only the ALARM LED is on...
    So, the temp var is correct, but it's not setting to port correctly????

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: 18F46K22 being dyslexic

    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...

    Code:
    LCDOUT $FE, $C0, BIN8 TEMPPORTC, " ", BIN8 LATB
    and the LCD reads...

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

  6. #6
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: 18F46K22 being dyslexic

    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.



    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.
    DT

  7. #7
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default Re: 18F46K22 being dyslexic

    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?
    Charles Linquist

  8. #8
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: 18F46K22 being dyslexic

    Quote Originally Posted by Charles Linquis View Post
    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/Proteus...oteusDemo.html
    Last edited by Darrel Taylor; - 2nd August 2012 at 22:25.
    DT

  9. #9
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default Re: 18F46K22 being dyslexic

    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.
    Charles Linquist

  10. #10


    Did you find this post helpful? Yes | No

    Default Re: 18F46K22 being dyslexic

    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.

  11. #11
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: 18F46K22 being dyslexic

    So which registers don't have the correct power-on value?

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

  12. #12
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default Re: 18F46K22 being dyslexic

    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...
    Dave Purola,
    N8NTA
    EN82fn

  13. #13
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: 18F46K22 being dyslexic

    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?
    DT

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts