| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| nmeyer 
 
 
 Joined: 09 Jul 2004
 Posts: 70
 
 
 
			    
 
 | 
			
				| Using CCP1 to measure Frequency |  
				|  Posted: Mon Apr 14, 2008 8:58 pm |   |  
				| 
 |  
				| Hello, I have been looking for a way to use either CCP1 or CCP2 to measure an input frequency.  I have read several posts on this forum for doing tachometers and gathered some of the programs that other have posted.  I am trying to read a frequency of tenths of Hz up to a few kHz.  I have tried to use the code posted by PCM Programmer and others that makes the timer a 24 bit to get the lower frequencies.  My program that i have put together, seems to work well at high frequencies (tested at 1Khz to 3 kHz) however at lower frequencies i get 1hz returned quite often and ocasionally the correct value.  Below 150 hz it gives all kinds of erronous values.  Please review the code below and if anyone see errors let me know.  Compiler 4.062 PIC18F8722
 
  	  | Code: |  	  | #include <18F8722.H>
 #device adc=10
 #include <stdio.h>
 #include <math.h>
 #include <bootloader.h>
 //#fuses HSPLL, PLL3, CPUDIV1, NOWDT, PUT, BROWNOUT, NOLVP   // 12 MHz xtal
 #fuses HS, WDT, NOPUT, NOBROWNOUT, NOLVP // 20 MHz xtal
 #use delay(clock=40000000,RESTART_WDT)
 #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
 
 #priority CCP1, TIMER1
 
 //#define BytePtr(var, offset)   (char *)(&(char *)var + offset)
 #define BytePtr(var,offset)(char*)(&var+offset)
 
 #byte PIR1 = 0xF9E
 #bit  TMR1IF = PIR1.0
 
 
 int8  gc_timer1_extension = 0;
 int8  gc_capture_flag = FALSE;
 int32 g32_ccp_delta;
 
 //------------------------------------------------------
 #int_timer1
 void timer1_isr(void)
 {
 gc_timer1_extension++;
 }
 
 //------------------------------------------------------
 
 #int_ccp1
 void ccp1_isr(void)
 {
 char timer_ext_copy;
 int32 current_ccp;
 static int32 old_ccp=0;
 gc_capture_flag=TRUE;
 current_ccp=(int32)CCP_1;
 timer_ext_copy=gc_timer1_extension;
 if(TMR1IF)
 {
 if(*BytePtr(current_ccp,1)<2)
 timer_ext_copy++;
 gc_timer1_extension++;
 TMR1IF=0;
 }
 *BytePtr(current_ccp,2)=timer_ext_copy;
 g32_ccp_delta=(current_ccp>old_ccp)?current_ccp-old_ccp:current_ccp+(0x1000000-old_ccp);
 old_ccp=current_ccp;
 }
 //=======================
 void main()
 {
 int16 frequency;
 int32 current_ccp_delta;
 
 set_timer1(0);
 setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
 setup_ccp1(CCP_CAPTURE_RE);
 clear_interrupt(INT_TIMER1);  // Enable interrupts.
 enable_interrupts(INT_TIMER1);
 clear_interrupt(INT_CCP1);
 enable_interrupts(INT_CCP1);
 
 enable_interrupts(GLOBAL);
 
 gc_capture_flag=FALSE;
 
 while(1)
 {
 disable_interrupts(GLOBAL);
 current_ccp_delta = g32_ccp_delta;;
 enable_interrupts(GLOBAL);
 if(gc_capture_flag == TRUE)
 {
 //setup_timer_1(T1_DISABLED);
 
 //(int32)current_ccp_delta = second_ccp-first_ccp;
 frequency = (int16)((10000000L + (current_ccp_delta >> 1)) / current_ccp_delta);
 
 printf("%lu Hz\n\r", frequency);
 //      printf("%lu Hz, delta = %lx \n\r", frequency, current_ccp_delta);
 
 gc_capture_flag = FALSE;
 }
 
 
 delay_ms(100);
 }
 
 }
 
 | 
 |  |  
		|  |  
		| nmeyer 
 
 
 Joined: 09 Jul 2004
 Posts: 70
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 16, 2008 8:15 pm |   |  
				| 
 |  
				| i was able to get this working very well by making a few minor changes.  I can read a few hz upto at least 3Khz which is plenty for my needs.    However, i am now trying to integrate this in a much larger program and there it falls apart.  I am still investigating why.  here is the new code. 
  	  | Code: |  	  | #include <18F8722.H>
 #device adc=10
 #include <stdio.h>
 #include <math.h>
 #include <bootloader.h>
 //#fuses HSPLL, PLL3, CPUDIV1, NOWDT, PUT, BROWNOUT, NOLVP   // 12 MHz xtal
 #fuses HS, WDT, NOPUT, NOBROWNOUT, NOLVP // 20 MHz xtal
 #use delay(clock=40000000,RESTART_WDT)
 #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
 
 #priority CCP1, TIMER1
 
 #define BytePtr(var, offset)   (char *)(&(char *)var + offset)
 
 #byte PIR1 = 0xF9E
 #bit  TMR1IF = PIR1.0
 
 
 int8  gc_timer1_extension = 0;
 int8  gc_capture_flag = FALSE;
 int32 g32_ccp_delta;
 
 //------------------------------------------------------
 #int_timer1
 void timer1_isr(void)
 {
 gc_timer1_extension++;
 }
 
 //------------------------------------------------------
 
 #int_ccp1
 void ccp1_isr(void)
 {
 char timer_ext_copy;
 int32 current_ccp;
 static int32 old_ccp=0;
 gc_capture_flag=TRUE;
 current_ccp=(int32)CCP_1;
 timer_ext_copy=gc_timer1_extension;
 if(TMR1IF)
 {
 if(*BytePtr(current_ccp,1)<2)
 timer_ext_copy++;
 gc_timer1_extension++;
 TMR1IF=0;
 }
 *BytePtr(current_ccp,2)=timer_ext_copy;
 g32_ccp_delta=(current_ccp>old_ccp)?current_ccp-old_ccp:current_ccp+(0x1000000-old_ccp);
 old_ccp=current_ccp;
 }
 //=======================
 void main()
 {
 
 int16 frequency,x;
 int32 current_ccp_delta;
 
 set_timer1(0);
 setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
 setup_ccp1(CCP_CAPTURE_FE);
 clear_interrupt(INT_TIMER1);  // Enable interrupts.
 enable_interrupts(INT_TIMER1);
 clear_interrupt(INT_CCP1);
 enable_interrupts(INT_CCP1);
 
 enable_interrupts(GLOBAL);
 
 gc_capture_flag=FALSE;
 x=0;
 while(1)
 {
 disable_interrupts(GLOBAL);
 current_ccp_delta = g32_ccp_delta;;
 enable_interrupts(GLOBAL);
 if(gc_capture_flag == TRUE)
 {
 frequency = (int16)((10000000L + (current_ccp_delta >> 1)) / current_ccp_delta);
 gc_capture_flag = FALSE;
 clear_interrupt(INT_CCP1);
 }
 if(x==50000)//50000
 {
 printf("%lu Hz\n\r", frequency);
 x=0;
 }
 x=x+1;
 delay_us(10);
 }
 
 }
 
 
 
 | 
 |  |  
		|  |  
		| RLScott 
 
 
 Joined: 10 Jul 2007
 Posts: 465
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Apr 17, 2008 5:47 am |   |  
				| 
 |  
				|  	  | nmeyer wrote: |  	  | i was able to get this working very well by making a few minor changes.  I can read a few hz upto at least 3Khz which is plenty for my needs.    However, i am now trying to integrate this in a much larger program and there it falls apart.  I am still investigating why.  here is the new code. | 
 
 Are we supposed to look at that code and guess what "falling apart" means?  Tell us exactly what your problem is if you want someone to look for a problem.
 
 Robert Scott
 Real-Time Specialties
 |  |  
		|  |  
		| nmeyer 
 
 
 Joined: 09 Jul 2004
 Posts: 70
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Apr 17, 2008 7:52 am |   |  
				| 
 |  
				| The code i posted above works as is.  I wanted to get that posted so that if anyone else was looking, they would have a "working" example.  At the time of my post i had added this code into a much larger program and i am having issues with it not reporting a frequency that is anywhere close to what it should be.  I have not posted any code from that program, as i am investigating it to see if i can solve it.  If not, i will post new information. Thanks
 |  |  
		|  |  
		|  |  
  
	| 
 
 | You cannot post new topics in this forum You cannot reply to topics in this forum
 You cannot edit your posts in this forum
 You cannot delete your posts in this forum
 You cannot vote in polls in this forum
 
 |  
 Powered by phpBB © 2001, 2005 phpBB Group
 
 |