Taxi Meter Help MPASM

Thread Starter

Matty Brindle

Joined Dec 7, 2017
1
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:
;http://digitaldiy.io/articles/mcu-programming/assembly/55-assembly-example/114-mpasm-tutorial-liquid-crystal-display-lcd#.WKDWRDvyiUk
;====================================================================
; Main.asm file generated by New Project wizard
;
; Created:   Sun Feb 12 2017
; Processor: PIC16F877
; Compiler:  MPASM (Proteus)
;====================================================================


#include p16f877a.inc             ; Include register definition file

__config 0x3D18 ;sets the configuration settings (osc type etc.)
;====================================================================
; VARIABLES
;====================================================================
LCD_PORT Equ PORTB
LCD_TRIS Equ TRISB
LCD_RS Equ 0x02 ;LCD handshake lines
LCD_E Equ 0x03

CBLOCK 0x20
  count ; Counter used when switch pressed has stopped
  count1 ; 160us Counter variable
  counta ; variables for delay timers
  countb ; variables for delay timers
  LCDTemp ; 4 bit for LCD
ENDC ;

;====================================================================
; RESET and INTERRUPT VECTORS
;====================================================================

; Reset Vector
RST   code  0x00
  goto  Start

Text
addwf PCL, f
retlw 'D'
retlw 'i'
retlw 's'
retlw 't'
retlw 'a'
retlw 'n'
retlw 'c'
retlw 'e'
retlw ':'
retlw 'M'  
retlw 'i'
retlw 'l'
retlw 'e'
retlw 's'
retlw 0x00

Text2
addwf PCL, f
retlw 'T'
retlw 'e'
retlw 'm'
retlw 'p'
retlw 'e'
retlw 'r'
retlw 'a'
retlw 't'
retlw 'u'
retlw 'r'
retlw 'e'
retlw ':'
retlw b'00110000'   ;0.
retlw 0x00     

DispNumNoDot
addwf PCL, f
retlw b'00110000'   ;0.
retlw b'00110001'   ;1.
retlw b'00110010'   ;2.
retlw b'00110011'   ;3.
retlw b'00110100'   ;4.
retlw b'00110101'   ;5.
retlw b'00110110'   ;6.
retlw b'00110111'   ;7.
retlw b'00111000'   ;8.
retlw b'00111001'   ;9.    
;====================================================================
; CODE SEGMENT
;====================================================================

PGM   code
      GOTO     Start
Start

bsf STATUS, RP0 ; select bank 1
clrf PORTA ; Initialize PORTA by setting output data latches
movlw b'00000000' ; PortA Outputs
movwf TRISA ; All portA pins are inputs
movlw b'00000000' ; PortB Outputs
movwf TRISB ; Change PortB I/O
bcf STATUS, RP0 ; select bank 0

call LCDInit ; Initialize the LCD Display

; Main program...

clrf count
Message

movf count, w ; put counter value in W
call Text ; get a character from the text table
xorlw 0x00 ; is it a zero?
btfsc STATUS, Z
goto NextMessage ; display next message if finished
call LCD_Char
incf count, f
goto Message

NextMessage
call LCD_L2 ;move to 2nd row, first column
clrf count ;set counter register to zero

Message2
movf count, w ;put counter value in W
call Text2 ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto EndMessage
call LCD_Char
incf count, f
goto Message2

EndMessage

; Infinate loop
Stop
goto Stop ;endless loop

; LCD routines and subs
LCDInit ; 4 Bit Initialization...
bcf LCD_PORT, LCD_RS ;
movlw 0x030 ; Send the Reset Instruction
movwf LCD_PORT ;
call Pulse_e ; Pulse LCD_E
call Del05 ; Delay 5ms

movlw 0x020 ; Send the Data Length Specification
movwf LCD_PORT ;
call Pulse_e ; Pulse LCD_E
call D160us ; Delay of 160us
movlw 0x028 ; Set Interface Length
call LCDIns ;
movlw 0x010 ; Turn Off Display
call LCDIns ;
movlw 0x001 ; Clear Display RAM
call LCDIns ;
movlw 0x006 ; Set Cursor Movement
call LCDIns ;
movlw 0x00C ; Turn on Display/Cursor
call LCDIns ;
call LCD_Clr ; Clear the LCD
return ;

