Tachometer
tach problem in MB
Hello,
Thanks to your fast reply but in my code that i have compile and test with a 16f876 4 mhz i put "8)" in R_Period = Word(Rot_P_H << HERE OR Rot_P_L ! SO, is not the problem! But Has you see, in a 16f876 i don't have "T3CON" SO, in your code i have simple erase this line "'T3CON = $00 '0000 0000 was $C0 Sets Timer1 as source clock for CCP1 and CCP2 leaves timer3 off" with a " ' "! I think it's a problem but with what i must replace T3CON = $00 in my 16f876???
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
Best Regards
Thanks to your fast reply but in my code that i have compile and test with a 16f876 4 mhz i put "8)" in R_Period = Word(Rot_P_H << HERE OR Rot_P_L ! SO, is not the problem! But Has you see, in a 16f876 i don't have "T3CON" SO, in your code i have simple erase this line "'T3CON = $00 '0000 0000 was $C0 Sets Timer1 as source clock for CCP1 and CCP2 leaves timer3 off" with a " ' "! I think it's a problem but with what i must replace T3CON = $00 in my 16f876???
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
Best Regards
When i say 8) it always put a smile but i put 8 and )
When i say it always put a smile but i put 8 and ) like you say in your post!
Tach
Ok, I thought the "8)" might be there but was not certain. Unfortunately, I have no experience with any of the chips but the 18F452, so unable to suggest what you might do with your chip.
I presume that the pulse train your are feeding your chip is varying and not just stuck at at value that would give your the 5580 rpm?
Wish I could assist more, good luck.
I presume that the pulse train your are feeding your chip is varying and not just stuck at at value that would give your the 5580 rpm?
Wish I could assist more, good luck.
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered
Matthews, NC USA
Rv-6A N494BW Rotary Powered
It's works in MB ;-))
Hello,
I found the problem, it's in the procedure "Sub Procedure ccp2_RPM(Dim Rot_P_H as byte,Dim Rot_P_L as byte)" I use "Rot_P_H" and "Rot_P_L" in PROCEDURE VARIABLE AND NOT IN GLOBAL VARIABLE!!! And the result never return and was always "0"!!!! So i put it in global variable and all work well!!!
To have just the time(µs or ms) of 1 pulse go on and go off! How can i have it??? I want just to know how many time(µs) the pulse are in High Logic? It's the TIME HI_LOGIC=word(Pulse_HSH <<8) OR Pulse_HSL ???
Best Regards,
I found the problem, it's in the procedure "Sub Procedure ccp2_RPM(Dim Rot_P_H as byte,Dim Rot_P_L as byte)" I use "Rot_P_H" and "Rot_P_L" in PROCEDURE VARIABLE AND NOT IN GLOBAL VARIABLE!!! And the result never return and was always "0"!!!! So i put it in global variable and all work well!!!
To have just the time(µs or ms) of 1 pulse go on and go off! How can i have it??? I want just to know how many time(µs) the pulse are in High Logic? It's the TIME HI_LOGIC=word(Pulse_HSH <<8) OR Pulse_HSL ???
Best Regards,
Logic High?
Glad you found the problem with your code. The Tach_Acq unit was code to provide the time from rising edge of pulse to next rising edge of pulse. This is one revolution period for Tachometer RPM. To read only the high pulse is also possible. However, the code must be re written. There are changes required in the CCP2 module, the calculation of PW and in the setting of CCP2Con.
Here is the code modified to measure the duration of Pulse High (Logic High) of a pulse train. It will measure between 1 and 10 milliseconds (I have tested it for that interval, but it should work for larger values).
The key is you must set the CCP module to intercept on the rising edge and falling edge capturing the Timer value at each point. Then by math you find the duration of the pulse for logic High.
The LCD will display the logic high as xx.xx milliseconds without the decimal. So for example, display of 750 is 7.50 milliseconds.
Note: you must set the LCD initialization different than my code to one that works for your LCD hook up.
Here is the code. There is the Main program PW_High.ppas and one Unit PW_Acq_high.ppas. It is possible to combine the two into one program.
1st is Main program
Here is the code modified to measure the duration of Pulse High (Logic High) of a pulse train. It will measure between 1 and 10 milliseconds (I have tested it for that interval, but it should work for larger values).
The key is you must set the CCP module to intercept on the rising edge and falling edge capturing the Timer value at each point. Then by math you find the duration of the pulse for logic High.
The LCD will display the logic high as xx.xx milliseconds without the decimal. So for example, display of 750 is 7.50 milliseconds.
Note: you must set the LCD initialization different than my code to one that works for your LCD hook up.
Here is the code. There is the Main program PW_High.ppas and one Unit PW_Acq_high.ppas. It is possible to combine the two into one program.
1st is Main program
Code: Select all
program PW_High;
//Program measures the logic High portion of a pulse train based on a pulse input and displays the PW in milliseconds
//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.
uses PW_Acq_High; //Determines logic Hign period time based on Timer TMR1
//Note this works for an 18F452 with a 4 Mhz crystal
//MP3 Default Configuration for 18F452 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)
Procedure Initialize_LCD; //This must be tailored for your particular LCD set up
begin
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;
Procedure Initialize_Ports;
begin
TRISD:= $00; //Set all PORTD for output
PORTD:= $00;
TRISC:= $02; // 0000 0010 Set bit RC1 for CCP2 input, RC6,4,5(Rs/En/RW) LCD control Output
end;
Procedure Initialize_Timer_CCP;
begin
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:= $05; //set for 1th rising edge
T1CON := $01; //set for 8 bit time read, prescaler of 1 and turn timer 1 on
TMR1L := $00; //zero timer registers
TMR1H := $00;
end;
Procedure Display_PW(PW:word);
var Txt: array[6] of char;
Txtstr: array[12] of char;
begin
Txt := ' '; //Intialize Txt
TxtStr := ' MP3 PW High';
LCD8_OUT(1,1,Txtstr);
TxtStr := 'X.XX msec'; //Displayed when Pulse train to CCP2 is active
LCD8_Out(2,8,Txtstr);
Wordtostr(PW,Txt);
LCD8_OUT(2,1,Txt);
end;
Procedure CCP2_Call; //Calls CCP2_PW to get pulse interval of rotation period then calculates and displays PW
Var
PW_L :byte; //Bytes to hold pulse time information from Tach_Acq_High unit
PW_H :byte;
PW :Word; //Holds PW Logic High time calculated
Begin
PW_L := 0;//Variables for Rotation Period Time
PW_H := 0;
If testbit(PIR2,CCP2IF) = 1 then //If CCP2 flag is set then pulse has triggered CCP2 module
begin
ccp2_PW( PW_H,PW_L); //Calls to Data_Acq unit for pulse measurements
if (CCP2CON = $05) AND (CCP2IF = 0) then //update viariable values and make calculation after finished with entire timeing sequence
begin
PW := 00;
PW := Word(PW_H shl 8) OR PW_L;//combined hi and low byted of High Pulse period into word
PW := PW div 10;
//Calculate PW(period is in clock cycles this turns it into milliseconds)
//Conversion value valid for a 4 Mhz oscillator frequency ONLY
Display_PW(PW); //Displays PW Data
end; //If (CCP2CON =5 .....
ClearBit(PIR2,CCP2IF);//Clear ccp2 Flag for next cycle
end;
end;
begin //Main part of program
Initialize_Ports;
Initialize_LCD;
Initialize_Timer_CCP;
Repeat //Loop forever calling CCP2_Call to determine rotation period and calculate PW
CCP2_call; //Call for Data and displayPW based on CCP2 module response to a pulse train
until true = false;
end.
//Next is Unit
unit PW_Acq_High;
implementation
Procedure ccp2_PW(Var PW_H,PW_L:byte);//CCP2_Fuel;
//This procedure is to measure the period of a pulse train to pin RC2.
//
// Note: The procedure is set up to interrupt on the 1st rising edge of a pulse CCPXCON := 05
//**************************** Start of timing sequence *********************************************************
// <--- ->
// ' ''''''''''| |''''''''' ''| |'''''''''''
// |.......| |.......|
// 1stRE FE RE
// 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 set as CCP2Con := $05 Must also reset value in main pgrom in CCP2 Initialization procedure
//and CCP2_Call Procedure (where If statement signifies end of timeing sequence)
Var
Pulse_HSL :byte; //Hold Rise Edge time for start of timing sequence
Pulse_HSH :byte;
Pulse_LSL :byte; //Hold Falling Edge time ( end of logic High)
Pulse_LSH :byte;
TPulse_EL :byte; //temp variable for pulse High Logic (Low byte)
TPulse_EH :byte; //Temp variable for Pulse High Logic (High byte);
begin //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?
begin //Yes, it is CCP2 Interrup.
// The CASE section determines which code section processes the request, Start_Time, Fall_Edge or 2nd Rise_Edge
case CCP2CON of //Note: CCP2CON := $05 ( Rising edge)
$05: //This STARTS TIMING SEQUENCE, get start time of every rising edge - Leave and wait for next falling ($04) Edge of pulse train
//******* Captures Start time of pulse sequence (Rising edge *****************************************************=
begin
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
end;
$04: //This detects the falling edge which is the end of the pulse logic HIGH
begin
Pulse_LSL := CCPR2L; //Ge start time of low Logic zero = end of Logic High
Pulse_LSH := CCPR2H;
TPulse_EL:=Pulse_LSL; //Hold time value
TPulse_EH:=Pulse_LSH;
PW_L := Pulse_LSL - Pulse_HSL; //Calculate Pulse High Time low byte
IF TestBit(STATUS,C) = 0 then //if Borrow required reduce high value of TPulse_H by 1
TPulse_EH := TPulse_EH - 1;
PW_H := TPulse_EH - Pulse_HSH; //Calculate Pulse High Time High byte
//ReSet for Rising Edge Capture on next entry into ISR
[b] CCP2CON := $05[/b]; //ReSet for Rising Edge Capture on next entry into this CCP2_PW Routine
ClearBit(PIR2,CCP2IF); //Clear in case of false interrupt when changin mode
end;
end;//case
end; // end of IF Statement CCP2_Inj
end;
end.
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered
Matthews, NC USA
Rv-6A N494BW Rotary Powered
Pulse timer OK but signal input problem with Tacho
Hello,
Thanks for your pulse timer!!! It work well but if i need to measure pulse of 10 µs or 150 ms period ON how can do it? My signal that i take is from an injector of the engine!SO, for one injection(2 engine revolutions) i have a big pulse and then 10 small pulse(pre-injection and injection)! So, my problem is to measure time between 2 raise of the big pulse to know the time for 2 revolutions engines! How can differenciate big pulse and small?
One way but is theory is to measure time of each pulse and when i have the biggest time i start the timer and wait to have another same pulse but i don't know if the time of big pulse change rapidely??? Do you have anothers ideas???
Best Regards
Thanks for your pulse timer!!! It work well but if i need to measure pulse of 10 µs or 150 ms period ON how can do it? My signal that i take is from an injector of the engine!SO, for one injection(2 engine revolutions) i have a big pulse and then 10 small pulse(pre-injection and injection)! So, my problem is to measure time between 2 raise of the big pulse to know the time for 2 revolutions engines! How can differenciate big pulse and small?
One way but is theory is to measure time of each pulse and when i have the biggest time i start the timer and wait to have another same pulse but i don't know if the time of big pulse change rapidely??? Do you have anothers ideas???
Best Regards
Pulse signal
It would help if you could describe your pulse train in more detail. A drawing would help.
I am surprised that you would need 10 usec resolution for a fuel injection system. I programmed one to read the injection pulse train for a Mazda Rotary engine. At 6000 rpm the period of revolution is 10 milliseconds, the injector on time varies between 1.5 milliseconds and 5 milliseconds depending on power being produced.
Most electronic fuel injectors will not function (open and close) if the PW is below 1.5 milliseconds.
It would help if you could describe your pulse train in more detail. A drawing would help.
Yes, if there is only one large (duration?) pulse per revolution then measuring all pulse durations and then based on the largest you could start your timing. However, when do you know it is the largest? Is the largest pulse always a specific duration?? or do you have to compare all pulses? There may be an easier way.
It would help if you could describe your pulse train in more detail. A drawing would help.
I am surprised that you would need 10 usec resolution for a fuel injection system. I programmed one to read the injection pulse train for a Mazda Rotary engine. At 6000 rpm the period of revolution is 10 milliseconds, the injector on time varies between 1.5 milliseconds and 5 milliseconds depending on power being produced.
Most electronic fuel injectors will not function (open and close) if the PW is below 1.5 milliseconds.
It would help if you could describe your pulse train in more detail. A drawing would help.
Yes, if there is only one large (duration?) pulse per revolution then measuring all pulse durations and then based on the largest you could start your timing. However, when do you know it is the largest? Is the largest pulse always a specific duration?? or do you have to compare all pulses? There may be an easier way.
It would help if you could describe your pulse train in more detail. A drawing would help.
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered
Matthews, NC USA
Rv-6A N494BW Rotary Powered
How to generate pulse with different Freq/Period
Hello,
Thanks for you pulse high program, it resolve my problem! My signal is a signal that have all the time different Freqency but with Constant Period depending of the RPM! So, pulse high is very fine! I need know to translate my signal in different Period! So, how can i produce pulse when i want (not with a fixed freqency) and during a "X" period[ms] WITHOUT Interrupt because i need to use pulse high program and if i use interrupt it will corrupt the TIMER of the capture pwm mode, isnt it?
Simply i need to adapt the pulse high program to produce a pulse_out period depending of the pulse_in period without a fixed frequency because i make 1 pulse_out when i have 1 pulse_in! It's like i would like to make a pulse IN/OUT converter! Of course i take the period of the (n-1) pulse to calculate the time of my pulse_out period!
A function like pulse_out=(pulse n-1 _in period,% of the period,pin number)
If you can help me or give me idea how to make that it will be very nice!
Best Regards
Thanks for you pulse high program, it resolve my problem! My signal is a signal that have all the time different Freqency but with Constant Period depending of the RPM! So, pulse high is very fine! I need know to translate my signal in different Period! So, how can i produce pulse when i want (not with a fixed freqency) and during a "X" period[ms] WITHOUT Interrupt because i need to use pulse high program and if i use interrupt it will corrupt the TIMER of the capture pwm mode, isnt it?
Simply i need to adapt the pulse high program to produce a pulse_out period depending of the pulse_in period without a fixed frequency because i make 1 pulse_out when i have 1 pulse_in! It's like i would like to make a pulse IN/OUT converter! Of course i take the period of the (n-1) pulse to calculate the time of my pulse_out period!
A function like pulse_out=(pulse n-1 _in period,% of the period,pin number)
If you can help me or give me idea how to make that it will be very nice!
Best Regards
Pulse Signal
I think I am beinging to understand what you want to do, but not certain on all aspects.
1st you do not have to use procedure interrupt. I have not found its implementation in MP3 to be of any value since you can not call a procedure from it. The CCP module will have its flag set when the trigger conditions are met even if the CCP module interrupt is NOT enabled. The flag CCPxIF will always be set when trigger conditions are met. That way- all you have to do is check the CCPxIF flag in your program to see if its set or not. That is what I do - you will notice there is no Procedure Interrupt used in my programs.
Here is a simply program that generates logic high pulses of abritary period - or you can simply generate one pulse as you choose. A more elegant solution would be to use one of the timers rather than the MP delay_MS/delay_us procedures. However, the Delay procedures are rather accurate - at least for the 4 Mhz oscillator.
Here is code that might give you some ideas. Depending on how many values you need to generate something this simple could work. In the mean time - I'll try to find some time to do something with the CCP PWM capability - need to refresh my knowledge.
Hope this helps.
1st you do not have to use procedure interrupt. I have not found its implementation in MP3 to be of any value since you can not call a procedure from it. The CCP module will have its flag set when the trigger conditions are met even if the CCP module interrupt is NOT enabled. The flag CCPxIF will always be set when trigger conditions are met. That way- all you have to do is check the CCPxIF flag in your program to see if its set or not. That is what I do - you will notice there is no Procedure Interrupt used in my programs.
Here is a simply program that generates logic high pulses of abritary period - or you can simply generate one pulse as you choose. A more elegant solution would be to use one of the timers rather than the MP delay_MS/delay_us procedures. However, the Delay procedures are rather accurate - at least for the 4 Mhz oscillator.
Here is code that might give you some ideas. Depending on how many values you need to generate something this simple could work. In the mean time - I'll try to find some time to do something with the CCP PWM capability - need to refresh my knowledge.
Hope this helps.
Code: Select all
program PWM_Test;
var i, j : byte;
ms :word;
Procedure XPeriod (Logic_High:word) ;
begin //Note MS3 Delay_MS(x) funtion will not take a variable as an argument - it must be a constant
//Otherwise this would be much simpler
case MS of
1: begin
PORTB.0 := 1; //Turn on PW Logic High
Delay_MS(1 );
PORTB.0 := 0; //Turn off PW Logic Low
Delay_MS(1 );
end;
2: begin
PORTB.0 := 1; //Turn on PW Logic High
Delay_MS(2 ); //Duration of logic High
PORTB.0 := 0; //Turn off PW Logic Low
Delay_MS(10 ); //Duration of Logic Low (can be set to a different value to give a different frequency)
end;
5:begin
PORTB.0 := 1; //Turn on PW Logic High
Delay_MS(5 );
PORTB.0 := 0; //Turn off PW Logic Low
Delay_MS(10 ); //Note different Frequency
end;
10:begin
PORTB.0 := 1; //Turn on PW Logic High
Delay_MS(10 );
PORTB.0 := 0; //Turn off PW Logic Low
Delay_MS(5 );
end;
20:begin
PORTB.0 := 1; //Turn on PW Logic High
Delay_MS(20 );
PORTB.0 := 0; //Turn off PW Logic Low
Delay_MS(20 );
end;
end;//Case
end;
// Concept 1. Turn on A pulse (send a port bit logic high
// 2. Start Timer
// 3. When timer reaches desired value
// 4. Turn off pulse (send port bit Logic Low
begin
TRISB := $00; //Make PORTB output
ms := 10;//Change value as desired. Choice of value MUST match CASE conditions in procedure Xperiod
Repeat
Xperiod(MS);
Until True = false; //OR can use a for loop or use by itself for a single pulse
end.
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered
Matthews, NC USA
Rv-6A N494BW Rotary Powered
Vdelay_ms !!!! Is the solution!!!
Hello,
Thanks for your idea but in MB and in MP there is a function call Vdelay_ms (parameter) but mikro team say that is not accurate like delay_ms but i have find a solution to have a Vdelay accurate! What do you think of this:
To generate 12 ms i can use with a 4 Mhz clock (1 Cyc= 1/4000000 s) = > delay_Cyc(4) * 1000(µs to ms) * 12(number of ms)!!! The function is:
I have a precision of 1 µs i think because of delay_Cyc(4)!!!
Thanks for your idea but in MB and in MP there is a function call Vdelay_ms (parameter) but mikro team say that is not accurate like delay_ms but i have find a solution to have a Vdelay accurate! What do you think of this:
To generate 12 ms i can use with a 4 Mhz clock (1 Cyc= 1/4000000 s) = > delay_Cyc(4) * 1000(µs to ms) * 12(number of ms)!!! The function is:
I have a precision of 1 µs i think because of delay_Cyc(4)!!!
Code: Select all
dim counter as int
counter=0
do
delay_Cyc(Clock in Mhz)
inc(counter)
while (1000*12)
It's ok or NOT???
If yes what do you think of that:
program PW_High;
//Program measures the logic High portion of a pulse train based on a pulse input and displays the PW in milliseconds
//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.
uses PW_Acq_High; //Determines logic Hign period time based on Timer TMR1
//Note this works for an 18F452 with a 4 Mhz crystal
//MP3 Default Configuration for 18F452 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)
//GLOBAL VARIABLE
PW :Word; //Holds PW Logic High time calculated
Procedure Pulseout_µs(time:WORD;clock:BYTE) // Function like variable timer with "time" as time in µs to reach and "clock=4" for 4 Mhz clock
begin
Var
counter: int;// Counter that count as long as time is reach
counter=0;// Initialize counter
PORTB.0 := 1; //Turn on PW Logic High the pin that you choose
do
delay_Cyc(clock)
inc(counter)
while (time)
PORTB.0 := 0; //Turn off PW Logic High the pin that you choose
end;
Procedure Initialize_LCD; //This must be tailored for your particular LCD set up
begin
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;
Procedure Initialize_Ports;
begin
TRISD:= $00; //Set all PORTD for output
PORTD:= $00;
TRISC:= $02; // 0000 0010 Set bit RC1 for CCP2 input, RC6,4,5(Rs/En/RW) LCD control Output
end;
Procedure Initialize_Timer_CCP;
begin
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:= $05; //set for 1th rising edge
T1CON := $01; //set for 8 bit time read, prescaler of 1 and turn timer 1 on
TMR1L := $00; //zero timer registers
TMR1H := $00;
end;
Procedure Display_PW(PW:word);
var Txt: array[6] of char;
Txtstr: array[12] of char;
begin
Txt := ' '; //Intialize Txt
TxtStr := ' MP3 PW High';
LCD8_OUT(1,1,Txtstr);
TxtStr := 'X.XX msec'; //Displayed when Pulse train to CCP2 is active
LCD8_Out(2,8,Txtstr);
Wordtostr(PW,Txt);
LCD8_OUT(2,1,Txt);
end;
Procedure CCP2_Call; //Calls CCP2_PW to get pulse interval of rotation period then calculates and displays PW
Var
PW_L :byte; //Bytes to hold pulse time information from Tach_Acq_High unit
PW_H :byte;
Begin
PW_L := 0;//Variables for Rotation Period Time
PW_H := 0;
If testbit(PIR2,CCP2IF) = 1 then //If CCP2 flag is set then pulse has triggered CCP2 module
begin
ccp2_PW( PW_H,PW_L); //Calls to Data_Acq unit for pulse measurements
if (CCP2CON = $05) AND (CCP2IF = 0) then //update viariable values and make calculation after finished with entire timeing sequence
begin
PW := Word(PW_H shl 8) OR PW_L;//combined hi and low byted of High Pulse period into word
PW := PW div 10;
//Calculate PW(period is in clock cycles this turns it into milliseconds)
//Conversion value valid for a 4 Mhz oscillator frequency ONLY
Display_PW(PW); //Displays PW Data
end; //If (CCP2CON =5 .....
ClearBit(PIR2,CCP2IF);//Clear ccp2 Flag for next cycle
end;
end;
begin //Main part of program
Initialize_Ports;
Initialize_LCD;
Initialize_Timer_CCP;
PW := 00; // initialize timer period
Repeat //Loop forever calling CCP2_Call to determine rotation period and calculate PW
CCP2_call; //Call for Data and displayPW based on CCP2 module response to a pulse train
until true = false;
end.
//Next is Unit
unit PW_Acq_High;
implementation
Procedure ccp2_PW(Var PW_H,PW_L:byte);//CCP2_Fuel;
//This procedure is to measure the period of a pulse train to pin RC2.
//
// Note: The procedure is set up to interrupt on the 1st rising edge of a pulse CCPXCON := 05
//**************************** Start of timing sequence *********************************************************
// <--- ->
// ' ''''''''''| |''''''''' ''| |'''''''''''
// |.......| |.......|
// 1stRE FE RE
// 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 set as CCP2Con := $05 Must also reset value in main pgrom in CCP2 Initialization procedure
//and CCP2_Call Procedure (where If statement signifies end of timeing sequence)
Var
Pulse_HSL :byte; //Hold Rise Edge time for start of timing sequence
Pulse_HSH :byte;
Pulse_LSL :byte; //Hold Falling Edge time ( end of logic High)
Pulse_LSH :byte;
TPulse_EL :byte; //temp variable for pulse High Logic (Low byte)
TPulse_EH :byte; //Temp variable for Pulse High Logic (High byte);
begin //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?
begin //Yes, it is CCP2 Interrup.
// The CASE section determines which code section processes the request, Start_Time, Fall_Edge or 2nd Rise_Edge
case CCP2CON of //Note: CCP2CON := $05 ( Rising edge)
$05: //This STARTS TIMING SEQUENCE, get start time of every rising edge - Leave and wait for next falling ($04) Edge of pulse train
//******* Captures Start time of pulse sequence (Rising edge *****************************************************=
begin
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
Pulseout_µs(( PW div 10000) ;4); // I generate my pulseout= pulsein/10 in µs
end;
$04: //This detects the falling edge which is the end of the pulse logic HIGH
begin
Pulse_LSL := CCPR2L; //Ge start time of low Logic zero = end of Logic High
Pulse_LSH := CCPR2H;
TPulse_EL:=Pulse_LSL; //Hold time value
TPulse_EH:=Pulse_LSH;
PW_L := Pulse_LSL - Pulse_HSL; //Calculate Pulse High Time low byte
IF TestBit(STATUS,C) = 0 then //if Borrow required reduce high value of TPulse_H by 1
TPulse_EH := TPulse_EH - 1;
PW_H := TPulse_EH - Pulse_HSH; //Calculate Pulse High Time High byte
//ReSet for Rising Edge Capture on next entry into ISR
CCP2CON := $05; //ReSet for Rising Edge Capture on next entry into this CCP2_PW Routine
ClearBit(PIR2,CCP2IF); //Clear in case of false interrupt when changin mode
end;
end;//case
end; // end of IF Statement CCP2_Inj
end;
end.
Time Delay
I think I understand your Approach to the timing problem.
4MHZ Osc/4 = 1 MHZ Clock = 1 usec per clock cycle = 1 x10^-6 sec.
1x10^-6 * 1x*10^3 = 1x10^-3 or 1 millsecond every 1000 clock cycles
I do not understand where the 12 comes from? Is this the number of milliseconds delay you want??
If you want 12 milliseconds then you must turn the pulse on for 12000 clock cycles for a 4 Mhz oscillator
So 12 Milliseconds = 12*1000 = 12000 clock cycles
The question is how do you measure your 1000 clock cycles? I presume that is what your procedure
delay_cyc(4) will do.
Will delay_cyc(4) = 1000 clock cycles = 1000 usec?? = 1 millisecond??
If delay_cyc(4) = 1000 clock cycle delays then I think your code should read something like this for what ever language you are using:
Counter : variable
Repeat
delay_cyc(4) ;Delay 1000 clock cycles or 1 millisecond
inc(counter) ;Increment counter after 1 millisecond
until Counter = 12;when counter = 12 then 12*1000 clock cycles = 12 milliseconds
Again, that is if I understand what you are trying to accomplish and if delay_cyc(4) will give 1000 usec delay
4MHZ Osc/4 = 1 MHZ Clock = 1 usec per clock cycle = 1 x10^-6 sec.
1x10^-6 * 1x*10^3 = 1x10^-3 or 1 millsecond every 1000 clock cycles
I do not understand where the 12 comes from? Is this the number of milliseconds delay you want??
If you want 12 milliseconds then you must turn the pulse on for 12000 clock cycles for a 4 Mhz oscillator
So 12 Milliseconds = 12*1000 = 12000 clock cycles
The question is how do you measure your 1000 clock cycles? I presume that is what your procedure
delay_cyc(4) will do.
Will delay_cyc(4) = 1000 clock cycles = 1000 usec?? = 1 millisecond??
If delay_cyc(4) = 1000 clock cycle delays then I think your code should read something like this for what ever language you are using:
Counter : variable
Repeat
delay_cyc(4) ;Delay 1000 clock cycles or 1 millisecond
inc(counter) ;Increment counter after 1 millisecond
until Counter = 12;when counter = 12 then 12*1000 clock cycles = 12 milliseconds
Again, that is if I understand what you are trying to accomplish and if delay_cyc(4) will give 1000 usec delay
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered
Matthews, NC USA
Rv-6A N494BW Rotary Powered
Delay_Cyc(4)=1ms ???
hello,
thanks for your help! 12 ms is for example! I understand more better timing problem with pic now!
In fact to do 1000 cycles and make 1 ms you must put Delay_Cyc(100) and not Delay_Cyc(4)!
Well i test it tomorrow and tell you the result!
See MB manual:
Delay_Cyc
Prototype void Delay_Cyc(unsigned Cycles_div_by_10);
Returns Nothing.
Description Creates a delay based on MCU clock. Delay lasts for 10 times the input parameter in MCU cycles.
Note that Delay_Cyc is library function rather than a built-in routine; it is presented in this topic for the sake of convenience.
Requires Nothing.
Example Delay_Cyc(10); /* Hundred MCU cycles pause */
Best regards and Thanks for all your time
thanks for your help! 12 ms is for example! I understand more better timing problem with pic now!
In fact to do 1000 cycles and make 1 ms you must put Delay_Cyc(100) and not Delay_Cyc(4)!
Well i test it tomorrow and tell you the result!
See MB manual:
Delay_Cyc
Prototype void Delay_Cyc(unsigned Cycles_div_by_10);
Returns Nothing.
Description Creates a delay based on MCU clock. Delay lasts for 10 times the input parameter in MCU cycles.
Note that Delay_Cyc is library function rather than a built-in routine; it is presented in this topic for the sake of convenience.
Requires Nothing.
Example Delay_Cyc(10); /* Hundred MCU cycles pause */
Best regards and Thanks for all your time
Delay_
I am not aware of that procedure. I will have to check MB. Thanks for the tip.
Sounds to me that you have found what you need.
Good Luck with the rest of your project
Sounds to me that you have found what you need.
Good Luck with the rest of your project
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered
Matthews, NC USA
Rv-6A N494BW Rotary Powered
Tach
I am not certain which code for Tach you are referring to. However, in the MB code shown, assuming PW is a global variable and represents the RPM. So I would think if you added an line of code in the "REPEAT" loop something like the following:
If PW>=1500 then Flag := 1 else Flag := 0;
It should work
begin //Main part of program
Initialize_Ports;
Initialize_LCD;
Initialize_Timer_CCP;
PW := 00; // initialize timer period
Repeat //Loop forever calling CCP2_Call to determine rotation period and calculate PW
CCP2_call; //Call for Data and displayPW based on CCP2 module response to a pulse train
If PW>=1500 then Flag := 1 else Flag := 0;//ADDED CODE
until true = false;
end.
//Next is Unit
unit PW_Acq_High;
If PW>=1500 then Flag := 1 else Flag := 0;
It should work
begin //Main part of program
Initialize_Ports;
Initialize_LCD;
Initialize_Timer_CCP;
PW := 00; // initialize timer period
Repeat //Loop forever calling CCP2_Call to determine rotation period and calculate PW
CCP2_call; //Call for Data and displayPW based on CCP2 module response to a pulse train
If PW>=1500 then Flag := 1 else Flag := 0;//ADDED CODE
until true = false;
end.
//Next is Unit
unit PW_Acq_High;
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered
Matthews, NC USA
Rv-6A N494BW Rotary Powered