| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| AlbertCharles 
 
 
 Joined: 15 Sep 2023
 Posts: 13
 
 
 
			      
 
 | 
			
				| ex_use_capture.c -  capture of a semi-cycle Pulse Width |  
				|  Posted: Tue Aug 13, 2024 5:09 pm |   |  
				| 
 |  
				| Hi Guys! 
 i'm using a ex_use_capture.c - PIC16F877A -Ccs PCM 5.115
 
 Second:   4935.6
 First:    4459.2
 Second-First= Period:    476.4 us
 
 Second:   7107.2
 First:    6630.8
 Second-First= Period:    476.4 us
 
 
 Second: 10231.4
 First:   9755.0
 Second-First= Period:    476.4 us
 
 I created fixed pulse train through scope's pulse generator, like this:
 
 // sorry about figure...
 _ _ _ _
 |            |  |
 |            |  |
 |            |  |
 |            |_|
 
 <------->  476.4 us = perĂod
 
 In the scope,  i read the HIGH pulse at ~433us and LOW pulse at ~43us.
 Boths add up ~476.4us. Its correct.
 But the problem is that I need to know the exact value of each high and low pulse.
 The variables that capture these values in the program receive variant values, as I published above. Why?
 
 I appreciate and appreciate any help, as I've been at this for 15 days Thanks.
 
 Below is the program:
 
 ---------------------------------------------------------------------------------
 
 #include <16F877A.h>
 #fuses HS, NOWDT, BROWNOUT, PUT, NOLVP
 #use delay(crystal=20MHz)
 
 #define GENERATE_PWM_SIGNAL
 #define RS232_XMIT     PIN_C6
 #define RS232_RCV      PIN_C7
 #define CAPTURE_PIN    PIN_C2
 #define CAPTURE_TIMER  1
 
 
 #define PWM_PIN       PIN_C1
 #define PWM_TIMER     2
 #define __CCS_USE_TIMER_PERIPH 0
 
 #use rs232(xmit=RS232_XMIT, rcv=RS232_RCV, baud=9600) //Text through the UART
 #use capture(input=CAPTURE_PIN,timer=CAPTURE_TIMER, CAPTURE_FALLING)
 
 #ifdef GENERATE_PWM_SIGNAL
 #use pwm(output=PWM_PIN, timer=PWM_TIMER, frequency=2kHz, duty=50)
 
 #define TICK_IS_16BITS
 #include <tick.c>
 
 #define GetTickDifference(a,b) (a-b)
 #endif
 
 #if getenv("INSTRUCTION_CLOCK") >= 1000000
 #define PERIOD_DIVISOR    (getenv("INSTRUCTION_CLOCK") / 1000000)
 #else
 #define PERIOD_DIVISOR    1
 #endif
 
 unsigned int16 FirstCapture, SecondCapture;
 int1 NewCapture = FALSE;
 
 #INT_CCP1
 
 void Capture_Interrupt(void)
 {
 static int1 First = TRUE;
 unsigned int16 dummy;
 
 if(!NewCapture)
 {
 if(First)
 FirstCapture = get_capture_time();     //Read first capture event.
 else
 {
 SecondCapture = get_capture_time();   //Read second capture event.
 NewCapture = TRUE;
 }
 
 First++;
 }
 else
 dummy = get_capture_time();
 }
 
 #define GetCaptureDifference(a,b)   (b-a)
 
 #ifdef GENERATE_PWM_SIGNAL
 //The following are values used to generate 6 different PWM signals for
 //the Capture to measure.  The periods are 500us, 333.3us, 250us, 125us,
 //62.5us, 31.2us.
 //obs: i'm not using
 unsigned int32 PwmFrequency[6] = {2000, 3000, 4000, 8000, 16000, 32000};
 
 #endif
 
 void main()
 {
 #ifdef GENERATE_PWM_SIGNAL
 TICK CurrentTick, PreviousTick;
 #endif
 unsigned int16 Time,Time1;
 unsigned int8 i = 0;
 
 printf("\n\rex_use_captur.c - %s\n\n\r", getenv("DEVICE"));
 
 //enable the Capture interrupt
 enable_interrupts(INT_CCP1);
 enable_interrupts(GLOBAL);
 
 #ifdef GENERATE_PWM_SIGNAL
 PreviousTick = CurrentTick = TickGet();
 #endif
 
 while (TRUE)
 {
 #ifdef GENERATE_PWM_SIGNAL
 CurrentTick = TickGet();
 
 // obs: i'm not using......
 if(GetTickDifference(CurrentTick, PreviousTick) >= (5*TICKS_PER_SECOND))  //change PWM period every 5 seconds
 {
 if(++i >= 6)
 i = 0;
 
 pwm_set_frequency(PwmFrequency[i]);
 pwm_set_duty_percent(500);
 
 PreviousTick = CurrentTick;
 }
 
 #endif
 
 if(NewCapture)
 {
 Time = GetCaptureDifference(FirstCapture, SecondCapture);
 
 printf("Second: %8.1w us\n", ((unsigned int32)SecondCapture * 10) / PERIOD_DIVISOR);
 printf("First: %8.1w us\n", ((unsigned int32)FirstCapture * 10) / PERIOD_DIVISOR);
 
 printf("Period: %8.1w us", ((unsigned int32)Time * 10) / PERIOD_DIVISOR);
 
 NewCapture = FALSE;
 delay_ms(5000);
 }
 }
 }
 |  |  
		|  |  
		| gaugeguy 
 
 
 Joined: 05 Apr 2011
 Posts: 350
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Aug 14, 2024 6:15 am |   |  
				| 
 |  
				| Your code is currently capturing every rising edge of the signal.  If you want to measure the time high or time low you will need to capture both the rising edge and the falling edge. You can either switch the CCP mode in each interrupt or set one CCP for rising capture and the other CCP for falling capture.
 |  |  
		|  |  
		| AlbertCharles 
 
 
 Joined: 15 Sep 2023
 Posts: 13
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Wed Aug 14, 2024 7:35 am |   |  
				| 
 |  
				| Okay, thanks for your areply. I added the following lines after the line 120 if (v==0)
 {
 setup_ccp1(CCP_CAPTURE_RE);
 v=1;
 }
 else
 {
 setup_ccp1(CCP_CAPTURE_FE);
 v=0;
 }
 and the result was only the period reading changed, starting now with the rising edge and now with the falling edge. But the main thing is to obtain only the value of the high time, separate from the low time. I don't need the period, but each separate semicycle.
 |  |  
		|  |  
		| gaugeguy 
 
 
 Joined: 05 Apr 2011
 Posts: 350
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Aug 14, 2024 8:29 am |   |  
				| 
 |  
				| A full cycle has three time readings, not just two. Rising edge, falling edge, & rising edge
 or falling edge, rising edge, & falling edge.
 |  |  
		|  |  
		| AlbertCharles 
 
 
 Joined: 15 Sep 2023
 Posts: 13
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Wed Aug 14, 2024 9:25 am |   |  
				| 
 |  
				| So, based on your answer, I say that I need to know the time (us) in which the high pulse was active, and then, the time (us) in which the low pulse was active. That's the real problem.Do you have any suggestions via code? |  |  
		|  |  
		| gaugeguy 
 
 
 Joined: 05 Apr 2011
 Posts: 350
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Aug 14, 2024 9:37 am |   |  
				| 
 |  
				| I am not giving you code, just some direction. 
 capture a rising edge, save as Rising1
 capture a falling edge, save as Falling1
 capture a rising edge, save as Rising2
 
 time high = Falling1 - Rising1
 time low = Rising2 - Falling1
 |  |  
		|  |  
		| temtronic 
 
 
 Joined: 01 Jul 2010
 Posts: 9589
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Aug 14, 2024 12:19 pm |   |  
				| 
 |  
				| If CCS doesn't have an example, I KNOW there's a chapter devoted to 'how-to-do-it in the Microchip databook,though actual code will be in Assembler, converting to C is easy. |  |  
		|  |  
		| AlbertCharles 
 
 
 Joined: 15 Sep 2023
 Posts: 13
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Wed Aug 14, 2024 5:24 pm |   |  
				| 
 |  
				| In the future I can try to convert, but today, in ccs, I would recover my time, as I have been in this fight for 15 days. If u have something in C, it would help me a lot. |  |  
		|  |  
		| temtronic 
 
 
 Joined: 01 Jul 2010
 Posts: 9589
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Aug 15, 2024 12:09 pm |   |  
				| 
 |  
				| to add to gaugeguy's post.. if you reset( zero) the timer's 'count' register before the 1st rising edge detection.you'll see better numbers, providing you don't overflow( exceed the max count )
 |  |  
		|  |  
		| AlbertCharles 
 
 
 Joined: 15 Sep 2023
 Posts: 13
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Thu Aug 15, 2024 12:55 pm |   |  
				| 
 |  
				| At lunch time I was meditating.. thinking about this hypothesis.. I will test it and report back here. 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
 
 |