Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
05/15/03 17:19
Read: times


 
#45556 - Velocity tracker using an 8051
Hi,
I am trying to write a program to track the velocity or range of an object using an ultrasonic transducer which send pulses and the pulses interrupt the processor when returning back . I am using the timers to determine the delay and had approximated the counted needed to make a metre. Since i haven't been that comfortable with the programming i just wondering if any of you guys can see any errors (i got no assembler errors) in the program (if you got some time and would like to check it out). Also since I can't get hold of any 44780 ic i am just wondering if there's a compatible alternative . Besides i decided not make the whole thing very accurate as i thought i should make things simpler first of all,I did not use floating point calculations and made all the calculatons in cm.

well thanks for checking this out.

I'd pasted the program below.
i think i had used a lot of memory locations unnecessarily. Anyway thanks again to you guys...


$DATE(May 2003) ; set date string

$PAGELENGTH (200) ; set list file page length to 200 lines

$PAGEWIDTH (110) ; set list file line width to 110 columns

$XREF ; generate cross reference listing

$NOTABS ; expand all tab characters to blanks

$NOMOD51 ; disable predefined standard 8051 SFR symbols

$INCLUDE (8052.MCU) ; include 8052 SFR symbol definitions

$LIST ; listing on


; SYMBOL AND CONSTANTS DEFINITIONS

; THE ENTIRE BANK 2 AND BANK 3 REGISTERS ARE USED FOR VARIABLES

RES0 DATA 010H ; 1 byte variable storing the Final result LSB
RES1 DATA 011H ; 1 byte variable
RES2 DATA 012H ; 1 byte variable
RES3 DATA 013H ; 1 byte variable
RES4 DATA 014H ; 1 byte variable storing the Final result MSB

VAR0 DATA 015H ; 1 byte scratchpad variable for temporary storage
VAR1 DATA 016H ; 1 byte scratchpad variable for temporary storage

MVAR0 DATA 017H ; 1 byte variable for storing metre byte of first counter
MVAR1 DATA 018H ; 1 byte variable for storing metre byte of second counter
CMVAR0 DATA 023H ; 1 byte variable for storing cm byte of first counter
CMVAR1 DATA 024H ; 1 byte variable for storing cmbyte of first counter

; DIVISION VARIABLES

DIVIDEND DATA 019H ; 16 bit number to be divided NOTE: It holds the LSB first
QUOTIENT DATA 01DH ; 16 bit result of the division it holds the LSB First
DIVISOR DATA 01BH ; 16 bit divisor equals to the number of T states required to make a cm
COUNT DATA 021H ; 8 bit shift counter

DIR BIT 020H.1 ; 1 bit variable to check for direction
OOR BIT 020H.2 ; 1 bit variable check for out of range condition
RET0 BIT 020H.3 ; 1 bit variable to wait for the signal 0 to return
RET1 BIT 020H.4 ; 1 bit varible to check for the return of signal 1

; these values are precalculated , assuming proper sound velocity and thus the values are calculted

CONST0 EQU 0ADH ; initial count lower byte ( total 16 bit count required to make a metre is 1752)
CONST1 EQU 0E8H ; initial count higher byte ( so initial count to be loaded is E8ADH)
CMCONST EQU 3CH ; count needed to make a cm





CSEG ; Code segment starts from here

ORG 0000H ; EXECUTION STARTS
AJMP START

ORG 0003H ; _INT0 Pin Interrupt Handler
ACALL INTR0
RETI
; the TIMER 0 interrupts the processor after a distance of 1 metre (including return time) and
; increments the metre counter R0
ORG 000BH ; TIMER 0 Pin Interrupt Handler
ACALL TMRINTR0
RETI

ORG 0013H ; _INT1 Pin Interrupt Handler
RETI ; nothing to do

; the TIMER 1 interrupts the processor after a distance of 1 metre (including return time) and
; increments the metre counter R1
ORG 001BH ; TIMER 1 Interrupt Handler
ACALL TMRINTR1
RETI

ORG 0023H ; Serial Port Interrupt Handler
RETI ; nothing to do

ORG 002BH ; Timer 2 Interrupt Handler
RETI ; provide accomodation for chips with 3 timers


; INTERRUPT HANDLERS
; ---------------------------------------------------------------------

ORG 0035H ; main code starts from here

TMRINTR0: ; Timer 0 interrupt subroutine
MOV TH0,#CONST1 ; reload counter of timer 0 , higher byte
MOV TL0,#CONST0 ; reload counter of timer 0 , lower byte
SETB TR0 ; start counting again
MOV A,R0 ; mov metre counter to the acc
ADD A,#01H ; this is done so as to make checking of overflow possible , i.e. carry will occur
MOV R0,A ; increment this variable if timer 0 overflows
JNC NOF0 ; check for overflow
SETB OOR ; set the OOR bit if the signal does not return back within the possible range
NOF0:
RET

