| ??? 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 |
| Topic | Author | Date |
| 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 |



