View previous topic :: View next topic |
Author |
Message |
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
EEPROM data access on a PIC12F519 |
Posted: Fri Jan 27, 2012 8:13 am |
|
|
Help: Can't get EEPROM to work on a PIC12F519, driving me crazy! Here is a simple test program:
Code: |
CCS PCB C Compiler, Version 4.129, 61851 27-Jan-12 14:01
Filename: c:\temp\will.lst
ROM used: 42 words (4%)
Largest free fragment is 512
RAM used: 3 (12%) at main() level
4 (16%) worst case
Stack: 1 locations
*
0000: MOVWF 05
0001: GOTO 016
0002: GOTO 003
.................... #include <will.h>
.................... #include <12F519.h>
.................... //////// Standard Header file for the PIC12F519 device ////////////////
.................... #device PIC12F519
.................... #list
....................
....................
.................... #FUSES NOWDT //No Watch Dog Timer
.................... #FUSES INTRC //Internal RC Osc
.................... #FUSES NOMCLR //Master Clear pin used for I/O
.................... #FUSES IOSC4 //INTOSC speed 4MHz
.................... #FUSES
.................... #use delay(int=4000000)
0003: MOVF 0A,W
0004: BTFSC 03.2
0005: GOTO 014
0006: MOVLW 01
0007: MOVWF 08
0008: CLRF 07
0009: DECFSZ 07,F
000A: GOTO 009
000B: DECFSZ 08,F
000C: GOTO 008
000D: MOVLW 4A
000E: MOVWF 07
000F: DECFSZ 07,F
0010: GOTO 00F
0011: GOTO 012
0012: DECFSZ 0A,F
0013: GOTO 006
0014: BCF 03.5
0015: GOTO 02A (RETURN)
....................
....................
....................
.................... int8 test = 0xFF;
.................... void main() {
0016: CLRF 04
0017: MOVLW FF
0018: MOVWF 09
.................... write_eeprom(0,10);
0019: BSF 04.5
001A: CLRF 06
001B: MOVLW 0A
001C: MOVWF 05
001D: BSF 01.2
001E: BSF 01.1
001F: NOP
0020: NOP
.................... test = read_eeprom(0);
0021: CLRF 06
0022: BSF 01.0
0023: NOP
0024: MOVF 05,W
0025: MOVWF 09
.................... while(TRUE) {
.................... delay_ms(1);
0026: MOVLW 01
0027: MOVWF 0A
0028: BCF 04.5
0029: GOTO 002
.................... }
002A: BSF 04.5
002B: GOTO 026
....................
.................... }
002C: SLEEP
Configuration Fuses:
Word 1: 0FCA INTRC NOWDT NOPROTECT NOMCLR IOSC4 NOPROTECTDF |
I can't see how this follows the data-sheet on EEPROM WRITE. The process in the datasheet involves a whole memory row. I can't see how the CCS code works....and it doesn't. The write_eeprom corrupts the data EEPROM memory! Any ideas? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Fri Jan 27, 2012 9:10 am |
|
|
OK.
Key is that the 518, & 519, don't have a 'normal' PIC EEPROM. Instead they have what is effectively a separate EEPROM 'die' built onto the chip, which communicates using I2C!....
It uses two 'non existent' pins for the communication.
So to use the EEPROM on these chips, you have to setup the I2C, and use the external EEPROM functions.
Code: |
#include <12F519.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC //Internal RC Osc
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES IOSC4 //INTOSC speed 4MHz
#FUSES
#use delay(int=4000000)
#define EEPROM_SDA (54) //Define pin addresses to use (non existent pins)
#define EEPROM_SCL (55)
#include <2401.c> //The eeprom it effectively emulates...
int8 test = 0xFF;
void main() {
write_ext_eeprom(0,10);
test = read_ext_eeprom(0);
while(TRUE) {
delay_ms(1);
}
}
|
An 'oddity' of these old chips....
Best Wishes |
|
|
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
|
Posted: Fri Jan 27, 2012 10:12 am |
|
|
Thanks, but I get:
Error 100 "C:\Program Files\PICC\drivers\2401.c" Line 46(5,49): USE parameter value is out of range Not a number: (54
The #use i2c doesn't seem to like those pins? |
|
|
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
|
Posted: Fri Jan 27, 2012 11:11 am |
|
|
Figured it out; ccs compiler bug, will post a workaround this evening so no-one else drops in the hole! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Fri Jan 27, 2012 12:56 pm |
|
|
I had omitted the 'init_ext_eeprom' call that is needed as well.
For some annoying reason the compiler doesn't like brackets round the numbers used as pin definitions:
Code: |
#include <12F519.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC //Internal RC Osc
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES IOSC4 //INTOSC speed 4MHz
#use delay(int=4000000)
#define PIN_B6 54
#define PIN_B7 55
#define EEPROM_SDA PIN_B6 //Define pin addresses to use (non existent pins)
#define EEPROM_SCL PIN_B7
#include <2401.C>
void main() {
int8 test;
init_ext_eeprom();
write_ext_eeprom(0,10);
test = read_ext_eeprom(0);
while(TRUE) {
delay_ms(1);
}
}
|
Been perhaps 10 years since I used this, so apologies for forgetting the exact syntax....
Best Wishes |
|
|
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
|
Posted: Fri Jan 27, 2012 1:09 pm |
|
|
Hi, from what I can see from the datasheet the 12F519 has real(ish) EEPROM which you need to erase a whole 8byte row before you can write a single byte. I think you are referring to the non-flash part which has the I2C implemented EEPROM?
I need to tidy up the code a bit and it doesn't read the 7 bytes you need to "save" before you erase the whole row and write all 8 back to EEPROM, but initial compilation seems to suggest it works OK (at least in the simulator in MPLAB). Hopefully ccs or you can suggest a neater solution to what I have come up with! I'll post some code in a few hours when I am back at my desk. |
|
|
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
|
Posted: Fri Jan 27, 2012 1:32 pm |
|
|
Here is my code:
Code: | #byte FSR = 0x4
#bit BANK = FSR.5
#byte EECON = 0x1
#bit FREE = EECON.4
#bit WREN = EECON.2
#bit WR = EECON.1
#bit RD = EECON.0
#byte EEDATA = 0x5
#byte EEADR = 0x6
void will_erase_eeprom() {
// This function will earase the first row of EEPROM data
BANK = 1;
EEADR = 0;
FREE = 1;
WREN = 1;
WR = 1;
BANK = 0;
}
void will_write_eeprom(int8 address,int8 data) {
// This function will write a byte of data to an address
// make sure that the row of data (8 bytes) has been erased first
BANK = 1;
EEADR = address;
EEDATA = data;
WREN = 1;
WR = 1;
BANK = 0;
}
void main() {
int8 temp = 0x00;
will_erase_eeprom();
will_write_eeprom(0,25);
temp = read_eeprom(0);
BANK = 0; // For some reason the compiler forgets to do this after a read
while(TRUE) {
delay_ms(1); // Add breakpoing in MPLAB!
} // while(true)
}
|
Luckily I can get away without reading the whole row of EEPROM data and having to store it while the row is erased. I am only storing one byte in EEPROM!
I just wish ccs would point out that their built in code didn't work on this part. It's wasted hours of my time!
I am always open to suggestions / corrections so please suggest easer ways to do this! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Fri Jan 27, 2012 1:53 pm |
|
|
Any chance you could use a 'normal' PIC for your application ? Maybe something newer but same pinout and compatible.
Like you, I've wasted a lot of R&D time on a bug or quirk, when spending even a whole extra dollar on a part would have saved that wasted time. |
|
|
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
|
Posted: Fri Jan 27, 2012 2:36 pm |
|
|
It needs to be the really tiny footprint part; I am just tasked with firmware! Apparently (I haven't checked!) it's the smallest F part with EEPROM you can get! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Fri Jan 27, 2012 3:13 pm |
|
|
gee...smaller is NOT always better...I have to be able to SEE what I'm working on ,preferably without a x5 magnifying glass. Yup, almost 60 and this micro,micro SMD stuff bufuddles me....
Sorry you have to work in Lillipution land ! |
|
|
|