Hot!Trouble using the read floating point value from internal EEPROM on PIC18f4520

Page: 1234 > Showing page 1 of 4
Author
KSK1006
New Users
  • Total Posts : 24
  • Reward points : 0
  • Joined: 2016/10/26 03:59:20
  • Location: 0
  • Status: offline
2018/02/26 00:24:27 (permalink)
0

Trouble using the read floating point value from internal EEPROM on PIC18f4520

Hi everyone,
 
I am facing this weird issue of not being able to use the retrieved floating point value from the internal EEPROM of my controller. What I am trying to do here is I will be storing a floating point value in the EEPROM and retrieve that value on controller reset or after a power cycle.
The issue that I am facing is after I read the value from EEPROM I display it on a serial terminal which looks just fine. But if I try to use that variable inside a while loop it is not being incremented as it is intended to.
This is my test code, and I know that EEPROMs have endurance limit and I shouldn't write so frequently to it. But this is just to test the code flow.

void main(void) {
unsigned int ln1,ld1,ln2,ld2,i;
unsigned char s_val[50],*c,*c1,w_val[4],addr = 0;
float rt = 0;
CloseUART1();
uart1_Init(1,0,21,1); //RC6, RC7 UART baud:115200 10->20MHz,21->40Mhz
TRISBbits.RB7 = 1;
GIE = PEIE = 1;
INTCONbits.RBIE = 1;
INTCONbits.RBIF = 0;
RBPU = 0;

addr = 0;
c1 = (char *)&rt;
for(i=0;i<sizeof(rt);i++){
*(c1++) = Read_EEP(addr++);
}

RBIE=0;
ln2 = rt;
ld2 = (rt-ln2)*1000;
RBIE=1;
sprintf(s_val,"read = %d.%03d\n",ln2,ld2);
puts_Uart1(s_val);

while(1){

rt += (float)pulse/440;     //rt remains zero here
RBIE=0;
ln1 = rt;
ld1 = (rt-ln1)*1000;
RBIE=1;
sprintf(s_val,"f1=%d.%03d,pulse=%d\n" \
,ln1,ld1,pulse);
puts_Uart1(s_val);
pulse = 0;
addr = 0;
c = (char *)&rt;
for(i=0;i<sizeof(rt);i++){
w_val[i] = *(c+i);
Write_EEP(addr++,w_val[i]);
}

delay_10ms(100);
}
return;
}
void Write_EEP(unsigned char add,unsigned char data){
char GIE_STATUS;
EEADR = add; //FF for 256 bytes EEPROM
EEDATA = data;
EECON1bits.EEPGD = 0;
EECON1bits.CFGS = 0;
EECON1bits.WREN = 1;
EECON1bits.FREE = 0;
GIE_STATUS = GIE; //save the Interrupt status before disabling
GIE = 0;
EECON2 = 0x55; //sequence to be followed(data sheet)
EECON2 = 0xAA;
EECON1bits.WR = 1;
while(EECON1bits.WR); //wait till the write is complete
GIE = GIE_STATUS;
EECON1bits.WREN = 0;
EEIF = 0;
}
unsigned char Read_EEP(unsigned char add){
EEADR = add;
EECON1bits.EEPGD = 0;
EECON1bits.CFGS = 0;
EECON1bits.RD = 1;
while(RD || WR);
Nop(); //intentional delay for controller with fast clocks
Nop();
return EEDATA;
}
void delay_10ms(unsigned int n){
while(n--){
__delay_ms(10);
}
}

The read value is displayed correctly but not able to increment the variable 'rt' as per the requirement. Here pulse is incremented by an ISR which is not shown in this code. 
Can somebody help me out with this issue? I work on PIC18f4520, MPLABX v4.10, XC8 v1.34 on Windows 7.
 
Thank you

SharathK
#1