TMRINTR1: ; timer 1 interrrupt subroutine
MOV TH1,#CONST1 ; reload counter of timer 1 , higher byte
MOV TL1,#CONST0 ; reload counter of timer 1 , lower byte
SETB TR1 ; start counting again
MOV A,R1 ; mov the metre counter to the acc and
ADD A,#01H ; increment it ,
MOV R1,A ; this is done so as to make checking of overflow possible , i.e. carry will occur
JNC NOF1 ; Check if the overflow occurs
SETB OOR ; set the OOR bit when signal is not received , out of range
NOF1:
RET ; Go back to the calling program


INTR0: ; External Interrupt 0 handler
JB TR0,STOP0 ; check if Timer 0 is still running then stop it else proceed
JB TR1,STOP1 ; check if Timer 1 is still running then stop it else proceed
STOP1:
CLR TR1 ; Stop TIMER 1
SETB RET1 ; set the RET1 bit if the signal 2 returns back
STOP0:
CLR TR0 ; Stop TIMER 0
SETB RET0 ; set the RET0 bit if the signal 1 returns back
RET ; go back to calling program

; MAIN PROGRAM
; ------------------------------------------------------------------

START:
CLR A ; clear ACC
CLR OOR ; Clear out of range bit
CLR RET0 ; clear signal 0 return bit
CLR RET1 ; clear signal 1 return bit
CLR DIR ; clear direction bit
USING 0 ; Use Bank 0 Registers
MOV R0,#00H ; clear the variable being used before starting again
MOV R1,#00H ; clear the variable being used before starting again
MOV TMOD,#17H ; set count mode to mode 1 for both timer 0 and timer 1
MOV IP,#01H ; give _int0 the highest priority
LCALL DISPLAY ; call subroutine for prompt
POLL:
JB P1.7,VLCTYTRK ; go to the subroutine for finding velocity
JB P1.6,RANGING ; go to the subroutine for finding range
SJMP POLL ; go back to POLL if no input is detected ,continue Polling

; RANGING
; -----------------------------------------------------------

RANGING: ; finding the range
LCALL BLNKDIS ; display blank on LCD during operation
MOV TL0,#CONST0 ; reset counter 0 lower byte
MOV TH0,#CONST1 ; reset counter 0 higher byte
MOV IE,#8BH ; enable _int0, enable timer 0 interrupt, disable timer 1 interrupt, disable _int1,
MOV TCON,#05H ; set interrupt control to edge triggered
SENDP0: ; sending pulse 0
CLR P1.4 ; blank receiver while transmitting pulse 0

SETB TR0 ; start counter 0
SETB P1.5 ; this instruction will send pulse 0
LCALL DELAY25 ; this instruction will call a delay for 2.5 ms
CLR P1.5 ; stop the pulse

SETB P1.4 ; enable receiver after transmission of pulse 1
WAIT1:
JB RET0,PROCESS1 ; wait for counter 0 to stop ,i.e. when pulse 1 is received
JB OOR,END1 ; terminate on out of range condition
SJMP WAIT1 ; keep monitoring
PROCESS1:
MOV IE,#00H ; disable all interrupts
LCALL RANCAL ; call subroutine to calculate range
LCALL DEC2ASCI ; get the ASCII value of the decimal result
LCALL RANDIS ; call subroutine to display result of the range
LJMP START ; start polling again
END1:
LCALL OOFRANG ; out of range
LJMP START ; go back

; VELOCITY TRACKING
; ---------------------------------------------------------------------
VLCTYTRK: ; finding the velocity
LCALL BLNKDIS ; display blank on LCD during operation
MOV TL0,#CONST0 ; reset counter 0 lower byte
MOV TH0,#CONST1 ; reset counter 0 higher byte
MOV TL1,#CONST0 ; reset counter 1 lower byte
MOV TH1,#CONST1 ; reset counter 1 higher byte
MOV IE,#8BH ; enable _int0, enable timer 0 interrupt, enable timer 1 interrupt, disable _int1,
MOV TCON,#05H ; set interrupt control to edge triggered
SENDP00: ; sending pulse 0
CLR P1.4 ; blank receiver while transmitting pulse 1

SETB TR0 ; start counter 0
SETB P1.5 ; this instruction will send pulse 1
LCALL DELAY35 ; this instruction will call a delay for 3.5 ms
CLR P1.5 ; stop the pulse

