PIC18f indirect addressing

Discussion in 'Embedded Systems and Microcontrollers' started by RG23, May 9, 2013.

  1. RG23

    Thread Starter Active Member

    Dec 6, 2010
    301
    2
    I want to shift one column data to another column from column 71 to column 72

    When I press switch 1, I display only one column of data

    When I press switch 2, it should shift the data to the next column

    Please have a look at the two simple subroutines below

    B1, B2, B3, B4 are the four pages I use to get 32 bit vertical data column

    Ignore the SND_CMD and SND_DTA subroutines as they are just the LCD command and data subroutines for the location on display

    I am displaying the data in column 71 correctly

    I am not getting the shifted data in column 72 correctly

    Code ( (Unknown Language)):
    1.  
    2.  
    3. //////column 71 is used here
    4. //////SND_CMD is the command subroutine
    5. //////SND_DTA is the data subroutine
    6.  
    7. label_diplay_column_data:
    8.  
    9.  
    10. LFSR 1,h'100'
    11. movlw 0xFF
    12. movwf INDF1
    13. movf POSTINC1,0
    14. movlw 0xFF
    15. movwf INDF1
    16.  
    17. movf POSTINC1,0
    18. movlw 0xFF
    19. movwf INDF1
    20.  
    21. movf POSTINC1,0
    22. movlw 0xFF
    23. movwf INDF1
    24.  
    25. movlw 0xB1
    26. movwf PORTD
    27. call SND_CMD
    28.  
    29. movlw 0x17
    30. movwf PORTD
    31. call SND_CMD
    32.  
    33. movlw 0x01
    34. movwf PORTD
    35. call SND_CMD
    36. movf POSTDEC1,0
    37. movf INDF1,0
    38. movwf PORTD
    39. call SND_DTA
    40.  
    41. movlw 0xB2
    42. movwf PORTD
    43. call SND_CMD
    44.  
    45. movlw 0x17
    46. movwf PORTD
    47. call SND_CMD
    48.  
    49. movlw 0x01
    50. movwf PORTD
    51. call SND_CMD
    52. movf POSTDEC1,0
    53. movf INDF1,0
    54.  
    55. movwf PORTD
    56. call SND_DTA
    57.  
    58. movlw 0xB3
    59. movwf PORTD
    60. call SND_CMD
    61.  
    62. movlw 0x17
    63. movwf PORTD
    64. call SND_CMD
    65.  
    66. movlw 0x01
    67. movwf PORTD
    68. call SND_CMD
    69. movf POSTDEC1,0
    70. movf INDF1,0
    71.  
    72. movwf PORTD
    73. call SND_DTA
    74.  
    75. movlw 0xB4
    76. movwf PORTD
    77. call SND_CMD
    78.  
    79. movlw 0x17
    80. movwf PORTD
    81. call SND_CMD
    82.  
    83. movlw 0x01
    84. movwf PORTD
    85. call SND_CMD
    86.  
    87. movf INDF1,0
    88.  
    89. movwf PORTD
    90. call SND_DTA
    91.  
    92. return
    93.  
    94.  
     
    Last edited: May 9, 2013
  2. RG23

    Thread Starter Active Member

    Dec 6, 2010
    301
    2
    Code ( (Unknown Language)):
    1.  
    2. label_display_shifted_datacolumn:
    3.          
    4.           movlw  0xB1
    5.           movwf  PORTD
    6.           call   SND_CMD
    7.        
    8.          movlw  0x17
    9.          movwf  PORTD
    10.          call   SND_CMD
    11.          movlw  0x01
    12.          movwf  PORTD
    13.          call   SND_CMD
    14.          movlw   0x00
    15.          movwf  PORTD
    16.          call   SND_DTA
    17.  
    18.          movlw  0xB2
    19.          movwf  PORTD
    20.          call   SND_CMD
    21.        
    22.          movlw  0x00
    23.          movwf  PORTD
    24.          call   SND_CMD
    25.          movlw  0x01
    26.          movwf  PORTD
    27.          call   SND_CMD
    28.          movlw   0x00
    29.          movwf  PORTD
    30.          call   SND_DTA
    31.          movlw  0xB3
    32.          movwf  PORTD
    33.          call   SND_CMD
    34.        
    35.          movlw  0x17
    36.          movwf  PORTD
    37.          call   SND_CMD
    38.          movlw  0x01
    39.          movwf  PORTD
    40.          call   SND_CMD
    41.          movlw   0x00
    42.          movwf  PORTD
    43.          call   SND_DTA
    44.          movlw  0xB4
    45.          movwf  PORTD
    46.          call   SND_CMD
    47.        
    48.          movlw  0x17
    49.          movwf  PORTD
    50.          call   SND_CMD
    51.          movlw  0x01
    52.          movwf  PORTD
    53.          call   SND_CMD
    54.          movlw   0x00
    55.          movwf  PORTD
    56.          call   SND_DTA
    57.  
    58.          movlw  0xB1
    59.           movwf  PORTD
    60.           call   SND_CMD
    61.        
    62.          movlw  0x17
    63.          movwf  PORTD
    64.          call   SND_CMD
    65.          movlw  0x02
    66.          movwf  PORTD
    67.          call   SND_CMD
    68.          
    69.          movf   INDF1,0
    70.          movwf  PORTD
    71.          call   SND_DTA
    72.          movlw  0xB2
    73.          movwf  PORTD
    74.          call   SND_CMD
    75.        
    76.          movlw  0x17
    77.          movwf  PORTD
    78.          call   SND_CMD
    79.          movlw  0x02
    80.          movwf  PORTD
    81.          call   SND_CMD
    82.          movf   POSTINC1,0
    83.          movf   INDF1,0
    84.          movwf  PORTD
    85.          call   SND_DTA
    86.          movlw  0xB3
    87.          movwf  PORTD
    88.          call   SND_CMD
    89.        
    90.          movlw  0x17
    91.          movwf  PORTD
    92.          call   SND_CMD
    93.          movlw  0x02
    94.          movwf  PORTD
    95.          call   SND_CMD
    96.          movf   POSTINC1,0
    97.          movf   INDF1,0
    98.          movwf  PORTD
    99.          call   SND_DTA
    100.          movlw  0xB4
    101.          movwf  PORTD
    102.          call   SND_CMD
    103.        
    104.          movlw  0x17
    105.          movwf  PORTD
    106.          call   SND_CMD
    107.          movlw  0x02
    108.          movwf  PORTD
    109.          call   SND_CMD
    110.          movf   POSTINC1,0
    111.          movf   INDF1,0
    112.          movwf  PORTD
    113.          call   SND_DTA
    114.          return
    115.  
    116.  
     
  3. RG23

    Thread Starter Active Member

    Dec 6, 2010
    301
    2
    Using Pickit2 debugger I found that when I press switch1

    the data in locations 100, 101, 102, 103 are all 0xFF

    when I press switch2 , the data in those locations are not 0xFF

    I wonder why is it so as I haven;t changed anything related to the data in those locations.

    If anyone has an idea please let me know

    Thanks
     
  4. JohnInTX

    Moderator

    Jun 26, 2012
    2,342
    1,024
    Code ( (Unknown Language)):
    1. movlw 0x01
    2. movwf PORTD
    3. call SND_CMD
    4. movf POSTDEC1,0
    5. movf INDF1,0 ; shouldn't this be [I][B]movwf[/B][/I]?
    6. movwf PORTD
    7. call SND_DTA
    Other than that since there are no comments in the routines, its difficult to know what you are trying to do. Further, you should not use movf POSTDEC1,0. Instead use movf POSTDEC1,W or ,F as required. It makes the code easier to read for someone is looking at it for the first time.

    EDIT: since you are using PK2, step through the code and look at the RAM in a watch window.
     
  5. RG23

    Thread Starter Active Member

    Dec 6, 2010
    301
    2
    The first subroutine works completely fine

    beginning with LFSR 1, h'100'

    I store oxFF in four consecutive data memory locations and display them on the four pages of dispay in a single column

    In the next subroutine I just access those register locations again and try to display them in the adjacent column

    One surprising result I noticed while debugging was the contents of those registers are no longer 0xFF

    Even if in the second subroutine there was any issue in the addressing still those contents in 100, 101, 102, 103 shouldn't be affected.

    What do you think?
     
  6. JohnInTX

    Moderator

    Jun 26, 2012
    2,342
    1,024
    Well, I just pulled one as an example, I didn't look all the way through the code for the reasons indicated. The same construct appears in several places.

    I don't know why you are moving from *FSR1 to W, decrementing FSR1 then moving *FSR1 to W again. If that's what you intended, we can take a longer look.

    EDIT: OK, is that construct to increment FSR1 after INDF? If so, you can shorten it to just POSTINC1, yes? For example, to set the 4 xFF:

    Code ( (Unknown Language)):
    1. lfsr 1, 0x100 ;Fill 4 bytes beginning at 0x100 with FF
    2. setf POSTINC1
    3. setf POSTINC1
    4. setf POSTINC1
    5. setf POSTINC1 ; FSR1 -> byte after the last FF
    I also notice you are not resetting FSR1 to start in the 2ed routine. Is that OK?

    l
     
    Last edited: May 9, 2013
  7. RG23

    Thread Starter Active Member

    Dec 6, 2010
    301
    2
    I figured out the problem

    Both subroutines worked ok.

    There was an additional subroutine that was writing different data to those register locations

    I am now running into another problem

    I have data stored in LFSR 1,h'100' consecutive data memory locations

    I am trying to store the same data in another memory location at the same time using LFSR 0,h'800'

    But every 2nd 8 bit data out of four is getting distorted.

    Has anyone tried the indirect addressing involving two FSRs at the same time and transferring the data between them and encountered a similar problem?
     
  8. JohnInTX

    Moderator

    Jun 26, 2012
    2,342
    1,024
    Yes, yes and no in that order. Based on your earlier code, you are not taking full advantage of the FSR capabilities (doing a dummy move to bump the pointer then using indirect - it can be done in one operation).

    Use something like this:
    Code ( (Unknown Language)):
    1.  
    2.  Count equ .10 ;move 10 bytes
    3.  SourceData equ 0x100 ; location of data to move
    4.  DestData equ 0x200 ; where to move it
    5.  
    6.  lfsr 1,SourceData ; set pointers
    7.  lfsr 2,DestData
    8.  movlw Count ; use W as a counter
    9. loop:
    10.  movff POSTINC1,POSTINC2 ; move *FSR1 -> *FSR2, bump both
    11.  decfsz WREG,F ; count
    12.  bra loop
    13.  return
    BTW: To avoid inadvertent writes to INDF clobbering RAM, good programming practice would suggest that you 'park' your FSRs after using them i.e. point them to some unused RAM. Better programming practice would have you put some known bytes at that location, a signature. Inspecting these for a changed signature would indicate you are misusing the FSRs (writing indirect when/where you don't expect) but at least you clobber unused RAM.
     
    Last edited: May 11, 2013
Loading...