PDA

View Full Version : PIC16F690 - 24LC08B: they won't talk...



xnihilo
- 22nd May 2008, 01:10
Hello,

I'm p....d off right now.
I'm using a PIC16F690.
I'm trying to store and read back 1 databyte to a 24LC08B EEPROM.
I connected the EEPROM accroding to the schematics found in PBP manual (I2C section).
It does not seem to work.
I've checked to see if I had VDD and VSS at eeprom pins, alright, I use 4.7k WPU; alright.
I don't see what can be wrong. I paste snippets related to this code section.

What's funny is that when I display the value of the value read after the write I get "0" which is not the initial value of the variable before the write. It means it can read (assuming the read walue is "0" but it cannot write (= write value '33' at first position in EEPROM... Why?

Could someone have a look?

Variable declaration:



ep_address VAR BYTE
eep_control VAR BYTE

checkwrite var BYTE 'used to check external EEPROM (in mag) operations



Registers setting


OSCCON = %01110001 'int osc, hs, 8mhz
''''''CMCON0 = %00000111 'comparators OFF, val = 7

CM1CON0.7 = 0 'comparator1 disabled
CM2CON0.7 = 0 'comparator2 disabled

ANSEL = %00000000 'choose digital i/o, val = 0
OPTION_REG = %01111111 'enable internal porta weak pullups resistors (no weak pull-up available for porta.3), p12. they bring pin to High state; to set a change, pull pin to ground


'First PORT then TRIS, see Mid-range MCU DS !!!

TRISA = %011011 'a5 is output (to lcd pins), A4 is input from supplier (score request)
TRISC = %00000000
TRISB = %0000

WPUA = %000111 'enable weak pull ups individually on portA
'Rem: porta.3 (MCLR) has no internal weak pullups, we add an external 10k WPU !!!!
'100k wpd on A4
WPUB = %0000


PORTA = %001111 'set pins logic
PORTB = %0000
PORTC = %00000000 'set pins logic
'porta pins with weak pullups will be set to high (i.e. 5v by the pullups)



Variables initialization



eep_address = 0
eep_control = %10100000 'block 0 (of 0-3), byte 0 (of 0 to 255)


The code section writing and checking EEPROM



'routine that checks if the external eeprom (the mag) is connected to the supplier
'it writes than reads back the test value (33)
checkwrite = 33
eep_address = 0 'use storage byte 1 of 255 fo rthe test
I2CWRITE PORTC.6,PORTC.7,eep_control,eep_address,[checkwrite] 'store maxitem value in the mag external EEPROM
PAUSE 15 'hadware dependent
I2CREAD PORTC.6,PORTC.7,eep_control,eep_address,[checkwrite] 'store maxitem value in the mag external EEPROM
LCDOUT $fe,1,"I2C:",#checkwrite
PAUSE 2000
IF (checkwrite != 33) then
LCDOUT $fe,1,"couldn't write"
PAUSE 4000
checkwrite = 0
GOTO endofroutine
ENDIF
checkwrite = 66

xnihilo
- 22nd May 2008, 08:57
could it be the breadboard connections?

could it be because of the 4.7k wpu on clock and on data pins?

could it be because of the length of wires from pic to eeprom?

could it be because of some registers related to c6 and c7?

sayzer
- 22nd May 2008, 09:02
First things at first look.

1. You set your OSC at 8Mhz. This is for your PIC. You must DEFINE OSC speed to the compiler also. Have DEFINE OSC 8.

2. For PIC16F690, SDA should be RB4 and SCL should be RB6.

xnihilo
- 22nd May 2008, 09:26
First things at first look.

1. You set your OSC at 8Mhz. This is for your PIC. You must DEFINE OSC speed to the compiler also. Have DEFINE OSC 8.

2. For PIC16F690, SDA should be RB4 and SCL should be RB6.

hi.

why rb4 and rb6? i thought i2cwrite was 'bit banging' and it did not matter on which pin it is used???

i'm not using hardware i2c support. then is my connexion still wrong?

xnihilo
- 22nd May 2008, 13:30
Sayzer,

There IS a
DEFINE OSC 8
in my program, i just forgot to paste it...

Here are some things i will have to check/do:

- solder a 8 pins socket on a protoboard instead of breadboard and solder connexions

- use 2k wpu only on sda instead of a 4.7k wpu on each scl and sda

- swap with another pic16f690 in case the one i use is defect

- swap with another 24lc08b in case the one i use is defect

- try a huge pause 50 instead of pause 5 after the i2cwrite in case it is a timing problem

- declare the eeprom address variable as a word instead of as a byte

