Page 1 of 1

Very basic EEPROM question: always reads as zero

PostPosted: Sun May 29, 2016 7:22 pm
by Voorhies
I tried writing and reading the EEPROM on my PIC18F46K80, and it always reads back as zero.
I'm writing in C and using XC8 functions: eeprom_write() and eeprom_read(). I also tried
using the __EEPROM_DATA macro.

What am I missing?
Thanks!



Here's my code:

Code: Select all

#ifndef __18F46K80
#define __18F46K80
#warning "Code is targeted for PIC18F46K80"
#endif

#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = DIG    // SOSC Power Selection and mode Configuration bits (Digital (SCLKI) mode)
#pragma config XINST = OFF      // Extended Instruction Set (Disabled)
#pragma config FOSC = HS1       // Oscillator (Internal RC oscillator, CLKOUT function on OSC2)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = OFF      // Brown Out Detect (Disabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
#pragma config WDTEN = OFF      // Watchdog Timer disabled
#pragma config WDTPS = 1024     // Watchdog Postscaler (1:1024), so every 4.096 seconds
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)
#pragma config CP0 = OFF        // Code Protect 00800-03FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 04000-07FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 08000-0BFFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 0C000-0FFFF (Disabled)
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)
#pragma config WRT0 = OFF       // Table Write Protect 00800-03FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 04000-07FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 08000-0BFFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 0C000-0FFFF (Disabled)
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)
#pragma config EBTR0 = OFF      // Table Read Protect 00800-03FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 04000-07FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 08000-0BFFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 0C000-0FFFF (Disabled)
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)


#include <pic18.h>     // Should bring in p18f46k80.h too
#include <stdio.h>     // For printf

__EEPROM_DATA(0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88);

void main()
{
   TRISA = TRISB = TRISC = TRISE = RDPU = 0;   // Benign
   TMR0 = 0, T0CON = 0x80;                     // 1MHz  (Fosc/4 (=2MHz), prescale 2:1), start running

   printf("Initial read of EEPROM[0-7]: %u %u %u %u %u %u %u %u\r\n",
      eeprom_read(0), eeprom_read(1), eeprom_read(2), eeprom_read(3),
      eeprom_read(4), eeprom_read(5), eeprom_read(6), eeprom_read(7));
   
   eeprom_write(27, 42);
   while(WR)
      continue;
   printf("Wrote EEPROM[27] non-zero, got %u\r\n", eeprom_read(27));

   eeprom_write(28, 0xff);
   while(WR)
      continue;
   printf("Wrote EEPROM[28] non-zero, got %u\r\n", eeprom_read(28));
   
   while(1)
      continue;
}

void putch(char c)   // For printf...bit-bang serial I/O
{
unsigned int shifter, next_bit;
char i;
 
   shifter = c;
   shifter <<= 1;                        // Move left, leaving START=0 bit
   shifter |= 0x600;                     // OR in two STOP=1 bits
   while (TMR0 > 0xf800)                 // Spin if we're within 2 ms of TMR0 wrapping
      continue;
   next_bit = TMR0 + 104;

   for (i=0; i<11; i++)
      {
      LATBbits.LATB5 = (0x1 & shifter);  // Non-inverted output
      shifter >>= 1;                     // Right shifter (start, then LSB->MSB, then stop, stop)
      while (TMR0 < next_bit)            // Spin until time for next bit
         continue;
      next_bit += 104;                   // 9600 baud = 104 usec per bit
      }
   LATBbits.LATB5 = 1;                   // Back to idle
}


...and here's what those printfs output:

Initial read of EEPROM[0-7]: 0 0 0 0 0 0 0 0
Wrote EEPROM[27] non-zero, got 0
Wrote EEPROM[28] non-zero, got 0

Re: Very basic EEPROM question: always reads as zero

PostPosted: Mon May 30, 2016 12:34 am
by jtemples
I don't know how those eeprom_* functions are implemented, but make sure you're clearing the EEPGD bit in EECON1. And don't "#define __18F46K80" since that could interfere with the compiler's internals.

Re: Very basic EEPROM question: always reads as zero

PostPosted: Mon May 30, 2016 1:20 pm
by ric
Which version of XC8 are you using?
The latest versions don't come with the PLIB library. If you don't install it, those functions do nothing.