??? 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 |