| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| tienchuan 
 
 
 Joined: 25 Aug 2009
 Posts: 175
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Wed Nov 13, 2013 8:42 am |   |  
				| 
 |  
				| Thanks Ttelmah. 
  	  | Code: |  	  | (ccp_delta *( 1/(10MHz)*(4*8*1000) ) ) | 
 Yes, It it's a remark.
 In my project change use crystal 10MHZ so that I must calcualtor this constant.
 Oh,I thought failure,, I'm careless when using division to change the code, because I always think division math is slower than multiplication. You pls show me way to calculate time for math operation.
 Added, when i test with this code, it has return value when i disconnect pulse clock in CCP1 pin, If true, it must no return value,so that I think need to clear int_ccp1 flag?
 
 here is my full code I changed flow your idea:
 
 
  	  | Code: |  	  | #include <16F877A.h>
 #fuses HS, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
 #use delay(clock=10000000)
 #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
 
 int8 capture_falling_edge;
 int8 got_pulse_width;
 int16  ccp_delta;
 
 
 #int_ccp1
 void ccp1_isr(void)
 {
 static int16 t1_falling_edge;
 
 // If current interrupt is for falling edge.
 if(capture_falling_edge)
 {
 setup_ccp1(CCP_CAPTURE_RE);
 capture_falling_edge = FALSE;
 t1_falling_edge = CCP_1;
 }
 else
 {
 setup_ccp1(CCP_CAPTURE_FE);
 capture_falling_edge = TRUE;
 ccp_delta = CCP_1 - t1_falling_edge;
 got_pulse_width = TRUE;
 }
 
 }
 
 //====================================
 main()
 {
 int16 pulse_width_ms;
 int16 local_ccp_delta;
 
 got_pulse_width = FALSE;
 capture_falling_edge = TRUE;
 
 setup_ccp1(CCP_CAPTURE_FE);
 setup_timer_1(T1_INTERNAL | T1_DIV_BY_8 );
 enable_interrupts(INT_CCP1);
 enable_interrupts(GLOBAL);
 
 while(1)
 {
 if(got_pulse_width)
 {
 disable_interrupts(GLOBAL);
 local_ccp_delta = ccp_delta;
 enable_interrupts(GLOBAL);
 
 pulse_width_ms = (local_ccp_delta * 32) /10000 ;
 printf("%lu ms \n\r", pulse_width_ms);
 }
 delay_ms(500);
 
 }
 
 }
 
 
 | 
 _________________
 Begin Begin Begin !!!
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Nov 13, 2013 9:22 am |   |  
				| 
 |  
				| It's not INT_CCP1 that is causing it to display with no input. You are not clearing the flag 'got_pulse_width' when you print. 
  	  | Code: |  	  | while(1)
 {
 if(got_pulse_width)
 {
 disable_interrupts(GLOBAL);
 local_ccp_delta = ccp_delta;
 enable_interrupts(GLOBAL);
 got_pulse_width=FALSE;   //need this or it'll keep printing....
 
 pulse_width_ms = (local_ccp_delta * 32) /10000 ;
 printf("%lu ms \n\r", pulse_width_ms);
 }
 delay_ms(500);
 }
 
 | 
 On times, CCS has a table in the manual 'how much time do maths operations take', which can be scaled for different clock rates, but the simplest solution is to just use a pulse output and time the actual duration, or use the stopwatch feature in MPLAB.
 
 There is one problem with *32/10000. The result of *32, won't fit in an int16, so for longer times, the values out the top will be lost (65mSec max). If this matters you'll need to cast to an int32.
 
 Best Wishes
 |  |  
		|  |  
		| tienchuan 
 
 
 Joined: 25 Aug 2009
 Posts: 175
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Wed Nov 13, 2013 8:34 pm |   |  
				| 
 |  
				| Thanks u, Ttelmah. Well, It worked
   But it seem has error when i disconnect pulse in CCP1, It has return value???
 And is here my code edited follow your comment:
 
 
  	  | Code: |  	  | #include <16F877A.h>
 #fuses HS, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
 #use delay(clock=10000000)
 #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
 
 int8 capture_falling_edge;
 int8 got_pulse_width;
 int32  ccp_delta;
 
 
 #int_ccp1
 void ccp1_isr(void)
 {
 static int16 t1_falling_edge;
 
 // If current interrupt is for falling edge.
 if(capture_falling_edge)
 {
 setup_ccp1(CCP_CAPTURE_RE);
 capture_falling_edge = FALSE;
 t1_falling_edge = CCP_1;
 }
 else
 {
 setup_ccp1(CCP_CAPTURE_FE);
 capture_falling_edge = TRUE;
 ccp_delta = CCP_1 - t1_falling_edge;
 got_pulse_width = TRUE;
 }
 
 }
 
 //====================================
 main()
 {
 int32 pulse_width_ms;
 int32 local_ccp_delta;
 
 got_pulse_width = FALSE;
 capture_falling_edge = TRUE;
 
 setup_ccp1(CCP_CAPTURE_FE);
 setup_timer_1(T1_INTERNAL | T1_DIV_BY_8 );
 enable_interrupts(INT_CCP1);
 enable_interrupts(GLOBAL);
 
 while(1)
 {
 if(got_pulse_width)
 {
 disable_interrupts(GLOBAL);
 local_ccp_delta = ccp_delta;
 enable_interrupts(GLOBAL);
 
 got_pulse_width= FALSE;
 
 pulse_width_ms = (local_ccp_delta * 32) /10000;
 printf("%lu ms \n\r", pulse_width_ms);
 }
 
 delay_ms(500);
 
 }
 
 }
 
 
 | 
 Thanks u so much.
 _________________
 Begin Begin Begin !!!
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Nov 14, 2013 1:28 am |   |  
				| 
 |  
				| No pulse = line floating (unless you have arranged a pull-up resistor). May start picking up RF/mains interference.... 
 Best Wishes
 |  |  
		|  |  
		| tienchuan 
 
 
 Joined: 25 Aug 2009
 Posts: 175
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Sat Nov 16, 2013 8:05 pm |   |  
				| 
 |  
				| Well, I worked exactly:) I  added config in main code:
 
 
 Follow instructions in datasheet:
 
  	  | Quote: |  	  | If the RC2/CCP1 pin is configured as an output, a write to the port can cause a Capture condition | 
 Thanks u very much
  _________________
 Begin Begin Begin !!!
 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |