PDA

View Full Version : EEPROM Read problem



Christos_K
- 5th June 2005, 02:41
Hi! I ve been trying to use an EEPROM to store results from a/d conversion.

Can you spot anything wrong with my code?
================================================== ========
DEFINE HSER_RCSTA 90h 'Enable Serial PORT
'8 bit reception
'Disable Single receive
'Enable continuous receive
'All bytes received, diable address detection
'No framming Error
'No overrun error

DEFINE HSER_TXSTA 20h '8 bit transmission
'Enable transmit
'Asyncronous mode
'Low baud rate (BRGH=0)
'TSR full

DEFINE HSER_SPBRG 64 'set USART to 2400 baud (when BRGH=0)

DEFINE HSER_CLROERR 1 'Enable automatic overrun error


'Oscillation Settings
'---------------------
DEFINE OSC 10 'Oscillation Speed 10MHz


'ADC settings
'-------------

DEFINE ADC_BITS 10 '10 bits conversion
DEFINE ADC_CLOCK 3 'Clock cycle (3=rc)
DEFINE ADC_SAMPLEUS 50 'Sampling time in ìs

INCLUDE "modedefs.bas"

CS var PORTA.5 ' Chip select pin
SCK var PORTC.3 ' Clock pin
SI var PORTC.4 ' Data in pin
SO var PORTC.5 ' Data out pin

addr var word ' Address
adc var word ' Result from ADC
adc1 var word ' read from memory result

TRISA.5 = 0 ' Set CS to output

'ADCON1 = 7 ' Set PORTA and PORTE to digital

trisa = %11011111
ADCON1 = %10001110 'Right Justified result format
'Only PortA.0 analogue input, Vref+ = Vcc, Vref-=Vss

addr = 0 'Inital address 0000h
MAIN:

