Hello,
i've adapt the code to MB Can someone check it or say why i have always 5585 rpm??? I send info not by LCD but by USART(9600) and i use Pic 16F876 4 mhz:
program Tach
'Program measures the rotation period based on a pulse input and calculates RPM
'NOTE: Interrupt Procedure is NOT used as the CCP2 interrupt flag is set regardless
'of whether interrupt is enabled. Since the CCP2IF is checked in the Main repeat loop, there is no
'need for the MP3 Interrup Procedure.
'include "Tach_Acq" 'Determines rotation period time based on Timer TMR1
'Note this works for an 18F452 with a 4 Mhz crystal
'MP3 Default Configuration for 19F452 chip was used for chip configuration
'Note: 18F452 Chip is configured so that CCP2 is on pin RC1
'rather than RB3 __CONFIG _CONFIG3H_OFF
'Pulse train must be +5V (Pluse logic High) and 0 volts (Pulse Logic Low)
'Sub Procedure Initialize_LCD 'This must be tailored for your particular LCD set up
'
' LCD8_Config(PORTC,PORTD,6,4,5,7,6,5,4,3,2,1,0) 'RS,EN,RW Data Use in Real Fuel board Initialze LCD through PORTs
' LCD8_Cmd(Lcd_Clear) 'Clear LCD display
' LCD8_Cmd(Lcd_Cursor_Off) 'Turn visible cursor off
'
'End Sub
Sub Procedure Initialize_RS_232
USART_init(9600) ' Initialise RS232 communication
End Sub
Sub Procedure Initialize_Ports
'TRISD = $00 'Set all PORTD for output
'PORTD = $00
TRISC = 00000010 'TRISC = $02 ' 0000 0010 Set bit RC1 for CCP2 input, RC6,4,5(Rs/En/RW) LCD control Output
'Note: this may need to be changed to match your board wiring
End Sub
Sub Procedure Initialize_Timer_CCP
INTCON = $00 'Disable all Interrupts for initialization of other registers
'T3CON = $00 '0000 0000 was $C0 Sets Timer1 as source clock for CCP1 and CCP2 leaves timer3 off
CCP2CON = $06 'set for 4th rising edge, $07 Initially Set CCP2 for 16th Rising Edge Capture
T1CON = $01 'set for 8 bit time read, prescaler of 1 and turn timer 1 on
TMR1L = $00 'zero timer registers
TMR1H = $00
End Sub
'Sub Procedure Display_Title
' Dim Txtstr as char[16]
'
' TxtStr = " RPM READING " 'Displayed even when Tach pulse train is not ON
' LCD8_OUT(1,1,TxtStr)
'End Sub
Sub Procedure Display_RPM(Dim RPM as word)
Dim Txt as char[6]
Dim k as Byte
'Dim Txtstr as char[8]
Txt= "" 'Intialize Txt
'TxtStr= " RPM = " 'Displayed when Pulse train to CCP2 is active
'LCD8_OUT(2,1,Txtstr)
'LCD8_OUT(2,9,Txt)
Wordtostr(RPM,Txt)
USART_write(Txt)
End Sub
Sub Procedure ccp2_RPM(Dim Rot_P_H as byte,Dim Rot_P_L as byte)'CCP2_Fuel;
'This procedure is to measure the period of a pulse train to pin RC2.
' The rotation period of the engine is determined by the duration of pulse Low Logic + Pulse High Logic.
' Note: The procedure is set up to interrupt on the 16th rising edge of a pulse CCPXCON := 07
'**************************** Start of timing sequence *********************************************************
' <----------------------- 4th or 16th RE -----------_->
' '''''''''''| |'''''''''''| |''''''''''' '''''''| |'''''''
' |.......| |.......| |.......|
' 16thRE FE RE 16thRE Repeating
' start Time Stop Time
'****************************************************************************************************************
'*********************************************************************
'Note: 18F452 Chip is configured so that CCP2 is on pin RC1 rather than RB3 __CONFIG _CONFIG3H_OFF
'*********************************************************************
'The rising edge CCP2 capture may be set as either CCP2Con := $06 (every 4th rising edge) or
' CCP2Con := $07 (every 16th rising pules). Must also reset value in main pgrom in CCP2 Initialization procedure
'and CCP2_Call Procedure (where If statement signifies end of timeing sequence)
Dim Pulse_HSL as byte 'Hold Rise Edge time for start of timing sequence
Dim Pulse_HSH as byte
Dim Pulse_EL as byte 'Next Rising Edge for End of Time Sequence
Dim Pulse_EH as byte
'Start measurement with pulse going low (falling), end measurement with pulse going high (rising)
ClearBit(INTCON,GIE) 'clear GIE to prevent further interupts while handling this one
if TestBit(PIR2,CCP2IF) = 1 then 'Is it CCP2 Interrupt?
'Yes, it is CCP2 Interrup.
' The CASE section determines which code section processes the request, Start_Time, Fall_Edge or 2nd Rise_Edge
select case CCP2CON 'Note: CCP2CON := $06 (4th Rising edge) could also use $07 (16th rising edge)
case $06 'This STARTS TIMING SEQUENCE, get start time of every 4th rising edge - Leave and wait for next falling ($04) Edge of pulse train
'******* Captures Start time of pulse sequence (Rising edge *****************************************************=
Pulse_HSL = CCPR2L 'Get captured pulse high start time low byte *******Change back to CCPR1L *****
Pulse_HSH = CCPR2H 'Get captured time high byte
CCP2CON = $04 'Set to capture next Falling edge
ClearBit(PIR2,CCP2IF) 'Reset to preclude False Interrupt
case $04'This detects the falling edge simply to know to reset CCP2 module to intercept next Rising edge ($05)
'This is next falling edge of pulse, so reset for next rising edge($05 - which will end period measurement)
'All this does, on detection of the falling edge, is to reset the CCP2 module for next Rising Edge
CCP2CON = $05 'ReSet for Rising Edge Capture on next entry into this CCP2_RPM Routine
ClearBit(PIR2,CCP2IF) 'Clear in case of false interrupt when changin mode
case $05'This ENDS TIMING SEQUENCE
' 2nd Rising edge (1st after Fallin edge) so timing sequence is complete - calculate time internvals
'Find Rotation Period - Rot_P_X
Pulse_EL = CCPR2L 'Get time of second Rising Edge
Pulse_EH = CCPR2H
Rot_P_L = Pulse_EL - Pulse_HSL 'Calculate Rotation Time = Time Pulse HI + Time Pulse Lo
If TestBit(STATUS,C) = 0 then
Pulse_EH = Pulse_EH - 1
Rot_P_H = Pulse_EH - Pulse_HSH
CCP2CON = $06 'Set to start next timing cycle on 4th rising edge was $07 Set for 16th Rising edge Interrupt
ClearBit(PIR2,CCP2IF) 'Clear possible supurious Interrupt caused by changing CCP interrupt mode
end if
end select'case
end if ' end of IF Statement CCP2_Inj
end sub
Sub Procedure CCP2_Call 'Calls CCP2_RPM to get pulse interval of rotation period then calculates and displays RPM
Dim Rot_P_L as byte 'Bytes to hold rotation period time from CCP2_RPM
Dim Rot_P_H as byte
Dim R_Period as Word 'Holds rotation period time calculated
Dim RPM as word 'Holds RPM value calculated
Rot_P_L = 0'Variables for Rotation Period Time
Rot_P_H = 0
If testbit(PIR2,CCP2IF) = 1 then 'If CCP2 flag is set then pulse has triggered CCP2 module
ccp2_RPM( Rot_P_H,Rot_P_L) 'Calls to Data_Acq unit for pulse measurements
if (CCP2CON = $06) AND (CCP2IF = 0) then 'update viariable values after finished with entire time sequence
R_Period = 00
R_period = Word(Rot_P_H <<
OR Rot_P_L 'combined hi and low byte of rotation period into word
RPM = 60000000 div R_Period 'Calculate RPM (period is in clock cycles this turns it into revs/min)
'Conversion value valid for a 4 Mhz oscillator frequency ONLY
Display_RPM(RPM) 'Displays RPM Data
end if 'If (CCP2CON =7 .....
ClearBit(PIR2,CCP2IF)'Clear ccp2 Flag for next cycle
end if
End Sub
Main: 'Main part of program
Initialize_Ports
'Initialize_LCD
Initialize_RS_232
Initialize_Timer_CCP
'Display_Title 'Display title of program on LCD
while TRUE 'Loop forever calling CCP2_Call to determine rotation period and calculate RPM
CCP2_call 'Call for Data and display RPM based on CCP2 module response to a pulse train
wend
end.
I have put all procedure and ccp2_RPM TOO in One Project!
Best Regards