Storing 16 bit data in two 8 bit registers

Discussion in 'Programmer's Corner' started by MCrowe, Jul 2, 2011.

  1. MCrowe

    Thread Starter Member

    May 29, 2011
    69
    0
    I hesitate to ask another question because I know people will get sick of me askign things eventually, but I cant figure this one out. What I wanted to know is, is there a simple way to store 16 bits of data into two 8 bit data registers. (ie a value for the 16 bit Timer 1 register) In other programs Ive used, you could write 2 bytes of data to an address and it would just put the first byte in the address, and the second byte in the address+1. I dont think this works in assembly using MPLAB though? does it? It came up with a warning.

    Also, quite similiar question. When declaring variables at the start of my program. Is each variable just assigned 1 byte (8 bits)??
     
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,388
    1,605
    Ask away, that is what this place is for.

    As everything is stored as 8 bit words you just store your 16 bit number in 2 memory registers:

    Code ( (Unknown Language)):
    1. timehi         EQU    0x20
    2. timelo         EQU    0x21
    3.  
    4.     movf    TMR1L, W   ; put low part of timer1 into w
    5.     movwf    timelo     ; moves value from timer1  low to timelo
    6.     movf    TMR1H, W
    7.     movwf    timehi
    Then you can test each one in turn.
    Generally yes, everything is stored as an 8 bit quantity in the memory registers.
     
  3. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    A few tricks:
    if you put
    test16 equ d'1024' ; decimal 1024 is stored in a variable just in the compiler

    at the start, you can later use:

    movlw HIGH(test16)
    movlw LOW(test16)

    or you can just use this in code

    movlw HIGH(d'1024')
    movlw LOW(d'1024')

    Normally each variable is 1 byte but if you use the cblock to define variables you can define arrays;
    The number after the colon is the number of bytes to use, so AARG is at 0x20, REM is at 0x23, BARG is at 25, etc.
    You can use them like this:

    Code ( (Unknown Language)):
    1.     movf hall_0, W
    2.     movwf AARG
    3.     movf hall_0+1, W
    4.     movwf AARG+1
    5.     clrf AARG+2
    Code ( (Unknown Language)):
    1. cblock 0x20
    2.     AARG:3             ;AARG MSByte     AARG+2 LSByte
    3.     REM:2
    4.     BARG:2            ;BARG MSByte
    5.     TEMP
    6.     maxhall_0:2
    7.     minhall_0:2
    8.     maxhall_1:2
    9.     minhall_1:2
    10.     count
    11.     LOOPCOUNT
    12.     heading
    13.     endc
     
  4. MCrowe

    Thread Starter Member

    May 29, 2011
    69
    0
    Hey, thanks for that, now I understand the bit of McLarens PWM code that I couldn't figure out.

    movlw low 1500 ; |B0
    movwf Servo+00 ; Servo 1 lo |B0
    movlw high 1500 ; |B0
    movwf Servo+01 ; Servo 1 hi |B0

    I couldn't figure out why you would put 1500 into the CCPR1H AND CCPR1L registers...

    But it doesn't. the high and low command is used to seperat the high and low byte into the two different registers.!!! (or in this case the array, before they are put into the timer registers)
    Which is EXACTLY what McLaren saids when I asked the question, I just didn't understand how it worked. Ive onyl been at this pic programming stuff for a couple for weeks...

    Awesome, thanks heaps all.

    Actually, this has raised another question :) Can I now use a variable to access different parts of the array? I assume I can, right?

    As in,

    movwf AARG+count

    where count would be 0, 1, or 2.
     
  5. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    Unfortunately it's not quite that easy. Have a look at indirect adressing using FSR and INDF to do it.
     
  6. MCrowe

    Thread Starter Member

    May 29, 2011
    69
    0
    Lol, yeah, im going through all that at the moment.. Got the theory sorted now for indirect addressing. Another question,
    What is this instruction?? I would guess its skip if carry?

    skpc ; borrow? no, skip, else |B0

    This isn't an instruction for my Pic. its from McLarens program.
    i think it skips the next instruction if carry bit is set.

    If so, would

    BTFSS STATUS,C

    do the same thing??
    bit test file, 'status' 'carry bit' skip if set..
     
  7. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,388
    1,605
    You've stumbled across one of the very obscure pseudo PIC commands that is actually documented in the MPASM Assembler Help file under
    12-Bit/14-Bit Instruction Width Pseudo-Instructions.

    You actually decoded it correctly from the context and the comment, so very good!
     
  8. MCrowe

    Thread Starter Member

    May 29, 2011
    69
    0
    Is it possible to Hi-jack your own thread?? Any ways, I'm starting to get a lot of code that im loading on to my PIC, as I test out each function it has, and I was wondering. What happens when I reach the end of the allowable code space in Bank 0?? Does the compiler automatically put the code where it needs to go? I don't understand this part of it at all. I think my manual said I had 96 bytes in bank 0.

    Do I need to put some of the subroutines in Bank 1,2 & 3. And if I do, and I call those subroutines do I need to change Bank to do so. How does this work?
     
  9. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    For Program Memory you won't have any trouble until you get to 2048 instructions unless you are using the table read.
    Have a look at AN556 from the microchip website for how to deal with those and it also goes into the 2048 instruction thing.
    96 bytes is for the data memory.
     
  10. MCrowe

    Thread Starter Member

    May 29, 2011
    69
    0
    oh, My bad. Kinda freaked me out, though I was just going to run out of memory. Actually looking at it I though I should already have run out of memory. Thanks for that.
     
Loading...