LCDIns ; Send the Instruction to the LCD
movwf LCDTemp ; Save the Value
andlw 0xF0 ; Most Significant Nibble first
movwf LCD_PORT ;
bcf LCD_PORT, LCD_RS ;
call Pulse_e ;
swapf LCDTemp, w ; Least Significant Nibble Second
andlw 0xF0 ;
movwf LCD_PORT ;
bcf LCD_PORT, LCD_RS ;
call Pulse_e ;
call Del05

return ;

;LCD_CharD

LCD_Char ; Send the Character to the LCD
movwf LCDTemp ; Save the Value
andlw 0xF0 ; Most Significant Nibble first
movwf LCD_PORT ;
bsf LCD_PORT, LCD_RS ;
call Pulse_e ;
swapf LCDTemp, w ; Least Significant Nibble Second
andlw 0xF0 ;
movwf LCD_PORT ;
bsf LCD_PORT, LCD_RS ;
call Pulse_e ;
call Del05 ;
nop ;
return ;



LCD_L2: movlw 0xc0 ; move to 2nd row, first column
call LCDIns ;
return


LCD_Clr movlw 0x01 ; Clear display
call LCDIns ;
return


Pulse_e ;
bsf LCD_PORT, LCD_E ; LCD Enable pulse to write data from PORTB
bcf LCD_PORT, LCD_E ;
nop ;
return ;


; Delay routines...
D160us
clrf count1 ;
bsf count1, 5 ; Delay 160 usecs
bsf count1, 3 ;
decfsz count1, f ;
goto $ - 1 ;
return ;


Del05 movlw 0x05 ; delay 5.000 ms (1 MHz clock)
goto d0 ;
d0 movwf count1 ;
d1 movlw 0xC8 ; x200  delay 1mS
movwf counta ;
movlw 0x05 ;   x5
movwf countb ;
Del_0 decfsz counta,f ;
goto $+2 ;
decfsz countb,f ;
goto Del_0 ;
decfsz count1,f ;
goto d1 ;
return


;====================================================================
  END
 

Attachments

jpanhalt

Joined Jan 18, 2008
11,088
I don't see where you try to print data after your message. Take this part of the code:
Code:
Text
     addwf PCL, f
     retlw 'D'
     retlw 'i'
     retlw 's'
     retlw 't'
     retlw 'a'
     retlw 'n'
     retlw 'c'
     retlw 'e'
     retlw ':'
     retlw 'M'
     retlw 'i'
     retlw 'l'
     retlw 'e'
     retlw 's'
     retlw 0x00
     clrf  count
Message 
     movf count, w            ; put counter value in W
     call Text                ; get a character from the text table
     xorlw 0x00               ; is it a zero?
     btfsc STATUS, Z
     goto NextMessage         ; display next message if finished
     call LCD_Char
     incf count, f
     goto Message
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:
Start  
     movlw     '1'       ;example odometer data
     movwf     Tens
     movlw     '6'       ;example odometer data
     movwf     Ones
     goto       Message
Text
     addwf PCL, f
     retlw 'D'
     retlw 'i'
     retlw 's'
     retlw 't'
     retlw 'a'
     retlw 'n'
     retlw 'c'
     retlw 'e'
     retlw ':'
     retlw 0xFF
     retlw 'M'
     retlw 'i'
     retlw 'l'
     retlw 'e'
     retlw 's'
     retlw 0x00
;====================================================================
; CODE SEGMENT
;====================================================================
     clrf      count  
Message
     movf      count, w       ; put counter value in W
     call      Text           ; get a character from the text table
     xorlw     0xFF           ; is it a zero?
     btfsc     STATUS,2
     call      PutMiles
     xorlw     0x00
     btfsc     STATUS,2
     goto      NextMessage
     call      LCD_Char
     incf      count,f
     goto      Message
PutMiles
     movf      Tens,w
     call      LCD_Char
     movf      Ones,w
     call      LCD_Char
     movlw     0x20           ;ascii "space" between data and unit
     return
LCD_Char
;     <insert your code here>
NextMessage
     end
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:
Top