Per Kent's advice, this is a new but related thread on his eeprom routine. Here's the set-up. I have a toggle switch on A.0. In one position, reading from the 24LC256 is demoed, in the other position writing to the chip is demoed (always after a restart power-up).
The results appear on serial terminal software. When writing to the eeprom, I have the terminal software send one character at a time, with a 50 mS pause between each.
Here's the trouble: reading the eeprom always works, but writing to it always sends the same garbage. I had previously done a similar project with similar source code on a PICAXE which worked flawlessly. Here's my GC Basic code. I hope it formats halfway decently on this forum:
;A program to send and receive text to and from the
;24LC256 eeprom using software I2C routines.
if sw = 0 then ;read eeprom
address = 0 ;prime the loop
datum = eeprom_receive(msb, lsb)
do while datum <> eof ;quit if end of file
serSend 1, datum ;else send to terminal
address ++ ;set for the next byte
datum = eeprom_receive(msb, lsb)
loop
else ;write to eeprom
serReceive 1, datum ;get first datum
address = 0
do while datum <> eof
eeprom_send(msb, lsb, datum)
wait 10 mS
address ++ ;point to next address
serReceive 1, datum ;get next datum
loop
eeprom_send(msb, lsb, eof) ;append eof marker
end if
Thanks, Thomas Henry
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Kent - This looks like the same issue that I am currently re. Does this circuit have pulls up on the I2C lines? If so, then the new code may resolve this issue. If not, ignore this comment.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2013-10-02
Yes, I should have mentioned it. I do have 4.7k pull-ups on both lines.
Thomas Henry
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thomas et al thanks for starting another thread, since we are talking about my old software I2C header file, as opposed to the GCBasic inbuilt routines. Things can get confusing in a hurry.
It's been quite awhile since I've played with the soft I2C. Also, couldn't find by Olimex Pic-P18 board, so the Pic-P40 and a 16f877A chip will have to do for my example. Even lost my soft I2C with pullup header file, good reason to share on the forum :).
Had trouble with the SerSend, so you get a double dose with a soft USART routine also, set for 9600 Buad. No internal osc with the 16f877A, so the OSC is 20MHZ crystal.
The original soft I2C header seems just fine. My trouble was with the SerSend, so here is my working example. No serial receive going on, just write some numbers, then read back every 30 sec on the terminal.
Let me know if any questions, I notice there was no include? in your posted code.
#chip 16f877A,20#config OSC=HS#include<I2CMstrSoftPullup.h> 'Or whatever you want to call it#define SDA PortC.4 '16f877A#define SCL PortC.3 '16f877A#define waittime 1 ms#define chipwrite b'10100000' '24lc256 address 1010+A2A1A0+R/W#define chipread b'10100001'DimaddressasWord'InitSer1,r2400,1+WaitForStart,8,1,none,normal'#defineSerOutPortPortB.1;serialoutputonpin2'#defineSerInPortPortB.0;serialinputonpin3'#defineSendAHighSetSerOutPorton;outputlogiclevels'#defineSendALowSetSerOutPortoff'#defineRecAHighSerInPorton;inputlogiclevels'#defineRecALowSerInPortoff'dirSerInPortinCallSer_Initaddress=0Forlogtemp=0to255address=address+1addrl=addressaddrh=address_heeprom_send(addrh,addrl,logtemp)wait10ms'Needsomedelayhereforproperoperation'SerSend1,logtempbin2asciilogtempXmit_RS23210:Xmit_RS23213;linefeed,carriagereturnNextwait30sMain:Doaddress=0ForlogtempA=0to255address=address+1addrl=addressaddrh=address_heepromA=eeprom_receive(addrh,addrl)wait10ms'SerSend1,eepromAbin2asciieepromAXmit_RS23210:Xmit_RS23213;linefeed,carriagereturnNextwait30sLoopgotoMainSubSer_Init;slightadjustmentwasrequiredfor9600bpsdelayvalue#define baud 103#define halfbaud 52 ;place Read of SerRx in middle of bit#define SerTxHigh Set PortB.1 On#define SerTxLow Set PortB.1 Off#define SerRx PortB.0dirPortB.1out;TxdirPortB.0in;RxSerTxHigh;InitialRS232idlestateendsubSubRCV_RS232RxWait:IFSerRxOnThengotoRCV_RS232;waitforstartbitwaithalfbaudus;dohalfbittimedelayIfSerRxOnThengotoRxWaitRxByte=0ForRxBit=1to8;setuptoread8bitswaitbaudusRotateRxByteRightIfSerRxOnthenSetRxByte.71IfSerRxOffThenSetRxByte.70NextwaitbaudusEndsubsubXMIT_PRINT(PrintData$)PrintLen=PrintData(0)ifPrintLen=0thenexitsub'WriteDataforSysPrintTemp=1toPrintLenXMIT_RS232(PrintData(SysPrintTemp))nextendsubSubXMIT_RS232(Xmit_Byte)#NRSerTxLowwaitbaudusForcntr=1to8RotateXmit_ByteRightIfStatus.CONThenSerTxHighIfStatus.COffThenSerTxLowwaitbaudusNextSerTxHighwaitbaudusendsubsubbin2ascii(LCDValue)#NRLCDValueTemp=0LCDShowChar=0SERCEN=0SERDEC=0SERUN=0IfLCDValue>=100thenLCDValueTemp=LCDValue/100LCDValue=SysCalcTempXSERCEN=LCDValueTemp+48Xmit_RS232(SERCEN)LCDShowChar=TRUEEndIfIfLCDShowChar>0orLCDValue>=10thenLCDValueTemp=LCDValue/10LCDValue=SysCalcTempXSERDEC=LCDValueTemp+48Xmit_RS232(SERDEC)EndIfSERUN=LCDValue+48Xmit_RS232(SERUN)EndSubsubbin2ascii(LCDValueasword)#NRDimSysCalcTempXAsWordLCDValueTemp=0LCDShowChar=0SERDECMIL=0SERMIL=0SERCEN=0SERDEC=0SERUN=0IfLCDValue>=10000thenLCDValueTemp=LCDValue/10000[word]LCDValue=SysCalcTempXSERDECMIL=LCDValueTemp+48Xmit_RS232(SERDECMIL)LCDShowChar=TRUEEndIfIfLCDShowChar>0orLCDValue>=1000thenLCDValueTemp=LCDValue/1000[word]LCDValue=SysCalcTempXSERMIL=LCDValueTemp+48Xmit_RS232(SERMIL)LCDShowChar=TRUEEndIfIfLCDShowChar>0orLCDValue>=100thenLCDValueTemp=LCDValue/100[word]LCDValue=SysCalcTempXSERCEN=LCDValueTemp+48Xmit_RS232(SERCEN)LCDShowChar=TRUEEndIfIfLCDShowChar>0orLCDValue>=10thenLCDValueTemp=LCDValue/10[word]LCDValue=SysCalcTempXSERDEC=LCDValueTemp+48Xmit_RS232(SERDEC)EndIfSERUN=LCDValue+48Xmit_RS232(SERUN)EndSub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2013-10-03
Thank you, Kent. I'll give it a whirl as soon as I can get my decrepit workbench laptop up and running (I hope yet tonight).
The Include is indeed in my file, but disappeared on the Forum posting. Just what is the secret of making code look right, including the comments, spaces and font?
Thanks again, so much for dipping into this.
Thomas Henry
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The Formatting Help button has the answer, been mentioned before, use the tilde's being sure their is a blank line before and after too.
"~~~~"
code here
"~~~~"
So without the exclamations:
code here
Check preview, and should be good to go now.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2013-10-04
Hi Kent,
Well, you're right. The original header file code seems to be fine. I changed my experiment so that rather than getting the text to be written to the eeprom from the serial port, I get it from an internal string and send it one character at a time.
In a nutshell, either the software serial stuff is troublesome, or there's an unexpected interaction between your I2C eeprom code and the GC Basic software serial routines.
I'll have to rethink how I'm going to handle this, but at least I now know that it is possible to reliably read and write to the 24LC256 on its own.
Thanks again for your good work.
Thomas Henry
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello all,
Per Kent's advice, this is a new but related thread on his eeprom routine. Here's the set-up. I have a toggle switch on A.0. In one position, reading from the 24LC256 is demoed, in the other position writing to the chip is demoed (always after a restart power-up).
The results appear on serial terminal software. When writing to the eeprom, I have the terminal software send one character at a time, with a 50 mS pause between each.
Here's the trouble: reading the eeprom always works, but writing to it always sends the same garbage. I had previously done a similar project with similar source code on a PICAXE which worked flawlessly. Here's my GC Basic code. I hope it formats halfway decently on this forum:
;A program to send and receive text to and from the
;24LC256 eeprom using software I2C routines.
;----- Configuration
#chip 16F88, 8 ;PIC16F88 running at 8 MHz
#config mclr=off ;reset handled internally
#config osc=int ;use internal clock
#include <I2CEeprom.h> ;Kent's header file
;----- Constants
#define sw PortA.0 ;toggle switch on pin 17
#define SerOutPort PortA.3 ;serial output on pin 2
#define SerInPort PortA.4 ;serial input on pin 3
#define SendAHigh Set SerOutPort on ;output logic levels
#define SendALow Set SerOutPort off
#define RecAHigh SerInPort on ;input logic levels
#define RecALow SerInPort off
#define SDA PortB.0 ;data on pin 6
#define SCL PortB.1 ;clock on pin 7
#define waittime 1 ms
#define chipwrite b'10100000' ;I2C address 000
#define chipread b'10100001'
#define eof 0xff ;end of file marker
;----- Variables
dim msb, lsb, datum as byte
dim address as word alias msb, lsb
;----- Program
dir PortA 0b11110111
InitSer 1, r2400, 1+WaitForStart, 8, 1, none, invert
if sw = 0 then ;read eeprom
address = 0 ;prime the loop
datum = eeprom_receive(msb, lsb)
else ;write to eeprom
serReceive 1, datum ;get first datum
address = 0
end if
Thanks, Thomas Henry
Kent - This looks like the same issue that I am currently re. Does this circuit have pulls up on the I2C lines? If so, then the new code may resolve this issue. If not, ignore this comment.
Yes, I should have mentioned it. I do have 4.7k pull-ups on both lines.
Thomas Henry
Thomas et al thanks for starting another thread, since we are talking about my old software I2C header file, as opposed to the GCBasic inbuilt routines. Things can get confusing in a hurry.
It's been quite awhile since I've played with the soft I2C. Also, couldn't find by Olimex Pic-P18 board, so the Pic-P40 and a 16f877A chip will have to do for my example. Even lost my soft I2C with pullup header file, good reason to share on the forum :).
Had trouble with the SerSend, so you get a double dose with a soft USART routine also, set for 9600 Buad. No internal osc with the 16f877A, so the OSC is 20MHZ crystal.
The original soft I2C header seems just fine. My trouble was with the SerSend, so here is my working example. No serial receive going on, just write some numbers, then read back every 30 sec on the terminal.
Let me know if any questions, I notice there was no include? in your posted code.
Thank you, Kent. I'll give it a whirl as soon as I can get my decrepit workbench laptop up and running (I hope yet tonight).
The Include is indeed in my file, but disappeared on the Forum posting. Just what is the secret of making code look right, including the comments, spaces and font?
Thanks again, so much for dipping into this.
Thomas Henry
The Formatting Help button has the answer, been mentioned before, use the tilde's being sure their is a blank line before and after too.
"~~~~"
code here
"~~~~"
So without the exclamations:
Check preview, and should be good to go now.
Hi Kent,
Well, you're right. The original header file code seems to be fine. I changed my experiment so that rather than getting the text to be written to the eeprom from the serial port, I get it from an internal string and send it one character at a time.
In a nutshell, either the software serial stuff is troublesome, or there's an unexpected interaction between your I2C eeprom code and the GC Basic software serial routines.
I'll have to rethink how I'm going to handle this, but at least I now know that it is possible to reliably read and write to the 24LC256 on its own.
Thanks again for your good work.
Thomas Henry