SETB P1.4 ; enable receiver after transmission of pulse 1
GAP: ; gap of 5 ms between pulses
LCALL DELAY5 ; 5 ms delay
LCALL DELAY5 ; 5 ms delay
SENDP01: ; sending pulse 1
CLR P1.4 ; blank receiver while transmitting pulse 2

SETB TR1 ; start counter 1
SETB P1.5 ; this instruction will send pulse 2
LCALL DELAY25 ; this instruction will call a delay for 2.5 ms
CLR P1.5 ; stop the pulse

SETB P1.4 ; enable receiver after transmission of pulse 2
WAIT0:
JB RET1,PROCESS0 ; wait for counter 1 to stop ,i.e. when pulse 2 is received
JB OOR,END0 ; terminate on out of range condition
SJMP WAIT0 ; keep monitoring
PROCESS0: ; process data
MOV IE,#00H ; disable all interrupts
LCALL VELCAL ; call subroutine to calculate velocity
LCALL DEC2ASCI ; get the ASCII value of the decimal result
LCALL VELDIS ; call subroutine to display result
LJMP START ; start polling again
END0:
LCALL OOFRANG ; out of range
LJMP START ; go back

; SUBROUTINES
; --------------------------------------------------------------

; ----------------- DELAYS --------------------------

DELAY5: ; 5.0009 ms delay not using the timer
MOV R2,#53H
L200:
MOV R3,#0B4H
L100:
NOP
NOP
DJNZ R3,L100
DJNZ R2,L200
RET ; return to calling program

DELAY25: ; 2.5049 ms delay not using the timer
MOV R2,#2BH
L201:
MOV R3,#0AEH
L101:
NOP
NOP
DJNZ R3,L101
DJNZ R2,L201
RET ; return to calling program

DELAY35: ; 3.49 ms delay not using the timer
MOV R2,#46H
L210:
MOV R3,#095H
L110:
NOP
NOP
DJNZ R3,L110
DJNZ R2,L210
RET ; return to calling program

DELAY1: ; 1.006 ms delay not using the timer
MOV R2,#1BH
L211:
MOV R3,#6FH
L111:
NOP
NOP
DJNZ R3,L111
DJNZ R2,L211
RET ; return to calling program

; -------------------- CALCULATIONS ---------------------------

VELCAL: ; subroutine to calculate velocity
MOV VAR0,TL0 ; move TL0 to VAR0 , cm lower byte to VAR0
MOV VAR1,TH0 ; move TH0 to VAR1 , cm higher byte to VAR1
MOV MVAR0,R0 ; move metre byte to MVAR0
LCALL MLTR ; call the subroutine to get the cm part
MOV CMVAR0,VAR0 ; mov the result from the subroutine in the cm variable

MOV VAR0,TL1 ; move TL1 to VAR0 , cm lower byte to VAR0
MOV VAR1,TH1 ; move TH1 to VAR1 , cm higher byte to VAR1
MOV MVAR1,R1 ; move metre byte to MVAR1
LCALL MLTR ; call the subroutine to get the cm part
MOV CMVAR1,VAR0 ; mov the result from the subroutine in the cm variable

MOV A,CMVAR0 ; get the differnce in the distance covered by the two pulses
CLR C
SUBB A,CMVAR1
JNC NEX0
CPL A
ADD A,#01H
NEX0:
MOV CMVAR0,A
MOV A,MVAR0
SUBB A,MVAR1
JNC NEX1
CPL A
ADD A,#01H
SETB DIR

NEX1:
MOV MVAR0,A ; difference in distance is again put back in the location MVAR0 AND CMVAR0
LCALL HX2DEC ; get the decimal value of the hexadecimal result
; shift decimal digits to the left by two position to get the distance for an interval of 10ms
MOV RES4,RES2 ; minimum velocity that can be tracked is 1 m/s
MOV RES3,RES1
MOV RES2,RES0


NEXT:
; divide total distance covered by the time i.e 10ms = multiply by 100d i.e. 64h
RET

RANCAL: ; subroutine to calculate range
MOV VAR0,TL0 ; move TL0 to VAR0 , cm lower byte to VAR0
MOV VAR1,TH0 ; move TH0 to VAR1 , cm higher byte to VAR1
MOV MVAR0,R0 ; move metre byte to MVAR0
LCALL MLTR ; call the subroutine to get the the exact count in cm
LCALL HX2DEC ; get the decimal equivalent of the result
MOV CMVAR0,VAR0 ; mov the result from the subroutine in the cm variable
RET


MLTR: ; this subroutine takes the centimetre counters frOm the timer 16 bit counter and subtract them
; by the initial count

; NOTE: SOURCE is VAR0 & VAR1,AFTER CALCULATION RESULT IS PUT BACK THERE

