Taxi Meter Help MPASM

Discussion in 'Homework Help' started by Matty Brindle, Apr 15, 2018.

  1. Matty Brindle

    Thread Starter New Member

    Dec 7, 2017
    1
    0
    hello there,

    i was hoping you could help me with my project on a taxi meter where:
    • The motor start/stop switch increases the mileage
    • Detects the temperature of the sensor
    • When the button is pressed it displays the fare/distance respectively.( where the fare starts at £5)
    i have included pictures and also the code where i have managed to display the distance and temperature but not increment the actions that are being made.

    the only problem im having is that im not sure how to make the motor increment a counter just after the distance: and same with the temperature, as i have done both these commands seperately on a 7 segment i just cant get my head round how to get it onto the LCD display...
    thank you
    Code (Text):
    1. ;http://digitaldiy.io/articles/mcu-programming/assembly/55-assembly-example/114-mpasm-tutorial-liquid-crystal-display-lcd#.WKDWRDvyiUk
    2. ;====================================================================
    3. ; Main.asm file generated by New Project wizard
    4. ;
    5. ; Created:   Sun Feb 12 2017
    6. ; Processor: PIC16F877
    7. ; Compiler:  MPASM (Proteus)
    8. ;====================================================================
    9.  
    10.  
    11. #include p16f877a.inc             ; Include register definition file
    12.  
    13. __config 0x3D18 ;sets the configuration settings (osc type etc.)
    14. ;====================================================================
    15. ; VARIABLES
    16. ;====================================================================
    17. LCD_PORT Equ PORTB
    18. LCD_TRIS Equ TRISB
    19. LCD_RS Equ 0x02 ;LCD handshake lines
    20. LCD_E Equ 0x03
    21.  
    22. CBLOCK 0x20
    23.   count ; Counter used when switch pressed has stopped
    24.   count1 ; 160us Counter variable
    25.   counta ; variables for delay timers
    26.   countb ; variables for delay timers
    27.   LCDTemp ; 4 bit for LCD
    28. ENDC ;
    29.  
    30. ;====================================================================
    31. ; RESET and INTERRUPT VECTORS
    32. ;====================================================================
    33.  
    34. ; Reset Vector
    35. RST   code  0x00
    36.   goto  Start
    37.  
    38. Text
    39. addwf PCL, f
    40. retlw 'D'
    41. retlw 'i'
    42. retlw 's'
    43. retlw 't'
    44. retlw 'a'
    45. retlw 'n'
    46. retlw 'c'
    47. retlw 'e'
    48. retlw ':'
    49. retlw 'M'  
    50. retlw 'i'
    51. retlw 'l'
    52. retlw 'e'
    53. retlw 's'
    54. retlw 0x00
    55.  
    56. Text2
    57. addwf PCL, f
    58. retlw 'T'
    59. retlw 'e'
    60. retlw 'm'
    61. retlw 'p'
    62. retlw 'e'
    63. retlw 'r'
    64. retlw 'a'
    65. retlw 't'
    66. retlw 'u'
    67. retlw 'r'
    68. retlw 'e'
    69. retlw ':'
    70. retlw b'00110000'   ;0.
    71. retlw 0x00    
    72.  
    73. DispNumNoDot
    74. addwf PCL, f
    75. retlw b'00110000'   ;0.
    76. retlw b'00110001'   ;1.
    77. retlw b'00110010'   ;2.
    78. retlw b'00110011'   ;3.
    79. retlw b'00110100'   ;4.
    80. retlw b'00110101'   ;5.
    81. retlw b'00110110'   ;6.
    82. retlw b'00110111'   ;7.
    83. retlw b'00111000'   ;8.
    84. retlw b'00111001'   ;9.    
    85. ;====================================================================
    86. ; CODE SEGMENT
    87. ;====================================================================
    88.  
    89. PGM   code
    90.       GOTO     Start
    91. Start
    92.  
    93. bsf STATUS, RP0 ; select bank 1
    94. clrf PORTA ; Initialize PORTA by setting output data latches
    95. movlw b'00000000' ; PortA Outputs
    96. movwf TRISA ; All portA pins are inputs
    97. movlw b'00000000' ; PortB Outputs
    98. movwf TRISB ; Change PortB I/O
    99. bcf STATUS, RP0 ; select bank 0
    100.  
    101. call LCDInit ; Initialize the LCD Display
    102.  
    103. ; Main program...
    104.  
    105. clrf count
    106. Message
    107.  
    108. movf count, w ; put counter value in W
    109. call Text ; get a character from the text table
    110. xorlw 0x00 ; is it a zero?
    111. btfsc STATUS, Z
    112. goto NextMessage ; display next message if finished
    113. call LCD_Char
    114. incf count, f
    115. goto Message
    116.  
    117. NextMessage
    118. call LCD_L2 ;move to 2nd row, first column
    119. clrf count ;set counter register to zero
    120.  
    121. Message2
    122. movf count, w ;put counter value in W
    123. call Text2 ;get a character from the text table
    124. xorlw 0x00 ;is it a zero?
    125. btfsc STATUS, Z
    126. goto EndMessage
    127. call LCD_Char
    128. incf count, f
    129. goto Message2
    130.  
    131. EndMessage
    132.  
    133. ; Infinate loop
    134. Stop
    135. goto Stop ;endless loop
    136.  
    137. ; LCD routines and subs
    138. LCDInit ; 4 Bit Initialization...
    139. bcf LCD_PORT, LCD_RS ;
    140. movlw 0x030 ; Send the Reset Instruction
    141. movwf LCD_PORT ;
    142. call Pulse_e ; Pulse LCD_E
    143. call Del05 ; Delay 5ms
    144.  
    145. movlw 0x020 ; Send the Data Length Specification
    146. movwf LCD_PORT ;
    147. call Pulse_e ; Pulse LCD_E
    148. call D160us ; Delay of 160us
    149. movlw 0x028 ; Set Interface Length
    150. call LCDIns ;
    151. movlw 0x010 ; Turn Off Display
    152. call LCDIns ;
    153. movlw 0x001 ; Clear Display RAM
    154. call LCDIns ;
    155. movlw 0x006 ; Set Cursor Movement
    156. call LCDIns ;
    157. movlw 0x00C ; Turn on Display/Cursor
    158. call LCDIns ;
    159. call LCD_Clr ; Clear the LCD
    160. return ;
    161.  
    162. LCDIns ; Send the Instruction to the LCD
    163. movwf LCDTemp ; Save the Value
    164. andlw 0xF0 ; Most Significant Nibble first
    165. movwf LCD_PORT ;
    166. bcf LCD_PORT, LCD_RS ;
    167. call Pulse_e ;
    168. swapf LCDTemp, w ; Least Significant Nibble Second
    169. andlw 0xF0 ;
    170. movwf LCD_PORT ;
    171. bcf LCD_PORT, LCD_RS ;
    172. call Pulse_e ;
    173. call Del05
    174.  
    175. return ;
    176.  
    177. ;LCD_CharD
    178.  
    179. LCD_Char ; Send the Character to the LCD
    180. movwf LCDTemp ; Save the Value
    181. andlw 0xF0 ; Most Significant Nibble first
    182. movwf LCD_PORT ;
    183. bsf LCD_PORT, LCD_RS ;
    184. call Pulse_e ;
    185. swapf LCDTemp, w ; Least Significant Nibble Second
    186. andlw 0xF0 ;
    187. movwf LCD_PORT ;
    188. bsf LCD_PORT, LCD_RS ;
    189. call Pulse_e ;
    190. call Del05 ;
    191. nop ;
    192. return ;
    193.  
    194.  
    195.  
    196. LCD_L2: movlw 0xc0 ; move to 2nd row, first column
    197. call LCDIns ;
    198. return
    199.  
    200.  
    201. LCD_Clr movlw 0x01 ; Clear display
    202. call LCDIns ;
    203. return
    204.  
    205.  
    206. Pulse_e ;
    207. bsf LCD_PORT, LCD_E ; LCD Enable pulse to write data from PORTB
    208. bcf LCD_PORT, LCD_E ;
    209. nop ;
    210. return ;
    211.  
    212.  
    213. ; Delay routines...
    214. D160us
    215. clrf count1 ;
    216. bsf count1, 5 ; Delay 160 usecs
    217. bsf count1, 3 ;
    218. decfsz count1, f ;
    219. goto $ - 1 ;
    220. return ;
    221.  
    222.  
    223. Del05 movlw 0x05 ; delay 5.000 ms (1 MHz clock)
    224. goto d0 ;
    225. d0 movwf count1 ;
    226. d1 movlw 0xC8 ; x200  delay 1mS
    227. movwf counta ;
    228. movlw 0x05 ;   x5
    229. movwf countb ;
    230. Del_0 decfsz counta,f ;
    231. goto $+2 ;
    232. decfsz countb,f ;
    233. goto Del_0 ;
    234. decfsz count1,f ;
    235. goto d1 ;
    236. return
    237.  
    238.  
    239. ;====================================================================
    240.   END
     
  2. jpanhalt

    Expert

    Jan 18, 2008
    6,290
    1,173
    I don't see where you try to print data after your message. Take this part of the code:
    Code (ASM):
    1.  
    2. Text
    3.      addwf PCL, f
    4.      retlw 'D'
    5.      retlw 'i'
    6.      retlw 's'
    7.      retlw 't'
    8.      retlw 'a'
    9.      retlw 'n'
    10.      retlw 'c'
    11.      retlw 'e'
    12.      retlw ':'
    13.      retlw 'M'
    14.      retlw 'i'
    15.      retlw 'l'
    16.      retlw 'e'
    17.      retlw 's'
    18.      retlw 0x00
    19.      clrf  count
    20. Message
    21.      movf count, w            ; put counter value in W
    22.      call Text                ; get a character from the text table
    23.      xorlw 0x00               ; is it a zero?
    24.      btfsc STATUS, Z
    25.      goto NextMessage         ; display next message if finished
    26.      call LCD_Char
    27.      incf count, f
    28.      goto Message
    29.  
    That simply prints your messages in order. You need to return after printing "Distance" to insert your data, then add "Miles." I suspect you see that using 'retlw' prevents you from inserting a variable. When I need to add a variable following a printed label, I do not do it the way you are trying to do it, but as this is homework, here is something to try using your code's structure:
    Code (ASM):
    1.  
    2. Start  
    3.      movlw     '1'       ;example odometer data
    4.      movwf     Tens
    5.      movlw     '6'       ;example odometer data
    6.      movwf     Ones
    7.      goto       Message
    8. Text
    9.      addwf PCL, f
    10.      retlw 'D'
    11.      retlw 'i'
    12.      retlw 's'
    13.      retlw 't'
    14.      retlw 'a'
    15.      retlw 'n'
    16.      retlw 'c'
    17.      retlw 'e'
    18.      retlw ':'
    19.      retlw 0xFF
    20.      retlw 'M'
    21.      retlw 'i'
    22.      retlw 'l'
    23.      retlw 'e'
    24.      retlw 's'
    25.      retlw 0x00
    26. ;====================================================================
    27. ; CODE SEGMENT
    28. ;====================================================================
    29.      clrf      count  
    30. Message
    31.      movf      count, w       ; put counter value in W
    32.      call      Text           ; get a character from the text table
    33.      xorlw     0xFF           ; is it a zero?
    34.      btfsc     STATUS,2
    35.      call      PutMiles
    36.      xorlw     0x00
    37.      btfsc     STATUS,2
    38.      goto      NextMessage
    39.      call      LCD_Char
    40.      incf      count,f
    41.      goto      Message
    42. PutMiles
    43.      movf      Tens,w
    44.      call      LCD_Char
    45.      movf      Ones,w
    46.      call      LCD_Char
    47.      movlw     0x20           ;ascii "space" between data and unit
    48.      return
    49. LCD_Char
    50. ;     <insert your code here>
    51. NextMessage
    52.      end
    53.  
    That code has not been tested. Obviously, you need to get the odometer mileage, convert to BCD, and then convert the decimal digits to ascii.

    John

    EDIT: On thinking a little further about your question, let me emphasize that the approach I showed was based entirely on trying to fit a variable into your already fixed print routine, or what appeared fixed to me. Here are some suggestions for change based on what I do.
    1) Remember that LCD's do not need to be refreshed. So, if you print something like "Distance:" followed by some value, followed by a unit, "Miles," the only thing you need to print with each change is the value.
    2) You can get to the value by coordinates, e.g, line 0, 10 will get you one space after the colon for Distance: .
    3) If the "value" is always the same format, say 2 digits, re-writing at the same location simply writes over what is there.
    4) Based on the above, I suggest you break your write routines into smaller chunks and/or write spaces (0x20) there the values go. Then as you determine each value, write it to a specific location.
    5) Your compiler may support some shorthand. While there is nothing wrong with what you wrote using retlw's, I usually write something like dt "Distance: " (I use MPLab 8.92.) That is easier to read and takes less space on paper (program memory is the same). If disassembled, it will show exactly as yours, i.e., a series of retlw instructions for each character. Be sure to use double quote (") instead of single quote (') when you want more than one character.
    6) Make one print routine and use that. I call mine "Put232" ; although, it has very little to do with that interface today. Each character is moved into W register, then that routine is called. Exactly the same routine is used for placing the cursor in the correct spot as is used for printing a character.
    7) I use 1/4" squared graph paper to plot out my print routines, That way, I can be sure what will overwrite and what needs to be cleared.
     
    Last edited: Apr 16, 2018
Loading...