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

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
01/12/06 17:32
Read: times


 
#107175 - Tachometer code with problems
Hi,

I'm busy making a tachometer for model engines that uses a hall effect sensor with one 'pulse' per revolution. I started out making a system that measured the time for each revolution, however, I have decided to simplify it by counting the number of revolutions in one second instead. I have been trying to avoid asking anyone for help, but unfortunately, I cannot see what I am doing wrong and hope that someone can possibly help me.

I am using an AT89S8252. The code uses timer 1 to time 1 second and timer 0 to count the number of revolutions. Only the lower byte of timer 0 is used, as that will give a large enough RPM range. At the moment when I turn my circuit on, it displays 'RPM: 00000_'. I'm not sure why the underscore is there. When I cause a 1-0 transition on P3.4, nothing happens. I have simulated the code on Pinnacle 52 without any of the LCD code included and it seems to be doing what I want, so I have a feeling it has something to do with writing the RPM to the LCD.

The '2 BYTE HEX TO 5 DIGITS BCD' section of code came straight from the code library, so there shouldn't be a problem with that. Most of the LCD subroutines came from Craig Steiner's book, so they should also be OK.

Finally, before I give the code, I have tried to comment wherever possible, so I hope the code makes sense.

;Code assumes an AT89S8252 with 12MHz crystal

Initial:	LJMP Start

		ORG 0034h
Start:		MOV TMOD, #15h 		;Setup timer 0 and timer 1
				
		SETB EA 		;Enable interrupts
		SETB ET1 		;Enable timer 1 interrupt
				
		EN EQU P3.5 
		RW EQU P3.6 
		RS EQU P3.7 
		DATA EQU P2				
		TCOUNT EQU 40h  	;This is an address in IRAM
   		ALARM  EQU 00h  	;This is an address of BIT memory


INIT_LCD:	MOV A, #38h 		;Setting up LCD
		LCALL LCD_COMMAND 	;Setting up LCD
		MOV A, #0Eh 		;Setting up LCD 
		LCALL LCD_COMMAND 	;Setting up LCD
		MOV A, #06h 		;Setting up LCD
		LCALL LCD_COMMAND 	;Setting up LCD
				
		LCALL CLEAR_LCD 	;Clear LCD
		MOV A, #'R' 		;Write 'R' to LCD
		LCALL LCD_WRITE
		MOV A, #'P' 		;Write 'P' to LCD
		LCALL LCD_WRITE
		MOV A, #'M' 		;Write 'M' to LCD
		LCALL LCD_WRITE
		MOV A, #':' 		;Write ':' to LCD
		LCALL LCD_WRITE
			
				
Mainloop:		
				
		MOV TL0, #00h 		;Set timer 0 to #00h initially
		MOV TH1,#03Ch 		;Initialize TH1 to overflow every .05 seconds
      		MOV TL1,#0B0h 		;Initialize TL1 to overflow every .05 seconds
		MOV TCOUNT,#20  	;Set TCOUNT to 20 to wait for 1 second
      		SETB TR1        	;Turn timer 1 on
      		JNB ALARM,$     	;Cycle until ALARM is set (1 second later)
				
		LCALL RPM_CALC
		CLR TR1 		;Stop timer 1
		CLR ALARM 		;Clear ALARM bit

; Writing RPM to the LCD
				
		MOV A, #85h 		;Move cursor on LCD
		LCALL LCD_COMMAND
		MOV A, 74h 		;Move highest byte of decimal RPM to accumulator
		ADD A, #30h 		;Add #30h to convert to correct ASCII character
		LCALL LCD_WRITE		;Write to LCD
		MOV A, 75h		;Move 2nd highest byte of decimal RPM to accumulator
		ADD A, #30h		;Add #30h to convert to correct ASCII character
		LCALL LCD_WRITE		;Write to LCD
		MOV A, 76h		;Move 3rd highest byte of decimal RPM to accumulator
		ADD A, #30h		;Add #30h to convert to correct ASCII character
		LCALL LCD_WRITE		;Write to LCD
		MOV A, 77h		;Move 4th highest byte of decimal RPM to accumulator
		ADD A, #30h		;Add #30h to convert to correct ASCII character
		LCALL LCD_WRITE		;Write to LCD
		MOV A, 78h		;Move 5th highest byte of decimal RPM to accumulator
		ADD A, #30h		;Add #30h to convert to correct ASCII character
		LCALL LCD_WRITE		;Write to LCD
				
		LJMP Mainloop		;Repeat the loop

;************
;*Interrupts*
;************
				
		ORG 001Bh		;Timer 1 interrupt
				
		MOV TL1,#0B0h       	;Set TL1 to 0B0h
      		MOV TH1,#03Ch       	;Set TH1 to 3Ch
      		DJNZ TCOUNT,T1_EXIT 	;Decrement TCOUNT, if not zero exit interrupt
      		SETB ALARM          	;Set ALARM to indicate the preset time has passed
      
T1_EXIT:
      			
      		RETI                	;Return from the interrupt

;*************
;*Subroutines*
;*************

		ORG 0FAh
RPM_CALC:		
		MOV A, #03Ch 		;Set accumulator to 60 decimal
		MOV B, TL0 		;Store the low byte of timer 0 in the B register
		MUL AB 			;Multiply A and B to determine RPM
							
				
;**************************************************
;*      START OF 2 BYTE HEX TO 5 DIGITS BCD		  *	
;**************************************************				
		MOV R1, A		;Store low byte of RPM in R1
		MOV R2, B		;Store high byte of RPM in R2
				
		MOV	R5,#0
		MOV	R6,#0
		MOV	R7,#0

		MOV	A,R1
		MOV	B,#10
		DIV	AB
	
		MOV	R3,B		; Lower byte, in R1, is transformed into 2 decade digits,
		MOV	R4,A		; it's OK that the higher one can be greater than 9

		MOV	A,R2		; Higher byte is in R2
		JZ	SPRING		; Spring over if 0
		MOV	B,#10
		DIV	AB

		MOV	R5,B		; Same as for lower byte
		MOV	R6,A

; Value in R5 is 256 times higher than value standing in R3, R4. Mply R5 with 6,
; add to R3, mply R5 with 5, add to R4, mply R5 with 2 and replace itself in R5

		MOV	R0,#05		; Point to R5
		ACALL	TRANSF		; Transform R5 to 3 lower positions

		INC	R0		; Repeat from R6, now all registers are 1 higher
		ACALL	TRANSF		; Transform R6 to 3 higher positions

SPRING:		MOV	R0,#03		; Point to lowest digit

; Adjust to decimal, everything higher than 9 should be, as 1 tenth, added to higher.
; Starting from the lowest digit, divide with 10, keep the rest, and add the 1/10th to
; first higher place (eg. 145, leave 5 and add 14 to the next higher)

		ACALL	DECADJ

		LJMP	END_HEX

TRANSF:		MOV	A,@R0
		MOV	B,#6
		MUL	AB
		DEC	R0
		DEC	R0
		ADD	A,@R0
		MOV	@R0,A

		INC	R0
		INC	R0
		MOV	A,@R0
		MOV	B,#5
		MUL	AB
		DEC	R0
		ADD	A,@R0
		MOV	@R0,A

		INC	R0
		MOV	A,@R0
		RL	A		; Mply with 2
		MOV	@R0,A

		RET

DECADJ:		MOV	A,@R0
DECLOP:		MOV	B,#10
		DIV	AB
		MOV	@R0,B
		INC	R0
		ADD	A,@R0
		MOV	@R0,A
	
		CJNE	R0,#7,DECLOP
		RET

END_HEX:	MOV 74h, R7      
		MOV 75h, R6
		MOV 76h, R5
		MOV 77h, R4
		MOV 78h, R3

;**************************************************
;*       END OF 2 BYTE HEX TO 5 DIGITS BCD	  *	
;**************************************************					
				
		RET			
				


LCD_COMMAND:	CLR RS
		CLR RW
		MOV DATA, A
		SETB EN
		NOP
		NOP
		NOP
		NOP
		CLR EN
		LCALL WAIT_LCD
		RET

WAIT_LCD:	MOV R1, #27h		;Store #39 decimal in R1
TOP:		MOV R0, #00h		;Store #00h in R0
WAIT_LCD1:	CLR RS
		SETB RW
		MOV DATA, #0FFh
		SETB EN
		MOV A, DATA
		LJMP TEST
CONT:		JB ACC.7, WAIT_LCD1
		LJMP MOV
TEST:		DJNZ R0, CONT		;If R0 not zero then go to CONT
		DJNZ R1, TOP		;If R1 not zero then go to TOP
MOV:		CLR EN
		CLR RW
		RET
				
				
;WAIT_LCD will only repeat 9984 times then continue


CLEAR_LCD:	MOV A, #01h
		LCALL LCD_COMMAND
		RET
				
LCD_WRITE:	SETB RS
		CLR RW
		MOV DATA, A
		SETB EN
		NOP
		NOP
		NOP
		NOP
		CLR EN
		LCALL WAIT_LCD
		RET
				
				
END 


I hope what I have said is clear and understandable.

Thanks
Warren

List of 28 messages in thread
TopicAuthorDate
Tachometer code with problems            01/01/70 00:00      
   have you tried to separate the elements?            01/01/70 00:00      
   LCD problems            01/01/70 00:00      
      from the left and from the right            01/01/70 00:00      
         Good point            01/01/70 00:00      
            I like the ideas so far...            01/01/70 00:00      
               Flashing cursor            01/01/70 00:00      
   underscore?            01/01/70 00:00      
   Set TR0 bit in TCON (TCON..4)            01/01/70 00:00      
      right there in "the bible" ch3 pg7): "TC            01/01/70 00:00      
         It works - well the software anyway...            01/01/70 00:00      
            ir does            01/01/70 00:00      
               I'm getting there...slowly            01/01/70 00:00      
                  the only problem with the sensor is that            01/01/70 00:00      
                     Personally            01/01/70 00:00      
                     How embarrassing...            01/01/70 00:00      
                     Noise pickup            01/01/70 00:00      
                        It's my own engine            01/01/70 00:00      
                           Averaging            01/01/70 00:00      
                              car rpm - mahmood            01/01/70 00:00      
                                 some links            01/01/70 00:00      
                                    much thanks            01/01/70 00:00      
   I've had some success...            01/01/70 00:00      
      not the points            01/01/70 00:00      
         Maybe not the points, but...            01/01/70 00:00      
            Screen the hall sensor.            01/01/70 00:00      
               Simple the better            01/01/70 00:00      
                  Hall vs Opto            01/01/70 00:00      

Back to Subject List