CLR C ; Clear carry for subtraction operations
MOV A,VAR0 ; Move the cm counter lower byte in the ACC
SUBB A,#CONST0 ; subtract the counter lower byte by the initial count lower byte
MOV VAR0,A ; store the result in the same place
MOV A,VAR1 ; move the cm counter higher byte in the ACC
SUBB A,#CONST1 ; subtract the counter higher byte the initial count higher byte (with the previous carry)
MOV VAR1,A ; store the result in the same place

DIVRTNE: ; division subroutine for two 2-byte numbers
; NOTE: SOURCE is VAR0 & VAR1,AFTER CALCULATION RESULT IS PUT BACK IN VAR0
MOV DIVISOR,#CMCONST ; bring out the contents of the counters high and low bytes as centimetrs in a single location
MOV DIVISOR+1,#00H
MOV DIVIDEND,VAR0
MOV DIVIDEND+1,VAR1
MOV COUNT,#01H
MOV COUNT+1,#00H
MOV QUOTIENT,#00H
MOV QUOTIENT+1,#00H

DIVLOOP1:

MOV A,DIVIDEND
CLR C
SUBB A,DIVISOR
MOV A,DIVIDEND+1
SUBB A,DIVISOR+1
JC DIVEND1

MOV A,DIVISOR
RLC A
MOV DIVISOR,A
MOV A,DIVISOR+1
RLC A
MOV DIVISOR+1,A

MOV A,COUNT
CLR C
RLC A
MOV COUNT,A
MOV A,COUNT+1
RLC A
MOV COUNT+1,A

AJMP DIVLOOP1

DIVEND1:

MOV A,COUNT
DEC A

JZ DIVEND

CLR C
MOV A,DIVISOR+1
RRC A
MOV DIVISOR+1,A
MOV A,DIVISOR
RRC A
MOV DIVISOR,A

MOV A,COUNT+1
CLR C
RRC A
MOV COUNT+1,A
MOV A,COUNT
RRC A
MOV COUNT,A

DIVLOOP2:
MOV A,DIVIDEND
CLR C
SUBB A,DIVISOR
MOV B,A
MOV A,DIVIDEND+1
SUBB A,DIVISOR+1
JC DIVSKIP2

MOV DIVIDEND,B
MOV DIVIDEND+1,A

CLR C
MOV A,QUOTIENT
ADD A,COUNT
MOV QUOTIENT,A
MOV A,QUOTIENT+1
ADDC A,COUNT+1
MOV QUOTIENT+1,A

DIVSKIP2:

MOV A,DIVISOR+1
CLR C
RRC A
MOV DIVISOR+1,A
MOV A,DIVISOR
RRC A
MOV DIVISOR,A

MOV A,COUNT+1
CLR C
RRC A
MOV COUNT+1,A
MOV A,COUNT
RRC A
MOV COUNT,A

JNC DIVLOOP2
DIVEND:
MOV VAR0,QUOTIENT
RET

HX2DEC: ; converts the HEX value in MVAR0 and CMVAR0 to the decimal value
MOV A,MVAR0
MOV B,#64H
DIV AB
MOV RES4,A
MOV A,B
MOV B,#0AH
DIV AB
MOV RES3,A
MOV RES2,B
MOV A,CMVAR0
MOV B,#0AH
DIV AB
MOV RES1,A
MOV RES0,B
RET

DEC2ASCI: ; converts the decimal result to ASCII
MOV A,RES4
ADD A,'0'
MOV RES4,A

MOV A,RES3
ADD A,'0'
MOV RES3,A

MOV A,RES2
ADD A,'0'
MOV RES2,A

MOV A,RES1
ADD A,'0'
MOV RES1,A

MOV A,RES0
ADD A,'0'
MOV RES0,A

RET
; --------------------- DISPLAY SUBROUTINES ----------------


VELDIS: ; subroutine to display velocity
RET


RANDIS: ; subroutine to display range
RET


DISPLAY: ; initial display at booting
RET


BLNKDIS: ; blank display during operation
RET

OOFRANG: ; out of range display
RET


END



List of 8 messages in thread
TopicAuthorDate
Velocity tracker using an 8051            01/01/70 00:00      
   RE: Velocity tracker using an 8051            01/01/70 00:00      
      RE: Velocity tracker using an 8051            01/01/70 00:00      
   RE: Velocity tracker using an 8051            01/01/70 00:00      
   RE: Velocity tracker using an 8051            01/01/70 00:00      
      RE: Velocity tracker using an 8051            01/01/70 00:00      
         RE: Velocity tracker using an 8051            01/01/70 00:00      
         RE: Velocity tracker using an 8051            01/01/70 00:00      

Back to Subject List