ADCIN 0, ADC
hserout [#adc,13] 'check a/d conversion before writting to mem
gosub eewrite
pause 50 ' Delay after each write
gosub eeread
hserout[#addr, "," , #adc1,13]
pause 1000
addr = addr + 1
goto main



' Subroutine to read data from addr in serial EEPROM
eeread:
ADDR = ADDR - 1
CS = 0 ' Enable serial EEPROM
Shiftout SI, SCK, MSBFIRST, [$03, addr.byte1, addr.byte0]
Shiftin SO, SCK, MSBPRE, [adc1.Byte1] ' Read data
cs = 1
pause 50
addr = addr + 1
cs = 0
Shiftout SI, SCK, MSBFIRST, [$03, addr.byte1, addr.byte0]
Shiftin SO, SCK, MSBPRE, [adc1.byte0] ' Read data
CS = 1 ' Disable
Return

' Subroutine to write data at addr in serial EEPROM
eewrite: CS = 0 ' Enable serial EEPROM
Shiftout SI, SCK, MSBFIRST, [$06] ' Send write enable command
CS = 1
CS = 0 ' Enable
Shiftout SI, SCK, MSBFIRST, [$02, addr.byte1, addr.byte0, adc.byte1]
cs = 1
pause 50
addr = addr + 1
cs=0
Shiftout SI, SCK, MSBFIRST, [$02, addr.byte1, addr.byte0, adc.byte0]
CS = 1
Return
================================================== =======

I canot get the correct result when reading from eeprom


The eeprom i am using is an 25LC640 SPI and I have tested it with a single data store to an address and it works...

mister_e
- 5th June 2005, 08:47
' Subroutine to read data from addr in serial EEPROM
eeread:
ADDR = ADDR - 1
CS = 0 ' Enable serial EEPROM



what about addr=addr-2 since you write 2 bytes?

Christos_K
- 5th June 2005, 15:29
Well, at the first read/write the memory is 0000h. When sub eewrite is called adc.Byte1 should be written in 0000h and then the address becooes addr+1 or 0001h and adc.Byte0 is written there.

The the sub returns and sub eeread is called. The previous address was 0001h..so i am thinking is should substract 1 so that it can read whatever is written in 0000h first and then add 1 again to read whatever is in 0001h....Does this sound wrong?

Christos_K
- 5th June 2005, 16:21
I think I found what my problem is although I don't understand why...
Taking everything out I just wrote a smple code where I store the 16bit value 1234 in a word variable and then I hserout the .byte1 and .byte0 of the variable...

================================================== ======
test var word

MAIN:

pause 1000
test = 1234
hserout [#test,13]
hserout [#test.Byte1,13,#test.Byte0,13]
goto main
================================================== =====

I get:
1234 (which is the value of test and is correct)
4 (this is test.byte1 which should be 12)
210 (this is test.byte0 which should be 34)

What am I doing wrong here??

Christos_K
- 5th June 2005, 17:06
Sorry for all those contiuous posts! just wanted to let you know that the problem is fixed now.
Apparently when you want to write to this SPI memory a 16bit value (word) you don't have to write the first 8bits then increase the address by one and then write the following 8 bits. You just set the initial address and then enter the two 8bit values you want to store and the address is increased automatically. In order to read from the eeprom though you do need to increase the address (i think). I give the following working code for reference:

================================================== =======
' PIC setting & Programming mode
' -------------------------------
'
' HS(10Mhz) oscillator
' Enable watch dog timer
' Enable power up timer
' Enable brown out detect
' Disable low voltage programming

'Usart Settings
' --------------
'
DEFINE HSER_RCSTA 90h 'Enable Serial PORT
'8 bit reception
'Disable Single receive
'Enable continuous receive
'All bytes received, diable address detection
'No framming Error
'No overrun error

DEFINE HSER_TXSTA 20h '8 bit transmission
'Enable transmit
'Asyncronous mode
'Low baud rate (BRGH=0)
'TSR full

DEFINE HSER_SPBRG 64 'set USART to 2400 baud (when BRGH=0)

DEFINE HSER_CLROERR 1 'Enable automatic overrun error


'Oscillation Settings
'---------------------
DEFINE OSC 10 'Oscillation Speed 10MHz


'ADC settings
'-------------

DEFINE ADC_BITS 10 '10 bits conversion
DEFINE ADC_CLOCK 3 'Clock cycle (3=rc)
DEFINE ADC_SAMPLEUS 50 'Sampling time in ìs

INCLUDE "modedefs.bas"

CS var PORTA.5 ' Chip select pin
SCK var PORTC.3 ' Clock pin
SI var PORTC.4 ' Data in pin
SO var PORTC.5 ' Data out pin

addr var word ' Address
adc var word ' Result from ADC
adc1 var word ' read from memory result

TRISA.5 = 0 ' Set CS to output

trisa = %11011111
adcon1 = %10001110

addr = 0

MAIN:
adcin 0,adc
hserout [#adc,13]
gosub eewrite
pause 500 ' Delay after each write
gosub eeread
hserout [#adc1,13] 'Display the result from eeprom read
pause 1000
addr = addr + 1
goto main



' Subroutine to read data from addr in serial EEPROM
eeread:
CS = 0 ' Enable serial EEPROM
Shiftout SI, SCK, MSBFIRST, [$03, addr.byte1, addr.byte0]
Shiftin SO, SCK, MSBPRE, [adc1.Byte1] ' Read data
cs = 1
pause 500
addr = addr + 1
cs = 0
Shiftout SI, SCK, MSBFIRST, [$03, addr.byte1, addr.byte0]
Shiftin SO, SCK, MSBPRE, [adc1.byte0] ' Read data
CS = 1 ' Disable
Return

' Subroutine to write data at addr in serial EEPROM
eewrite: CS = 0 ' Enable serial EEPROM
Shiftout SI, SCK, MSBFIRST, [$06] ' Send write enable command
CS = 1
CS = 0 ' Enable
Shiftout SI, SCK, MSBFIRST, [$02, addr.byte1, addr.byte0, adc.byte1, adc.byte0]
cs = 1
pause 500
Return
================================================== ========

The pause values can be much smaller I guess!

NavMicroSystems
- 5th June 2005, 17:10
Your Code works as designed:

with test being a word variable holding the decimal value of 1234 it reads binary: 0000010011010010

the lowbyte of test equals binary 11010010 (decimal 210)
the highbyte of test equals binary 00000100 (decimal 4)