LCD Using pic16f628a

Discussion in 'Programmer's Corner' started by Knightmare.BH, May 30, 2014.

  1. Knightmare.BH

    Thread Starter New Member

    May 30, 2014
    7
    0
    This program to count the people in a lab ( max 9 people ). it has 2 sensors one for increment and the other for decrement.

    Code ( (Unknown Language)):
    1.  
    2. include<p16f628a.inc>
    3.     CBLOCK  H'20'
    4.     COUNT1 
    5.     COUNT2 
    6.     COUNT3
    7.     LCD_POINTER
    8.     LAB_COUNT
    9.     endc   
    10. #define LCD_RS  PORTA,0
    11. #define LCD_RW  PORTA,1
    12. #define LCD_E   PORTA,2
    13. #define IN_ PORTA,3
    14. #define OUT_    PORTA,4
    15.     clrf    PORTA
    16.     clrf    PORTB
    17.     clrf    COUNT1
    18.     clrf    LAB_COUNT
    19.    
    20.     movlw   H'07'
    21.     movwf   CMCON
    22.     bsf STATUS,RP0 
    23.     movlw   b'11111000'
    24.     movwf   TRISA
    25.     movlw   b'00000000'
    26.     movwf   TRISB
    27.     bcf STATUS,RP0
    28.     call    Delay_L
    29.    
    30.     movlw   b'00001100'
    31.     call    Send_CMD   
    32.     movlw   b'00111000'
    33.     call    Send_CMD   
    34.  
    35.     call    Text1
    36.     call    Disp_C
    37.  
    38. Start
    39.     btfsc   IN_
    40.     goto    INC_LAB
    41.     btfsc   OUT_
    42.     goto    DEC_LAB
    43.     goto    Start
    44.    
    45. INC_LAB
    46.     incf    LAB_COUNT,f
    47.     call    Disp_C
    48.     goto    Start
    49. DEC_LAB
    50.     decf    LAB_COUNT,f
    51.     call    Disp_C
    52.     goto    Start
    53.  
    54.  
    55.  
    56. Disp_C  movlw   b'10000100'
    57.     call    Send_CMD
    58.     call    Delay_L
    59.     movf    LAB_COUNT,w
    60.     iorlw   H'30'
    61.     call    Send_CHR
    62.     return
    63.  
    64.  
    65.  
    66. Text1
    67.     clrf    LCD_POINTER
    68. Text1L  movf    LCD_POINTER,w
    69.     call    TextM1
    70.     call    Send_CHR
    71.     incf    LCD_POINTER,w
    72.     xorlw   d'4'
    73.     btfsc   STATUS,Z
    74.     return
    75.     incf    LCD_POINTER,f
    76.     goto    Text1L 
    77.  
    78.  
    79.  
    80.  
    81.  
    82.  
    83.  
    84. Puls_E
    85.     bsf LCD_E
    86.     nop
    87.     bcf LCD_E
    88.     return 
    89. Send_CMD
    90.     bcf LCD_RS
    91.     bcf LCD_RW
    92.     movwf   PORTB
    93.     call    Puls_E
    94.     call    Delay_S
    95.     return
    96. Send_CHR
    97.     bsf LCD_RS
    98.     bcf LCD_RW
    99.     movwf   PORTB
    100.     call    Puls_E
    101.     call    Delay_S
    102.     return
    103.  
    104. Delay_S
    105. Loop1   deCfsz  COUNT1,f
    106.     goto    Loop1
    107.     return
    108.  
    109. Delay_L
    110. Loop2   call    Delay_S
    111.     deCfsz  COUNT2,f
    112.     goto    Loop2
    113.     return
    114.  
    115.  
    116. TextM1
    117.     addwf   PCL,f
    118.     dt  "LAB:",0
    119.  
    120.  
    121.     end
    122.  

    The problem now is when it reach 9 and the increment sensor work it still count and when it reach 0 and the decrement sensor work it count also showing symbols.

    I want to make it when it reach 9 and the sensor work it ignore it and still show 9
    and the same with the 0
     
    Last edited by a moderator: May 30, 2014
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Simple: when you increment inside INC_LAB test the people count: if 9 don't increment it. If greater than 9 you may want to set it to 9.

    Same with decrementing: if there are zero people in the room don't decrement the count.
     
  3. atferrari

    AAC Fanatic!

    Jan 6, 2004
    2,645
    759
    Hola Knight

    It is easier, by far, to discuss a flow diagram. It helps you to think in a more logic way.

    I personally make sure my flow diagrama satisfies me and THEN I write code.
     
  4. MrChips

    Moderator

    Oct 2, 2009
    12,421
    3,355
    +1

    Design comes first. Writing code comes after design.
     
  5. JohnInTX

    Moderator

    Jun 26, 2012
    2,340
    1,022
    +2!
    And..
    Code ( (Unknown Language)):
    1. TextM1
    2. addwf PCL,f
    3. dt "LAB:",0
    4.  
    When you use a table lookup like this, you also must ensure that:

    1) The value of W bounds-checked to make sure that the lookup will not jump off the end of the table

    2) The table does not span 256 word program ROM pages unless you compute the jump as a 16 bit address.
    Failure will have your program going out into the weeds. #2 is especially tricky since it can work reliably until you add some code above the table that pushes it down enough to span a bank.

    I usually dedicate a page of ROM to tables with an ORG to a page boundary then put the tables at the beginning of the page.

    EDIT: The code that sends the string could be better. Strings end with 00h as they should but the code tests the index for a fixed number of characters. This is not a good way to do it if you want messages of different lengths. A better way is to fetch the char, test for 00h as shown, and return on 00h.

    I added a way to send more than one message as well. Use W as the index of the start of the message. The assembler will calculate the index automatically for you using $-MsgStart where $ is the ROM address of the start of a particular message and MsgStart is the ROM address of the start of the whole message table. In the example, MsgStart is at 701h and Msg2 is at 706h. 706h-701h = 5 which is the value of W that will fetch the first character of Msg2. Nice. The indexes are named using the EQU directive. To use, just movlw <name of message>. This will help (but not cure) the problem of bounds-checking the index as well. Note that the messages can be arbitrary lengths as long as they are terminated by 00h.

    Finally, I put the message table on a ROM page boundary to help (but also not completely cure) the crossing a ROM page problem.

    I didn't add bounds checking for the index in W because enough's enough for now. How would you add it?

    Have fun!


    Code ( (Unknown Language)):
    1. ;*************** SEND STRING OF ARBITRARY LENGTH  *********************
    2. ; Send string from MsgStart[W] until 00h
    3.  
    4. Text_W:
    5.     movwf    LCD_POINTER    ; save W as LCD_POINTER
    6.  
    7. Text1L:
    8.     movf    LCD_POINTER,W    ; get index
    9.     call    TextM1        ; get character to W
    10.    
    11.     iorlw    0        ; set flags on W to look for end of string
    12.     skpnz            ; built in macro for btfsc STATUS,Z
    13.     return            ; 0 found, done!
    14.  
    15.     call    Send_CHR    ; else, send character
    16.     incf    LCD_POINTER,F    ; bump index
    17.     goto    Text1L        ; next
    18.  
    19.  
    20.     ;**************** EXAMPLE USE  ********************
    21. Send1:
    22.     movlw    Msg1
    23.     call    Text_W
    24.     return
    25.  
    26. Send2:    movlw    Msg2
    27.     call    Text_W
    28.     return
    29.  
    30.     ORG    700h        ; tables on page boundary (last page of ROM)
    31. ;************* MESSAGES IN LOOKUP TABLE  ****************
    32. TextM1:    
    33.     addwf    PCL,W ; still need to bounds-check W
    34.  
    35. MsgStart:              
    36. Msg1 equ $-MsgStart ; Compute index for Msg1    
    37.     dt    "LAB:",0
    38.  
    39. Msg2: equ $-MsgStart ; Compute index for Msg2
    40.     dt    "MSG2 is Bigger",0
     
    Last edited: May 30, 2014
    absf likes this.
  6. Knightmare.BH

    Thread Starter New Member

    May 30, 2014
    7
    0
    yeah i got ur point
    but how can i test what's inside the register ?? it's not like a port i can test it if it on or off.

    this is my first time with LCD so am newbie in it
     
  7. JohnInTX

    Moderator

    Jun 26, 2012
    2,340
    1,022
    To do tests and comparisons on a 16F, its necessary to do some arithmetic or logical operations on the value then testing the Z and/or C flags in STATUS.

    Testing for zero (or non-zero) is easy:
    Code ( (Unknown Language)):
    1. iorlw 0 ; will set the Z flag in STATUS if W was 0
    2. iorwf aRAMbyte,F ; OR's a byte in RAM with itself and sets Z if it was zero.
    3.   ; In both cases W/RAM is unchanged.
    4.  
    Comparing two values requires subtraction:
    Code ( (Unknown Language)):
    1. sublw 2 ; does 2-W comparing W with the literal value 2.
    2.                         ;Z is set if they are equal, C is set if 2 > W etc .
    3.  
    4. movlw value
    5. subwf value,W ; compares a RAM byte with 'value' in W.
    6.                        ;Flags are set as before.
    Any instruction which affects the flags may be useful. For example:
    Code ( (Unknown Language)):
    1. incf aRAMbyte,W ; will set Z if the byte in RAM was FFh (affects Z)
    2. incfsz aRAMbyte,W ;will skip if the byte in RAM was FFh
    3.                               ;(without affecting flags)
    4.  
    decf(sz) ; likewise can be used to test for 01h etc. In the cases that affect the STATUS flags, the next instruction is a test and skip on the flag(s) that indicate the relation between the values.

    All of the STATUS flag settings are described in the descriptions for each instruction in the manual. These should be committed to memory.

    Have fun!
     
    Last edited: May 30, 2014
  8. Knightmare.BH

    Thread Starter New Member

    May 30, 2014
    7
    0
    i didn't understand anything... am just a beginner

    can u just fix the program then i will ask you what did u do after seeing it
    that way will be easier
     
  9. MaxHeadRoom

    Expert

    Jul 18, 2013
    10,507
    2,367
    Then maybe you should take a few tutorials that are out there,
    http://www.winpicprog.co.uk/pic_tutorial.htm covers what you are doing, there are other sites such as Gooligum etc.
    For tables and the like in assy, migrating to 18F they are much easier.
    Max.
     
    JohnInTX likes this.
  10. JohnInTX

    Moderator

    Jun 26, 2012
    2,340
    1,022
    If you understand what you originally posted:
    Code ( (Unknown Language)):
    1.        
    2. incf    LCD_POINTER,w
    3. [B]xorlw    d'4' [COLOR=Red]; do a logical op on W and check Z[/COLOR]    
    4. btfsc    STATUS,Z[/B]    
    5. return
    ..then you should be able to understand what I posted - do the logical/arithmetic operation and check the flags in STATUS.

    I can't go much farther because
    1) I don't know what you are trying to compare
    2) this is basic stuff - you have to understand it before you can do anything.

    Build the code. Fire up MPSIM (MPLAB's simulator) and step through the code. Open a WATCH window, type in the names of some variables and watch what they do when the various instructions are executed. Try a few of the examples and it will all become clear.

    Did you write the code or is it from a book/site?
     
  11. Knightmare.BH

    Thread Starter New Member

    May 30, 2014
    7
    0

    i didn't write it..
    the teacher wrote it and he said to make it cant count more than 9
    and cant count less than zero..
    like when it reach 9 and the sensor work it must stay on 9 only if the 2nd sensor work it will count down to 8
     
  12. JohnInTX

    Moderator

    Jun 26, 2012
    2,340
    1,022
    OK. Well, ErnieM in #2 said what has to be done and in #7 the first code snippet shows 2 ways of testing for zero and the second one shows 2 ways of testing / comparing to an arbitrary value (9 in your case).

    So, revise the code, get it to assemble with no errors and run it up on MPSIM. Any problems will become obvious. If you can't resolve the questions, post your revised code and we can look at it from there.
     
  13. Knightmare.BH

    Thread Starter New Member

    May 30, 2014
    7
    0

    i already tried it it didn't do anything:

    DEC_LAB
    iorlw 0
    iorwf LAB_COUNT,f
    decf LAB_COUNT,f
    call Disp_C
    goto Start
     
  14. JohnInTX

    Moderator

    Jun 26, 2012
    2,340
    1,022
    I showed various ways to test for 0 depending on the program. You can't just copy all of them and hope for the best. I picked the middle one.

    Code ( (Unknown Language)):
    1. DEC_LAB:
    2.  [COLOR=DarkOrange]iorwf LAB_COUNT,F [/COLOR] ; set STATUS,Z if LAB_COUNT == 0
    3.  [B]btfss STATUS,Z[/B] ; [B][I][COLOR=Red][COLOR=Black]TEST RESULT OF iorwf,[/COLOR] [COLOR=Black]SKIP[/COLOR] [COLOR=SeaGreen]NEXT INSTRUCTION [/COLOR][COLOR=Black]IF Z IS SET[/COLOR][/COLOR][/I][/B]
    4. [COLOR=SeaGreen][B] decf LAB_COUNT,F[/B][/COLOR][I][COLOR=SeaGreen] ; if [/COLOR][/I][COLOR=SeaGreen]NZ, this is not skipped so LAB_COUNT is decremented, result is left in LAB_COUNT (not W)[/COLOR]
    5.   ; the updated value of LAB_COUNT is in RAM, move to W if necessary
    6.   call Disp_C ; update display
    7.   goto Start
    How did you test your code?
     
  15. MaxHeadRoom

    Expert

    Jul 18, 2013
    10,507
    2,367
    Before you converse in any language you have to know how to speak it.
    It seems to me all you are doing is getting someone to translate for you and come up with the answer.
    No way to learn!
    Max.
     
    JohnInTX likes this.
  16. Knightmare.BH

    Thread Starter New Member

    May 30, 2014
    7
    0
    what is the STATUS,Z ??
    never used it before

    and i test my code using isis
     
  17. JohnInTX

    Moderator

    Jun 26, 2012
    2,340
    1,022
    Seriously?

    Read sections 3.0, 4.2.2.1 and 15.0 in the datasheet. Then go back and read sections 1 through 5 and 14. Then read some of the tutorial info in Max's #9. There are lots of application notes on microchip.com that have code examples - like this one. Pick a few and read the code until you understand what's going on.

    When you have it in hand, write the 'increment to 9' code, test it on ISIS then post it with problems. Until then, there isn't much more I can do for you.

    Its probably time to visit with your teacher on this as well.

    Good luck!
     
  18. Knightmare.BH

    Thread Starter New Member

    May 30, 2014
    7
    0
    i just need the code for tomorrow but u wont write it..
    so never mind
     
  19. JohnInTX

    Moderator

    Jun 26, 2012
    2,340
    1,022
    That is correct.
     
  20. MaxHeadRoom

    Expert

    Jul 18, 2013
    10,507
    2,367

    ...Your just a spoil sport! :confused:


    Max.:)
     
Loading...