- declare "eep_address" instead of "ep_address" (i wonder how i didn't see this typing error!)

- try to program a specific value in byte 0 of the eeprom using my pic-pg2 programmer and see if i get this value back with an i2cread

besides this i don't se what i can do...

skimask
- 22nd May 2008, 13:46
- declare the eeprom address variable as a word instead of as a byte
See pages 7 and 10 of this datasheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/21710H.pdf

EDIT: I get the feeling that you're doing a lot of 'thinking out loud' and not a lot of 'doing' (as indicated by the post below).
Not a good way to go about things...

sayzer
- 22nd May 2008, 14:05
Sayzer,

There IS a
DEFINE OSC 8
in my program, i just forgot to paste it...

Here are some things i will have to check/do:

- solder a 8 pins socket on a protoboard instead of breadboard and solder connexions

- use 2k wpu only on sda instead of a 4.7k wpu on each scl and sda

- swap with another pic16f690 in case the one i use is defect

- swap with another 24lc08b in case the one i use is defect

- try a huge pause 50 instead of pause 5 after the i2cwrite in case it is a timing problem

- declare the eeprom address variable as a word instead of as a byte

- declare "eep_address" instead of "ep_address" (i wonder how i didn't see this typing error!)

- try to program a specific value in byte 0 of the eeprom using my pic-pg2 programmer and see if i get this value back with an i2cread

besides this i don't se what i can do...


How did you NOT get an error then?

Also, when you change your code after you asked some questions about it, it is difficult to follow.

Paste a new one with your modifications, so that we can see what the difference was.

xnihilo
- 22nd May 2008, 20:45
"ep_address" instead of "eep_address" didn't generate an error because it is a paste error only. I selected the block starting from the 2nd chara of the line, so it is alright, the variable name is right.

I changed slightly the code:

eep_address VAR WORD
instead of BYTE

and:

I added:

ADCON0.0 = 0 'turn adcon off


Things I wanted to do:

- solder a 8 pins socket on a protoboard instead of breadboard and solder connexions
-> DONE

- use 2k wpu only on sda instead of a 4.7k wpu on each scl and sda
-> DONE, but I used 2K on each of the SCL and SDA pins

- swap with another pic16f690 in case the one i use is defect
-> DONE

- swap with another 24lc08b in case the one i use is defect
-> DONE

- try a huge pause 50 instead of pause 5 after the i2cwrite in case it is a timing problem
-> DONE

- declare the eeprom address variable as a word instead of as a byte
->DONE

- declare "eep_address" instead of "ep_address" (i wonder how i didn't see this typing error!)
-> DONE, no error there in fact

code is:



'routine that checks if the external eeprom (the mag) is connected to the supplier
'it writes than reads back the test value (33)
checkwrite = 33
eep_address = 0 'use storage byte 1 of 255 fo rthe test

LCDOUT $fe,1,"CTRLbyte:",#eep_control
PAUSE 2000

I2CWRITE PORTC.6,PORTC.7,eep_control,eep_address,[checkwrite] 'store maxitem value in the mag external EEPROM
PAUSE 50 'hadware dependent

LCDOUT $FE,1,"Wrote:",#checkwrite,"@",#eep_address
PAUSE 2000

I2CREAD PORTC.6,PORTC.7,eep_control,eep_address,[checkwrite] 'store maxitem value in the mag external EEPROM

LCDOUT $fe,1,"Read:",#checkwrite,"@",#eep_address
PAUSE 2000

IF (checkwrite != 33) then
LCDOUT $fe,1,"couldn't write"
PAUSE 4000
checkwrite = 0
GOTO endofroutine
ENDIF
checkwrite = 66



----------------------


RESULTS:

The output on LCD is:

"wrote:33@0"
"read:0@0"
"couldn'twrite"


So, back to the starting point but this time I have no idea what I could change.
Is it the wires length? Did I failed to set some registers? ...
I'm lost... And angry.
My circuit is useless if I can't write to external eeprom...

skimask
- 22nd May 2008, 21:38
And pin 7 on the eeprom is connected to _______________

mister_e
- 22nd May 2008, 23:47
EEP_ADDRESS MUST be a byte... Something change in the ControlByte when you want to access the other EEPROM Page (Banks). Page 6 of the above data sheet

One more, you haven't disable AN<9:8> yet, and it's your I2C lines... check ANSELH settings.... probably THE MAIN reason why you always have 00 as results. If it was the WP pin of the EEPROM, you would probably have FF all the time. if the device is already blank.

skimask
- 23rd May 2008, 02:44
EEP_ADDRESS MUST be a byte... Something change in the ControlByte when you want to access the other EEPROM Page (Banks). Page 6 of the above data sheet
Yep, sure enough... Figured Microchip should know better than to place 'WORD' above those on page 7 and 10...and the 'sheet even shows 8 bit slots in the diagram...

mister_e
- 23rd May 2008, 04:50
There's always something to screw the understanding here and there huh?

Some call it ControlByte, some other Control Word

Some says Address, some Adress word for 8 bits address...

and so on... nice world... thanks to my avatar :D

xnihilo
- 23rd May 2008, 08:50
And pin 7 on the eeprom is connected to _______________

to gnd of course. i do not want to write protect the chip.

xnihilo
- 23rd May 2008, 09:01
There's always something to screw the understanding here and there huh?

Some call it ControlByte, some other Control Word

Some says Address, some Adress word for 8 bits address...

and so on... nice world... thanks to my avatar :D

I will change my code and let you know if anything changes.
Thanks a lot for your help guys.
(If it doesnt work I'll try to find a simple program to write a byte to ter 24lc08b from a 16f684 (which I start to be fami iar with) and if it works I can try to migrate the code to the 16f690, which is a chip still full of secrets to me).

By the way, as you pointed out the datasheet talks about WORD... and for me a word is supposed to be a two bytes chunk of data... this does not help clear confused minds like mine...

xnihilo
- 23rd May 2008, 15:40
Funny, i have just read the chapter 4.2.1 dedicated to ANSEL. it is witten that if left set, the bits will lead to a 0 being read everytime.
rc6 and rc7 wew still analog, as you pointed out mister_e. No wonder why i got 0 when reading back.
This is because i'm used to pic16f684 where there is only ansel and no anselh so i didn't think of checking again all registers for 16f690, now I know i should.

in the meantime i wonder if there are other registers that i should care of like these related to serial connections: eusart, ssp,...

We have to think of so many things when using a pic. there are habits and good practices i don't have yet...

mister_e
- 24th May 2008, 01:29
If you're not sure, refer to the end of each module section, they provide you the related register list for the according module. Table 9-2 (pdf page 120) for the ADC

xnihilo
- 24th May 2008, 22:32
Hi,

Thanks for your answer. It works now.
I've used anselh = 0 and now I get the righ value back when reading a value from the pic.