|
|
View previous topic :: View next topic |
Author |
Message |
Gag
Joined: 05 Mar 2004 Posts: 5 Location: Canyon Country, CA
|
External EEPROM returning 0xFF only |
Posted: Fri Mar 05, 2004 4:25 pm |
|
|
I'm having a problem with storing some setup and calibration data on an external eeprom for a battery powered, handheld pressure gauge. The eeprom keeps returning 0xFF whenever I read it.
I'm hoping that the solution is visible to someone that isn't as close to the project as me.
Thanks in advance for any help.
Here's my environment ------
PCM Version 3.148
PIC 16C773 (#use delay (clock=3686400))
EEPROM 24LC01B (5v VCC, 2.2K pullups on SCL and SDA -- Also tried 4.7K, WP,A0,A1,A2 tied to VSS)
My code -----
Code: |
#include "16c773.h"
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
...
#define EEPROM_SDA PIN_C4 // This sets the pin assignment for SDA
#define EEPROM_SCL PIN_C3 // and SCL called in 2401.h.
#include "2401.c"
...
void main(void){
...
init_ext_eeprom(); // Note: Place before interrupts are enabled
...
if (!read_ext_eeprom(10)) // Check to see if the eeprom has any info
{ Offset.l = 0; // if not ... stuff the following values in
Gain.l = 200; //
BkLtTime.l = 1000; //
Hold2.l = 1000; //
write_ext_eeprom(10,0); // Set position 10 to zero
}
else
{ Offset.i[0] = read_ext_eeprom( 0 ); //
Offset.i[1] = read_ext_eeprom( 1 ); //
Gain.i[0] = read_ext_eeprom( 2 ); //
Gain.i[1] = read_ext_eeprom( 3 ); //
BkLtTime.i[0] = read_ext_eeprom( 4 ); //
BkLtTime.i[1] = read_ext_eeprom( 5 ); //
Hold2.i[0] = read_ext_eeprom( 8 ); //
Hold2.i[1] = read_ext_eeprom( 9 ); //
}
...
if (Pressed_3 && Released_3) // CAL
{ CalMode++;
lcd_gotoxy(1,1);
switch (CalMode)
{
case 1:
lcd_putc("\fOFF ");
printf(lcd_putc, "\n%5lu", Offset.l);
break;
case 2:
write_ext_eeprom(0, Offset.i[0]);
write_ext_eeprom(1, Offset.i[1]);
lcd_putc("\fGAIN");
printf(lcd_putc, "\n%5lu", Gain.l);
break;
case 3:
write_ext_eeprom(2, Gain.i[0]);
write_ext_eeprom(3, Gain.i[1]);
lcd_putc("\fBkLt");
printf(lcd_putc, "\n%5lu", BkLtTime.l);
break;
case 4:
write_ext_eeprom(4, BkLtTime.i[0]);
write_ext_eeprom(5, BkLtTime.i[1]);
lcd_putc("\fHLD2");
printf(lcd_putc, "\n%5lu", Hold2.l);
break;
default:
write_ext_eeprom(8, Hold2.i[0]);
write_ext_eeprom(9, Hold2.i[1]);
lcd_putc("\f"); // Clear screen
DisplayCylInfo(); CalMode = 0;
break;
}
Pressed_3 = 0; // Reset Press flag to off.
}
...
|
2401.c code included with the compiler that I'm calling -----
Code: |
#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)
#define EEPROM_ADDRESS byte
#define EEPROM_SIZE 128
void init_ext_eeprom() {
output_float(eeprom_scl);
output_float(eeprom_sda);
}
void write_ext_eeprom(byte address, byte data) {
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_write(data);
i2c_stop();
delay_ms(11);
}
byte read_ext_eeprom(byte address) {
byte data;
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data=i2c_read(0);
i2c_stop();
return(data);
}
|
Some questions that I have are:
1) I set no fuses for this project. Can this be the problem?
2) Does this version of the compiler have an error in it that I'm not aware of? [I've read the update notes on CCS for the versions above mine and didn't notice anything that addressed the eeprom]
3) I'm I just stupid and don't know it?
Thanks again. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 05, 2004 5:41 pm |
|
|
I suggest that you make a test program that only writes
and reads from the EEPROM. Make that work, and then
add your other code. |
|
|
Gag
Joined: 05 Mar 2004 Posts: 5 Location: Canyon Country, CA
|
|
Posted: Fri Mar 05, 2004 6:19 pm |
|
|
That is what I was doing while I was waiting for a reply ... It still isn't working. With a scope, I can see the SDA and SCL lines dropping from 5v to VSS. So the PIC is accessing the lines. I haven't gone the next step of checking the timing of the line changes.
Can it be the frequency I'm running the PIC (#use delay (clock=3686400)) ?
The hardware setup is simple --
VCC, VSS, WP held low, 2 lines with pullups.
The software setup is simple --
#define EEPROM_SDA PIN_C4 // This sets the pin assignment for SDA
#define EEPROM_SCL PIN_C3 // and SCL called in 2401.h.
#include "2401.c"
The software calls are simple --
init_ext_eeprom(); // Note: Place before interrupts are enabled
write_ext_eeprom( address, '8bit value' );
x = read_ext_eeprom( address );
The simplicity is where I'm stuck. I'm either missing something right in from of me and/or there is a compiler/structure error. (Or something completely different)
I'll keep working on the focused program to JUST get it to work.
Am I missing something with this brief outline?
|
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Fri Mar 05, 2004 6:35 pm |
|
|
I've never used the 16c773 but try forcing the speed to "slow" in your #use i2c statment
For example:
#use i2c(master, sda=SDA_PIN, scl=SCL_PIN, slow, restart_wdt) _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 05, 2004 6:37 pm |
|
|
Post the test program. Select and copy it all right out of MPLAB and
post it verbatim. |
|
|
Guest Guest
|
i2c_read? |
Posted: Mon Mar 08, 2004 4:32 am |
|
|
Have you tried using "data=i2c_read()" as opposed to "data=i2c_read(0)"?
I don't understand the nuances, but I have found such seemingly minor changes make a world of difference with I2C on the PIC. If you figure it out, please let me know! |
|
|
Gag
Joined: 05 Mar 2004 Posts: 5 Location: Canyon Country, CA
|
|
Posted: Mon Mar 08, 2004 12:11 pm |
|
|
PCM programmer:
Sorry for the delay ... weekends can be just too much fun sometimes.
Here is my "Test" program. It is a simple three step process -- Read data, Write data, Read again. (The commented lines were just another test-in-a-test to confirm that interger vs. hex arguments did not make a difference) The delays in the program are just to make things happen really slow visually.
Main Source file --
Code: |
#include "16c773.h"
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include "Lcd.h"
#define EEPROM_SDA PIN_C4 // This sets the pin assignment for SDA
#define EEPROM_SCL PIN_C3 // and SCL called in 2401.c.
#include "2401.c"
//========================================main()
void main(void){
lcd_init(); //
lcd_putc("\fEXTee"); // Display intro message.
delay_ms(2000);
init_ext_eeprom(); // Note: Place before interrupts are enabled
printf( lcd_putc, "\nee10=%u", read_ext_eeprom(0x0A) );
// printf( lcd_putc, "\nee10=%u", read_ext_eeprom(10) );
delay_ms(2000);
write_ext_eeprom(0x0A,0x01);
// write_ext_eeprom(10,1);
delay_cycles(10);
printf( lcd_putc, "\fee10=%u", read_ext_eeprom(0x0A) );
// printf( lcd_putc, "\fee10=%u", read_ext_eeprom(10) );
delay_ms(2000);
}
|
16C773.h -- (Notice that I have added the ADC and clock info that the top of the program and have added some defines at the bottom of the program also. This is a normal practice of mine -- to make a copy of any file that is used in compiling a program and put it in the project folder. This way I can see if the file changes with any update and have all the files backed up in one location in case of a hard drive crash. Its not a great idea, but it has worked for me.)
Code: |
//////// Standard Header file for the PIC16C773 device ////////////////
#device PIC16C773
#device ADC=12
#use delay (clock=3686400)
#nolist
//////// Program memory: 4096x14 Data RAM: 255 Stack: 8
//////// I/O: 21 Analog Pins: 8
//////// C Scratch area: 77 ID Location: 2000
//////// Fuses: LP,XT,HS,RC,NOWDT,WDT,NOPUT,PUT,PROTECT,PROTECT_75%
//////// Fuses: PROTECT_50%,NOPROTECT,NOBROWNOUT,BROWNOUT
////////
////////////////////////////////////////////////////////////////// I/O
// Discrete I/O Functions: SET_TRIS_x(), OUTPUT_x(), INPUT_x(),
// PORT_B_PULLUPS(), INPUT(),
// OUTPUT_LOW(), OUTPUT_HIGH(),
// OUTPUT_FLOAT(), OUTPUT_BIT()
// Constants used to identify pins in the above are:
#define PIN_A0 40
#define PIN_A1 41
#define PIN_A2 42
#define PIN_A3 43
#define PIN_A4 44
#define PIN_B0 48
#define PIN_B1 49
#define PIN_B2 50
#define PIN_B3 51
#define PIN_B4 52
#define PIN_B5 53
#define PIN_B6 54
#define PIN_B7 55
#define PIN_C0 56
#define PIN_C1 57
#define PIN_C2 58
#define PIN_C3 59
#define PIN_C4 60
#define PIN_C5 61
#define PIN_C6 62
#define PIN_C7 63
////////////////////////////////////////////////////////////////// Useful defines
#define FALSE 0
#define TRUE 1
#define BYTE int
#define BOOLEAN short int
#define getc getch
#define fgetc getch
#define getchar getch
#define putc putchar
#define fputc putchar
#define fgets gets
#define fputs puts
////////////////////////////////////////////////////////////////// Control
// Control Functions: RESET_CPU(), SLEEP(), RESTART_CAUSE()
// Constants returned from RESTART_CAUSE() are:
#define WDT_FROM_SLEEP 0
#define WDT_TIMEOUT 8
#define MCLR_FROM_SLEEP 16
#define NORMAL_POWER_UP 24
////////////////////////////////////////////////////////////////// Timer 0
// Timer 0 (AKA RTCC)Functions: SETUP_COUNTERS() or SETUP_TIMER0(),
// SET_TIMER0() or SET_RTCC(),
// GET_TIMER0() or GET_RTCC()
// Constants used for SETUP_TIMER0() are:
#define RTCC_INTERNAL 0
#define RTCC_EXT_L_TO_H 32
#define RTCC_EXT_H_TO_L 48
#define RTCC_DIV_1 8
#define RTCC_DIV_2 0
#define RTCC_DIV_4 1
#define RTCC_DIV_8 2
#define RTCC_DIV_16 3
#define RTCC_DIV_32 4
#define RTCC_DIV_64 5
#define RTCC_DIV_128 6
#define RTCC_DIV_256 7
#define RTCC_8_BIT 0
// Constants used for SETUP_COUNTERS() are the above
// constants for the 1st param and the following for
// the 2nd param:
////////////////////////////////////////////////////////////////// WDT
// Watch Dog Timer Functions: SETUP_WDT() or SETUP_COUNTERS() (see above)
// RESTART_WDT()
//
#define WDT_18MS 8
#define WDT_36MS 9
#define WDT_72MS 10
#define WDT_144MS 11
#define WDT_288MS 12
#define WDT_576MS 13
#define WDT_1152MS 14
#define WDT_2304MS 15
////////////////////////////////////////////////////////////////// Timer 1
// Timer 1 Functions: SETUP_TIMER_1, GET_TIMER1, SET_TIMER1
// Constants used for SETUP_TIMER_1() are:
// (or (via |) together constants from each group)
#define T1_DISABLED 0
#define T1_INTERNAL 0x85
#define T1_EXTERNAL 0x87
#define T1_EXTERNAL_SYNC 0x83
#define T1_CLK_OUT 8
#define T1_DIV_BY_1 0
#define T1_DIV_BY_2 0x10
#define T1_DIV_BY_4 0x20
#define T1_DIV_BY_8 0x30
////////////////////////////////////////////////////////////////// Timer 2
// Timer 2 Functions: SETUP_TIMER_2, GET_TIMER2, SET_TIMER2
// Constants used for SETUP_TIMER_2() are:
#define T2_DISABLED 0
#define T2_DIV_BY_1 4
#define T2_DIV_BY_4 5
#define T2_DIV_BY_16 6
////////////////////////////////////////////////////////////////// CCP
// CCP Functions: SETUP_CCPx, SET_PWMx_DUTY
// CCP Variables: CCP_x, CCP_x_LOW, CCP_x_HIGH
// Constants used for SETUP_CCPx() are:
#define CCP_OFF 0
#define CCP_CAPTURE_FE 4
#define CCP_CAPTURE_RE 5
#define CCP_CAPTURE_DIV_4 6
#define CCP_CAPTURE_DIV_16 7
#define CCP_COMPARE_SET_ON_MATCH 8
#define CCP_COMPARE_CLR_ON_MATCH 9
#define CCP_COMPARE_INT 0xA
#define CCP_COMPARE_RESET_TIMER 0xB
#define CCP_PWM 0xC
#define CCP_PWM_PLUS_1 0x1c
#define CCP_PWM_PLUS_2 0x2c
#define CCP_PWM_PLUS_3 0x3c
long CCP_1;
#byte CCP_1 = 0x15
#byte CCP_1_LOW= 0x15
#byte CCP_1_HIGH= 0x16
long CCP_2;
#byte CCP_2 = 0x1B
#byte CCP_2_LOW= 0x1B
#byte CCP_2_HIGH= 0x1C
////////////////////////////////////////////////////////////////// PSP
// PSP Functions: SETUP_PSP, PSP_INPUT_FULL(), PSP_OUTPUT_FULL(),
// PSP_OVERFLOW(), INPUT_D(), OUTPUT_D()
// PSP Variables: PSP_DATA
// Constants used in SETUP_PSP() are:
#define PSP_ENABLED 0x10
#define PSP_DISABLED 0
#byte PSP_DATA= 8
////////////////////////////////////////////////////////////////// SPI
// SPI Functions: SETUP_SPI, SPI_WRITE, SPI_READ, SPI_DATA_IN
// Constants used in SETUP_SSP() are:
#define SPI_MASTER 0x20
#define SPI_SLAVE 0x24
#define SPI_L_TO_H 0
#define SPI_H_TO_L 0x10
#define SPI_CLK_DIV_4 0
#define SPI_CLK_DIV_16 1
#define SPI_CLK_DIV_64 2
#define SPI_CLK_T2 3
#define SPI_SS_DISABLED 1
#define SPI_SAMPLE_AT_END 0x8000
#define SPI_XMIT_L_TO_H 0x4000
////////////////////////////////////////////////////////////////// ADC
// ADC Functions: SETUP_ADC(), SETUP_ADC_PORTS() (aka SETUP_PORT_A),
// SET_ADC_CHANNEL(), READ_ADC()
// Constants used in SETUP_ADC_PORTS() are:
#define NO_ANALOGS 0x0F // None
#define ALL_ANALOG 0x00 // A0 A1 A2 A3 A5 E0 E1 E2 B2 B3
#define AN0_TO_AN8_ANALOG 0x06 // A0 A1 A2 A3 A5 E0 E1 E2 B2
#define AN0_TO_AN7_ANALOG 0x07 // A0 A1 A2 A3 A5 E0 E1 E2
#define AN0_TO_AN6_ANALOG 0x08 // A0 A1 A2 A3 A5 E0 E1
#define AN0_TO_AN5_ANALOG 0x09 // A0 A1 A2 A3 A5 E0
#define AN0_TO_AN4_ANALOG 0x0A // A0 A1 A2 A3 A5
#define AN0_TO_AN3_ANALOG 0x0B // A0 A1 A2 A3
#define AN0_TO_AN2_ANALOG 0x0C // A0 A1 A2
#define AN0_TO_AN1_ANALOG 0x0D // A0 A1
#define AN0_ANALOG 0x0E // A0
// The following may be OR'ed in with the above using |
#define VSS_VDD 0x00 //x| Range 0-Vdd
#define VREF_VREF 0x10 //x| Range VrefL-VrefH
#define VRL_VRH 0x20 //x| Range Vrl-Vrh
#define VSS_VREF 0x30 //x| Range 0-VrefH
#define VSS_VRH 0x40 //x| Range 0-Vrh
#define VREF_VDD 0x50 //x| Range VrefL-Vdd
#define VRL_VDD 0x60 //x| Range Vrl-Vdd
#define VSS_VRL 0x70 //x| Range 0-Vrl
// Constants used for SETUP_ADC() are:
#define ADC_OFF 0
#define ADC_CLOCK_DIV_2 1
#define ADC_CLOCK_DIV_8 0x41
#define ADC_CLOCK_DIV_32 0x81
#define ADC_CLOCK_INTERNAL 0xc1
// Constants used in READ_ADC() are:
#define ADC_START_AND_READ 7 // This is the default if nothing is specified
#define ADC_START_ONLY 1
#define ADC_READ_ONLY 6
////////////////////////////////////////////////////////////////// INT
// Interrupt Functions: ENABLE_INTERRUPTS(), DISABLE_INTERRUPTS(),
// EXT_INT_EDGE()
//
// Constants used in EXT_INT_EDGE() are:
#define L_TO_H 0x40
#define H_TO_L 0
// Constants used in ENABLE/DISABLE_INTERRUPTS() are:
#define GLOBAL 0x0BC0
#define INT_RTCC 0x0B20
#define INT_RB 0x0B08
#define INT_EXT 0x0B10
#define INT_AD 0x8C40
#define INT_TBE 0x8C10 // PIE1.TXIE
#define INT_RDA 0x8C20
#define INT_TIMER1 0x8C01 //
#define INT_TIMER2 0x8C02
#define INT_CCP1 0x8C04 // PIE1.CCP1IE
#define INT_CCP2 0x8D01
#define INT_SSP 0x8C08
#define INT_PSP 0x8C80
#define INT_TIMER0 0x0B20
// Defines added by me.
#byte PIR1 = 0x0C
#bit ADIF_bit = 0x0C.6 //
#bit TXIF_bit = 0x0C.4 // USART Transmit Interrupt Flag (1 Buffer Empty, 0 Full)
#byte PIE1 = 0x8C
#bit ADIE_bit = 0x8C.6 // ADC Interrupt (1 Enable, 0 Disable)
#byte REFCON = 0x9B
#byte ADCON0 = 0x1F
#bit ADGO_bit = 0x1F.2 //
#byte ADCON1 = 0x9F
#bit ADFM_bit = 0x9F.7 //
#byte INTCON = 0x0B
#bit GIE_bit = 0x0B.7 //
#byte ADRESL = 0x9E
#byte ADRESH = 0x1E
#list
|
2401.c -- (I commented out the SDA and SCL defines just to eliminate another area of question -- it had no effect. And I tried the 2nd i2c with the NOFORCE_SW -- still didn't help.)
Code: |
///////////////////////////////////////////////////////////////////////////
//// Library for a MicroChip 24LC01B configured for a x8 org ////
//// ////
//// init_ext_eeprom(); Call before the other functions are used ////
//// ////
//// write_ext_eeprom(a, d); Write the byte d to the address a ////
//// ////
//// d = read_ext_eeprom(a); Read the byte d from the address a ////
//// ////
//// The main program may define EEPROM_SDA ////
//// and EEPROM_SCL to override the defaults below. ////
//// ////
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,1997 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
////////////////////////////////////////////////////////////////////////////
//#ifndef EEPROM_SDA
//#define EEPROM_SDA PIN_B1
//#define EEPROM_SCL PIN_B0
//#endif
#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)
//#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL, NOFORCE_SW)
#define EEPROM_ADDRESS byte
#define EEPROM_SIZE 128
void init_ext_eeprom() {
output_float(EEPROM_SCL);
output_float(EEPROM_SDA);
}
void write_ext_eeprom(byte address, byte data) {
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_write(data);
i2c_stop();
delay_ms(11);
}
byte read_ext_eeprom(byte address) {
byte data;
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data=i2c_read(0);
// data=i2c_read();
i2c_stop();
return(data);
}
|
I also tried the "data=i2c_read()" [without the zero] ... no change.
Any other information needed ... I can get it right to you.
I hope your weekend was enjoyable also,
Gag |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 08, 2004 1:42 pm |
|
|
I see these anomalies in your code:
1. There's no #fuse statement. I wonder what your #fuse
settings (ie., config bits) are ?
The fact that your LCD code works, means that the #fuse
settings are probably OK. But still, they should be specified.
2. You're letting the code fall off the end of main(), where
it will hit a sleep statement that CCS puts there.
This shouldn't affect your current problem, but it should
be fixed by adding a while(1); statement before the
closing brace of main().
My suspicion is that there is a hardware problem.
Do you have the SCL pin on the PIC connected to the SCL pin
on the EEPROM ? And, the SDA pins connected together, as well ?
Or do you accidently have them crossed ?
Look at the schematic in this post. Do you have these connections ?
http://www.ccsinfo.com/forum/viewtopic.php?t=17787
This is for a 24LC256. With a 24LC01B, you would also
have to connect the Write Protect pin to Ground, and not
leave it open. (24LC256 has an internal pull-down on it).
You're using a 16C773, and not a flash chip, which would be more
common these days. How are you programming these chips ?
Are you running the code on an actual PIC ? Are you running
all this in a simulator, and not real hardware ? (just checking).
Are you using an ICE ?
I installed PCM vs. 3.148 and tested it with a 24LC256 and a 16F877
(using my test code), and it worked fine. So I don't think there
is a problem with the compiler. |
|
|
Gag
Joined: 05 Mar 2004 Posts: 5 Location: Canyon Country, CA
|
|
Posted: Mon Mar 08, 2004 3:11 pm |
|
|
PCM programmer:
You spoke the works that I was hoping you wouldn't -- "...and it worked fine." Working from your notes, top down ...
I went a head and added the fuses statement (#fuses HS,NOPUT,NOPROTECT,NOWDT,NOBROWNOUT) and your right, it had no effect (ie didn't help). Put next time I'll make sure I add it to all new projects.
I've added the "while(1);" line (didn't help) and noticed all the other forum posts that this line has helped solve. Again, good habit to get into.
As for the hardware wiring, yes it has the SDA and SCL pins matched up and the WP pin tied to Grd. It sounds like you have had problems just like us with miss wiring an IC. Especially when wire wrapping a project like this one is. The schematic I'm working off of is on page 22, 23 from the link below. http://www.microchip.com/download/appnote/devspec/16cxx/00694a.pdf
This link also explains the use of the 16C773. The project is a Ratiometric Sensing project, so we decided not to reinvent the wheel and started with most of the structure in the Microchip article.
We use the PIC16C773/JW chips, programmed in a PicStart Plus, and ZIF inserted into the bread board. It may not be fast, but it works.
So the answer seems to lie with the hardware (even thou I don't see it). I'll keep smacking it around to see what I can find. When (and if) I do find the answer, I'll post it.
Thanks for the help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 08, 2004 3:26 pm |
|
|
I don't know your experience level, so I'll ask this question:
In the link that you posted to AN694, it shows a schematic
of the connections to the 24LC01B EEPROM.
The schematic symbol for the EEPROM shows the pins in a
different order, compared to the actual physical EEPROM chip.
In the actual chip, the pins are numbered like this:
When you wired up the EEPROM, were you aware of this ? |
|
|
Gag
Joined: 05 Mar 2004 Posts: 5 Location: Canyon Country, CA
|
|
Posted: Mon Mar 08, 2004 4:31 pm |
|
|
Thanks for the 'oops' factor check. Yes, I'm aware of the 'U' pin-out for ICs. We design test equipment for the automotive industry here, so I have just a little electrical back ground.
I mean no disrespect, if anything I'm amazed at how supportive this forum is. Essecaly you PCM. With all your posts I wonder how you find the time to answer alot of the questions and still get your work done.
As a little background ... I work with micro-controller designs, PLC, windows based programming, ... but this is my first PIC project. Since this is a battery, handheld project, the PIC chip seemed to be the best platform to use. Every system has its' own quirks, and that is what I was hoping for. That someone read the post and went "Ah yes ... you got to (blank) to make that work."
Given where I'm at with this project (ie everything else is working ... Pressure trans., LCD, Irda, ...), and given that I only need a dozen bytes of eeprom storage, I'm looking at the other PIC chips with internal eeprom memory (and flash programable) today. I just hate to given up.
So, I'm still looking at the hardware side of it. It looks like the Pic is communicating and I'm ordering some new eeproms just to check that the chips aren't DOA.
We'll see what happens.
Thanks again. |
|
|
Kasper
Joined: 14 Jan 2004 Posts: 88 Location: Aurora, Ontario, Canada
|
|
Posted: Mon Mar 08, 2004 5:06 pm |
|
|
Quote: | So, I'm still looking at the hardware side of it. It looks like the Pic is communicating and I'm ordering some new eeproms just to check that the chips aren't DOA. |
Good call.. I have seen serial eeproms die more than once! |
|
|
Gag
Joined: 05 Mar 2004 Posts: 5 Location: Canyon Country, CA
|
|
Posted: Tue Mar 09, 2004 8:48 pm |
|
|
Just a quick update for anyone who cares (at this point I almost don't).
I replaced the 2401 eeprom with a new one and it works ... with one oddity. The following snippet of code shows that I had to step two addresses for the read_ext_eeprom and write_ext_eeprom function calls to work. If I stepped one address at a time i would corrupt the higher address (i can give more details if anyone really needs it).
Code: |
...
union INTVAL { // Union to handle 16-bit values as
long l; // 1 16-bit
int i[2]; // 2 8-bit parts
};
union INTVAL Offset, Gain;
union INTVAL BkLtTime;
union INTVAL Hold2;
...
Offset.i[0] = read_ext_eeprom( 0 );
Offset.i[1] = read_ext_eeprom( 2 );
Gain.i[0] = read_ext_eeprom( 4 );
Gain.i[1] = read_ext_eeprom( 6 );
BkLtTime.i[0] = read_ext_eeprom( 8 );
BkLtTime.i[1] = read_ext_eeprom( 10 );
Hold2.i[0] = read_ext_eeprom( 12 );
Hold2.i[1] = read_ext_eeprom( 14 );
...
write_ext_eeprom(0, Offset.i[0]);
write_ext_eeprom(2, Offset.i[1]);
... etc.
|
This doesn't make complete sense to me. The 2401 chip is a
-- 1 x 128 x 8 (block x byte x bit) device,
-- the PIC chip is an 8bit device, and
-- the functions use 0 thru 128 address, 8bit (1byte) arguments (see the code for the 2401.c above).
What am I missing here ?? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 09, 2004 11:35 pm |
|
|
Quote: | I had to step two addresses for the read_ext_eeprom
and write_ext_eeprom function calls to work. If I stepped
one address at a time i would corrupt the higher address |
I am trying to guess what could cause that problem.
In your previous posts, you showed that you did some
experiments with the 2401.C driver. In your code below
you apparently tried doing the i2c_read operation without
the 0 parameter.
Code: | byte read_ext_eeprom(byte address) {
byte data;
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data=i2c_read(0);
// data=i2c_read();
i2c_stop();
return(data);
} |
Even though the code above is correct, I wonder if you
accidently left it like this:
data=i2c_read();
Can you check the driver and ensure that it looks like this:
data=i2c_read(0); |
|
|
Gag
Joined: 05 Mar 2004 Posts: 5 Location: Canyon Country, CA
|
|
Posted: Wed Mar 10, 2004 10:48 am |
|
|
No ... it is the code with the zero in the parentheses.
I'm like you ... I don't understand what I'm overlooking.
I feel like its just sitting in front of me, but I'm too close to see it.
I just got the CCS "mini software prototyping kit" with the PIC16F877 on it and I'm going to hook up the 24LC01B to it as a test. I'll keep you posted as it goes. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|