PDA

View Full Version : How to create a 21 bit address and separate into three bytes for Atmel serial eeprom?



BrianS
- 7th September 2010, 17:53
I am using a atmel AT45DB161D serial eeprom and need to do a continious memory read.
I am programming a pic 18f4620.

This is the code the format of the 21 bits I need to send.
I would need to send this as 3 bytes but don't know how to do this correctly.


/ /<---------Page Addr--------------->/<------starting byte----->/
/X,X,X,20,19,18,17,16/15,14,13,12,11,10,09,08/07,06,05,04,03,02,01,00/

The XXX are don't care bits.

In another compiler I can do this by using a Dword (32 bits) variable and the split the 32 bits into 4 bytes. Using only the last 3 bytes. This is accomplished using a pascal compiler using following code example.


procedure mm_rd_cmd(start:dword);
begin
BusyWait;
CS_Low;
SPI1_Write($E8);
SPI1_Write(higher(start));
SPI1_Write(hi(start));
SPI1_Write(lo(start));
SPI1_Write($00);
SPI1_Write($00);
SPI1_Write($00);
SPI1_Write($00);
end;
The higher, hi, and lo break the 24 bits of var "start" (a 32 bit Dword) into 3 lower bytes. Discarding the highest byte (bits 25 - 32).
Is there a way to get Picbasic Pro to do a similar thing. Help is greatly appreciated.

Thanks,
Bryan

HenrikOlsson
- 7th September 2010, 18:24
Hi,
What version of PBP do you have? As of v2.50 32bit variables are available in PBP...

myLong VAR LONG
And you can access the individual BYTES in a LONG with myLong.BYTE0, myLong.BYTE1 and so on.

/Henrik.

BrianS
- 7th September 2010, 21:12
Hi,
What version of PBP do you have? As of v2.50 32bit variables are available in PBP...

myLong VAR LONG
And you can access the individual BYTES in a LONG with myLong.BYTE0, myLong.BYTE1 and so on.

/Henrik.

Looks like a good solution. I tried it but it give an incorrect result on the third highest byte.
here a portion of the code.


rd_addr2 var long

rd_addr2 = $01FE

Readout_Strings:
gosub BusyWait
Low CSEE
Shiftout SDO,SCK,Msbfirst,[$E8]
Shiftout SDO,SCK,Msbfirst,[rd_addr2.byte2]
Shiftout SDO,SCK,Msbfirst,[rd_addr2.byte1]
Shiftout SDO,SCK,Msbfirst,[rd_addr2.byte0]
Shiftout SDO,SCK,Msbfirst,[$00]
Shiftout SDO,SCK,Msbfirst,[$00]
Shiftout SDO,SCK,Msbfirst,[$00]
Shiftout SDO,SCK,Msbfirst,[$00]
return

rd_addr2.byte2 = 16 or binary 10000 which is wrong it should be 0. Nothing else changes the value of rd_addr2 it's value is defined at the start of the code and nothing else alters it. Is, there any possible explaination for this that can cause the value to be wrong?

Thanks,
Bryan

HenrikOlsson
- 7th September 2010, 21:34
Hi,
I just tried the following code here:

rd_addr2 VAR LONG
rd_addr2 = $01FE
Pause 1000
HSEROUT [DEC3 rd_addr2.BYTE3, ",", DEC3 rd_addr2.BYTE2, ",", DEC3 rd_addr2.BYTE1, ",", DEC3 rd_addr2.BYTE0,10,13]
And it displays 000,000,001,254 on the serial terminal (see attached screenshot) so IT seems to work. Don't know why you would get 16.....

/Henrik.

BryanSw
- 8th September 2010, 00:53
Hi,
I just tried the following code here:

rd_addr2 VAR LONG
rd_addr2 = $01FE
Pause 1000
HSEROUT [DEC3 rd_addr2.BYTE3, ",", DEC3 rd_addr2.BYTE2, ",", DEC3 rd_addr2.BYTE1, ",", DEC3 rd_addr2.BYTE0,10,13]
And it displays 000,000,001,254 on the serial terminal (see attached screenshot) so IT seems to work. Don't know why you would get 16.....

/Henrik.

Really got me. I'll try the code all by itself without anything else and see what I get. Won't have a reply till tomorrow about this because I'm not at work now to try it. Hope it is something I can correct. Really need to get this working for a project at work. I use other compilers at home for personal use by at work I have to use PBP.

Thanks,
Bryan

BryanSw
- 10th September 2010, 00:20
OK, I got it working normally. What I had to do to make it work makes no sense to me because it should have worked the way I had it. Anyway I had to move

rd_addr2 VAR LONG
rd_addr2 = $01FE

into the same sub routine as

Pause 1000
HSEROUT [DEC3 rd_addr2.BYTE3, ",", DEC3 rd_addr2.BYTE2, ",", DEC3 rd_addr2.BYTE1, ",", DEC3 rd_addr2.BYTE0,10,13]

Then it worked.
If I put the
rd_addr2 VAR LONG
rd_addr2 = $01FE
at the top of my program with my global vars definations and assign a value to
rd_addr2 also at the top of my program it would give me an incorrect result.

I will play around with this some more as there has to be a reason for it. I am not assigning anything else at any othe time to rd_addr2.

Thanks,
Bryan

HenrikOlsson
- 10th September 2010, 06:19
Hi,
That's weird.... I don't think it matters (or should matter) where you put the variable declaration. What if you put the declaration at the top but assign a value to it right before the HSEROUT (or SHIFTOUT) statement?

Are you using any aliases or any Arrays? There are no boundary checks on arrays in PBP so if you are using an array and accidently write "outside of it" you will write to variable(s) adjacent to the array.

To me it sounds as if there's something in your code that write 16 to the third byte of your LONG, is it allways 16 by the way?

/Henrik.

BryanSw
- 11th September 2010, 00:32
No, don't have any arrays at all. That is what I was thinking that somehow I was over writing memory somewhere. I gave it a few days of rest as I had other jobs at work to perform. So, probably I won't get back to it till Monday or Tuesday next week. I do have a lot of variables I use in the program which I'm trying to thin down as much as I can. Actually you know what maybe it is this string storage thing I'm doing that is causing the problem. It's posted here.
Written by Darrel Taylor

http://www.pbpgroup.com/modules/wfsection/article.php?articleid=10

I haven't looked at it in any great detail.

I am also using an interrupt handler also written by Darrel Taylor

http://darreltaylor.com/DT_INTS-18/home.html

These could be affecting the Pic's memory somehow. Like I said I have not looked into all the code of his I use to see how it may be affecting memory. I hope not because I really need those routines. Especially the interrupt routines.