67 Replies Related Threads

    qɥb
    Monolothic Member
    • Total Posts : 3329
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/26 00:47:44 (permalink)
    +1 (1)
    You've left out several crucial details.
    What are the values of "rt" and "pulse" during this test?
    (I wouldn't have to ask if you just showed your serial output.)
     
    What size "float" do you have set in XC8? 24 or 32?
     

    This forum is mis-configured so it only works correctly if you access it via https protocol.
    The Microchip website links to it using http protocol. Will they ever catch on?
    PicForum "it just works"
    #2
    KSK1006
    New Users
    • Total Posts : 24
    • Reward points : 0
    • Joined: 2016/10/26 03:59:20
    • Location: 0
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/26 01:11:53 (permalink)
    0
    Hi qyb,
    1. "rt" and "pulse" are dynamic values that are generated when the sensor gives out the pulses on IOC (RB7) pin. "rt" is floating type and "pulse" is of unsigned int type.
    2. float is 3 bytes (24bits) on XC8

    read = 0.000
    f1=0.000,pulse=2
    f1=0.000,pulse=0
    f1=0.000,pulse=0
    f1=0.000,pulse=0
    f1=0.000,pulse=0
    f1=0.000,pulse=1
    f1=0.000,pulse=0
    f1=0.000,pulse=0
    f1=0.000,pulse=58
    f1=0.000,pulse=81
    f1=0.000,pulse=32
    f1=0.000,pulse=2

    This is the serial terminal output when "rt" is used inside while(1) loop
     

    f1=0.034,pulse=15
    f1=0.197,pulse=72
    f1=0.256,pulse=26
    f1=0.256,pulse=0
    f1=0.256,pulse=0
    f1=0.256,pulse=0
    read = 0.256
    f1=0.000,pulse=0       //the previous value is not being added as intended
    f1=0.000,pulse=0
    f1=0.000,pulse=0
    f1=0.000,pulse=0

    This is the serial terminal output when a different floating point variable is used inside while(1) loop.
     
    Thank you,

    SharathK
    #3
    mbrowning
    Just a Member
    • Total Posts : 1126
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: online
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/26 05:11:52 (permalink)
    0
    rt += (float)pulse/440;

    The highest value of "pulse" you show is 72. I know the precedence of (float) should be higher than "/", but try using 440.0 instead of 440 and force the floating division rather than a possible integer division.

    Go Navy! Beat Army!
    #4
    KSK1006
    New Users
    • Total Posts : 24
    • Reward points : 0
    • Joined: 2016/10/26 03:59:20
    • Location: 0
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/26 06:04:01 (permalink)
    0
    Thanks. Will take that tip.

    SharathK
    #5
    NKurzman
    A Guy on the Net
    • Total Posts : 16563
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/26 06:26:02 (permalink)
    +1 (1)
    A float is 24bits in XC8 by default. 32 bits is a selectable option.
    #6
    1and0
    Access is Denied
    • Total Posts : 8459
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/26 09:38:02 (permalink)
    +1 (5)
    KSK1006

    c1 = (char *)&rt;
    for(i=0;i<sizeof(rt);i++){
    *(c1++) = Read_EEP(addr++);
    }


    That should be either
    *(c1+i)

    or
    *c1++

    #7
    KSK1006
    New Users
    • Total Posts : 24
    • Reward points : 0
    • Joined: 2016/10/26 03:59:20
    • Location: 0
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/26 22:44:06 (permalink)
    0
    Did that change. But the original problem still remains the same. The value of f1 remains zero if I use the same floating point variable inside and outside the while loop or if I assign the value of floating point variable outside the while loop to the one inside. It is so frustrating.

    SharathK
    #8
    qɥb
    Monolothic Member
    • Total Posts : 3329
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/26 22:46:13 (permalink)
    +2 (2)
    The key to effective debugging is reducing the number of unknowns.
    Try dumping to serial the 4 hex byte values that are being written to EEPROM, and then the same 4 values after they are read back, to see if there is any difference.
     
    You could also make your code a lot more readable by using C "unions" rather than mucking around with pointers to get at the internal value.
     
    post edited by qɥb - 2018/02/26 22:47:19

    This forum is mis-configured so it only works correctly if you access it via https protocol.
    The Microchip website links to it using http protocol. Will they ever catch on?
    PicForum "it just works"
    #9
    KSK1006
    New Users
    • Total Posts : 24
    • Reward points : 0
    • Joined: 2016/10/26 03:59:20
    • Location: 0
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/26 23:53:49 (permalink)
    0
    Thanks qyb. Did exactly like you said. Read and write hex values were ditto. And also used union instead of pointers, but facing the exact same issue. When I add that assignment instruction just before "while(1)" it behaves wacky. If the assignment is not done, read and write will be fine but "rt" variable won't be updated to the read value. 
     
     

    SharathK
    #10
    1and0
    Access is Denied
    • Total Posts : 8459
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/27 02:33:46 (permalink)
    0
    The two persons who down-voted my Post #7 must need to be spoon-fed. 
     
    Anyway, XC8 v1.34 is old, so update it to the latest version and check again.
    #11
    qɥb
    Monolothic Member
    • Total Posts : 3329
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/27 02:37:05 (permalink)
    0
    At least two people understood your point though :)
     

    This forum is mis-configured so it only works correctly if you access it via https protocol.
    The Microchip website links to it using http protocol. Will they ever catch on?
    PicForum "it just works"
    #12
    1and0
    Access is Denied
    • Total Posts : 8459
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/27 03:33:11 (permalink)
    0
    qɥb
    At least two people understood your point though :)

    Good thing that OP is among one of them, from his Post #8 :)
     
    @OP, I suspect the value read from the EEPROM might be infinity or a NaN.  Print out that value and see:
    addr = 0;
    c1 = (char *)&rt;
    for(i=0;i<sizeof(rt);i++){
        *c1++ = Read_EEP(addr++);
    }
    sprintf(s_val,"Read_EEP = %f\n",rt);
    puts_Uart1(s_val);

     
     
    #13
    KSK1006
    New Users
    • Total Posts : 24
    • Reward points : 0
    • Joined: 2016/10/26 03:59:20
    • Location: 0
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/27 03:45:51 (permalink)
    0
    Thank you 1and0. Bang on, it was a NaN. Caught it in debug mode. But why is it so? if I print the value on the serial terminal with a different float variable than "rt" it prints alright. Any hints?

    SharathK
    #14
    qɥb
    Monolothic Member
    • Total Posts : 3329
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/27 03:50:41 (permalink)
    0
    what is the raw hex value?
     

    This forum is mis-configured so it only works correctly if you access it via https protocol.
    The Microchip website links to it using http protocol. Will they ever catch on?
    PicForum "it just works"
    #15
    1and0
    Access is Denied
    • Total Posts : 8459
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/27 04:08:34 (permalink)
    0
    SharathK
    Thank you 1and0. Bang on, it was a NaN. Caught it in debug mode. But why is it so? if I print the value on the serial terminal with a different float variable than "rt" it prints alright. Any hints?

    Did you write-protected the EEPROM?
     
    #16
    1and0
    Access is Denied
    • Total Posts : 8459
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/27 04:26:48 (permalink)
    +2 (2)
    Also, replace this
     EECON2 = 0x55; //sequence to be followed(data sheet)
    EECON2 = 0xAA;
    EECON1bits.WR = 1;

    with this
     #asm
    movlw   0x55
    movwf   EECON2
    movlw   0xAA
    movwf   EECON2
    bsf     EECON1,_EECON1_WR_POSN
    #endasm

    just in case the compiler decided to do things differently.
     
    <edit> Removed BANKSEL since it's in Access RAM.
    post edited by 1and0 - 2018/02/27 04:29:10
    #17
    KSK1006
    New Users
    • Total Posts : 24
    • Reward points : 0
    • Joined: 2016/10/26 03:59:20
    • Location: 0
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/27 04:43:37 (permalink)
    0
    Oh just got to know from one of the other threads that reading a float value declared inside a union which also contains something else returns a NaN. I guess that shouldn't be an issue as I am able to convert the char array to float in the program successfully. 
    To clear things off, this is my current program

    // CONFIG1H
    #pragma config OSC = HSPLL // Oscillator Selection bits (HS oscillator, PLL enabled (Clock Frequency = 4 x FOSC1))
    #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
    #pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
    // CONFIG2L
    #pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)
    #pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
    #pragma config BORV = 3 // Brown Out Reset Voltage bits (Minimum setting)
    // CONFIG2H
    #pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
    #pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
    // CONFIG3H
    #pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
    #pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
    #pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
    #pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
    // CONFIG4L
    #pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
    #pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
    #pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
    // CONFIG5L
    #pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
    #pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
    #pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
    #pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) not code-protected)
    // CONFIG5H
    #pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
    #pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
    // CONFIG6L
    #pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
    #pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
    #pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
    #pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) not write-protected)
    // CONFIG6H
    #pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
    #pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
    #pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
    // CONFIG7L
    #pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
    #pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
    #pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
    #pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)
    // CONFIG7H
    #pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)
    // #pragma config statements should precede project file includes.
    // Use project enums instead of #define for ON and OFF.

    #include <xc.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "uart.h"
    #define _XTAL_FREQ 40000000
    #define f1 PORTBbits.KBI3
    void Write_EEP(unsigned char add,unsigned char data);
    unsigned char Read_EEP(unsigned char add);
    void delay_10ms(unsigned int n);
    unsigned int pulse = 0;
    union {
    unsigned char c1[3];
    float fli;
    }eepr;
    union {
    unsigned char c[3];
    float rt;
    }eepw;
    void interrupt flow(void){
    unsigned char temp;
    temp = PORTB;
    RBIE = 0;
    if(f1){
    pulse++;
    }
    RBIF = 0;
    RBIE = 1;
    }
    void main(void) {
    unsigned int ln1,ld1,ln2,ld2,i;
    unsigned char s_val[50],w_val[4],r_val[20],*c,addr = 0,w_ch,r_ch;
    volatile float *p,rt = 0;
    CloseUART1();
    uart1_Init(1,0,21,1); //RC6, RC7 UART baud:115200 10->20MHz,21->40Mhz
    TRISBbits.RB7 = 1;
    GIE = PEIE = 1;
    INTCONbits.RBIE = 1;
    INTCONbits.RBIF = 0;
    RBPU = 0;
    addr = 0;

    for(i=0;i<3;i++){
    eepr.c1[i] = Read_EEP(addr+i);
    }

    RBIE=0;
    ln2 = eepr.fli;
    ld2 = (eepr.fli-ln2)*1000;
    RBIE=1;
    sprintf(s_val,"read = %d.%03d\n",ln2,ld2);
    puts_Uart1(s_val);
    // eepw.rt += (float)eepr.fli;  <--This line is causing the headache
    while(1){

    eepw.rt += (float)pulse/440.0;
    RBIE=0;
    ln1 = eepw.rt;
    ld1 = (eepw.rt-ln1)*1000;
    RBIE=1;
    sprintf(s_val,"f1=%d.%03d,pulse=%d\n" \
    ,ln1,ld1,pulse);
    puts_Uart1(s_val);
    pulse = 0;
    addr = 0;

    for(i=0;i<sizeof(eepw.rt);i++){

    Write_EEP(addr+i,eepw.c[i]);
    }

    delay_10ms(100);
    }


    return;
    }
    void Write_EEP(unsigned char add,unsigned char data){
    char GIE_STATUS;
    EEADR = add; //FF for 256 bytes EEPROM
    EEDATA = data;
    EECON1bits.EEPGD = 0;
    EECON1bits.CFGS = 0;
    EECON1bits.WREN = 1;
    EECON1bits.FREE = 0;
    GIE_STATUS = GIE; //save the Interrupt status before disabling
    GIE = 0;
    EECON2 = 0x55; //sequence to be followed(data sheet)
    EECON2 = 0xAA;
    EECON1bits.WR = 1;
    while(EECON1bits.WR); //wait till the write is complete
    GIE = GIE_STATUS;
    EECON1bits.WREN = 0;
    EEIF = 0;
    }
    unsigned char Read_EEP(unsigned char add){
    EEADR = add;
    EECON1bits.EEPGD = 0;
    EECON1bits.CFGS = 0;
    EECON1bits.RD = 1;
    while(RD || WR);
    Nop(); //intentional delay for controller with fast clocks
    Nop();
    return EEDATA;
    }
    void delay_10ms(unsigned int n){
    while(n--){
    __delay_ms(10);
    }
    }

     And no EEPROM is not write protected as you can see from CONFIG bits.
    Raw hex value of read and write were the same qyb. double checked it.
     
    Thank you,

    SharathK
    #18
    jtemples
    Super Member
    • Total Posts : 10997
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/27 10:48:36 (permalink)
    +2 (2)
    At least two people understood your point though

     
    I didn't vote either way, but I don't understand the point?  *(c1++) is the same as *c1++.
    #19
    1and0
    Access is Denied
    • Total Posts : 8459
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Trouble using the read floating point value from internal EEPROM on PIC18f4520 2018/02/27 11:12:21 (permalink)
    +1 (1)
    jtemples
    *(c1++) is the same as *c1++.

    You're correct and I've learned something. :)  I thought the former would increment the pointer first then the dereference.  Nevertheless, I'd appreciated if they would point out the mistake instead, as you have done here.
     
    #20
    Page: 1234 > Showing page 1 of 4
    Jump to:
    © 2018 APG vNext Commercial Version 4.5