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


Closed Thread
Results 1 to 8 of 8
  1. #1
    Join Date
    Jul 2010
    Posts
    14

    Default How to create a 21 bit address and separate into three bytes for Atmel serial eeprom?

    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.

    Code:
    /      /<---------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.
    Code:
    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

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default

    Hi,
    What version of PBP do you have? As of v2.50 32bit variables are available in PBP...
    Code:
    myLong VAR LONG
    And you can access the individual BYTES in a LONG with myLong.BYTE0, myLong.BYTE1 and so on.

    /Henrik.

  3. #3
    Join Date
    Jul 2010
    Posts
    14


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    What version of PBP do you have? As of v2.50 32bit variables are available in PBP...
    Code:
    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.

    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

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default

    Hi,
    I just tried the following code here:
    Code:
    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.
    Attached Images Attached Images  

  5. #5
    Join Date
    Jul 2010
    Posts
    10


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    I just tried the following code here:
    Code:
    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

  6. #6
    Join Date
    Jul 2010
    Posts
    10


    Did you find this post helpful? Yes | No

    Default

    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

  7. #7
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default

    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.

  8. #8
    Join Date
    Jul 2010
    Posts
    10


    Did you find this post helpful? Yes | No

    Default

    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/wfse...p?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.
    Last edited by BryanSw; - 11th September 2010 at 01:37.

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts