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


Closed Thread
Results 1 to 8 of 8

Hybrid View

  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,521


    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,521


    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

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