| View previous topic :: View next topic | 
	
	
		| Author | Message | 
	
		| hubble 
 
 
 Joined: 11 Dec 2006
 Posts: 10
 
 
 
			      
 
 | 
			
				| !!! Help me with PWM !!! |  
				|  Posted: Sat Sep 13, 2008 9:15 am |   |  
				| 
 |  
				| How can I get next graphs? 1. on CCP1 - PWM in odd period;
 2. on CCP2 - PWM in even period.
 
 Graphic and code below:
 
  	  | Code: |  	  | CCP1  _|''''|________________________|''''|______________
 
 CCP2  _______________|''''|__________________________|''''|___
 |              |               |               |
 |              |               |               |
 |<-1st period->|<-2nd period-> | <-3rd period->|
 
 | 
 
 
 
  	  | Code: |  	  | #include <16F886.h> #device  ADC=10
 #fuses HS,NOWDT,BROWNOUT,PUT,NOLVP
 #use delay (clock=4000000)
 
 #define PR2  49   // 20kHz
 
 //!#byte PWM1CON = 0x9B
 #byte CCP1CON = 0x17
 #byte CCP2CON = 0x1D
 
 int16 currentDuty;
 
 //=================================
 #int_timer2
 void Interrupt_RTCC()
 {
 int8 changeCCP;
 
 changeCCP^=1;
 if(changeCCP)
 set_pwm1_duty(currentDuty);
 else
 set_pwm2_duty(currentDuty);
 }
 //=================================
 void main()
 {
 int16 oldDuty;
 
 enable_interrupts(GLOBAL);
 enable_interrupts(INT_TIMER2);
 setup_port_a(ALL_ANALOG);
 setup_adc(adc_clock_internal);
 set_adc_channel(0);
 set_tris_b(0xff);
 set_tris_c(0xff);
 CCP1CON=0b00101100;
 CCP2CON=0b00101100;
 //!PWM1CON=0b00000010;
 setup_timer_2(T2_DIV_BY_1,PR2,1);
 set_tris_b(0);
 set_tris_c(0);
 output_c(0);
 
 while(1)
 {
 currentDuty=read_adc();
 
 if (oldDuty!=currentDuty){
 currentDuty=currentDuty*(PR2+1)/255;
 //!         set_pwm1_duty(currentDuty);
 //!         set_pwm2_duty(currentDuty);
 oldDuty=currentDuty;
 }
 delay_ms(10);
 }
 }
 | 
 It works, but not what I wanted
   Help me with question.
 
 Thank beforehand.
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 |  | 
	
		|  | 
	
		| Guest 
 
 
 
 
 
 
 
			
			
			
			
			
			
			
			
			
 
 | 
			
				|  |  
				|  Posted: Sat Sep 13, 2008 3:34 pm |   |  
				| 
 |  
				| Thank you PCM programmer. It works.
 But if I change the next variable
 
 #define PWM_PERIOD      1000L
 #define PULSE_ON_TIME    250L
 
 to (for example)
 
 #define PWM_PERIOD      1000L
 #define PULSE_ON_TIME   50L
 
 or to (for example too)
 
 #define PWM_PERIOD       250L
 #define PULSE_ON_TIME   150L
 
 then I have bad (very bad) graphs on me oscilloscope.
 
 What`s wrong?
 Can you help me again?
 |  | 
	
		|  | 
	
		| RLScott 
 
 
 Joined: 10 Jul 2007
 Posts: 465
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Sep 13, 2008 7:00 pm |   |  
				| 
 |  
				|  	  | Anonymous wrote: |  	  | ...But if I change the next variable 
 #define PWM_PERIOD      1000L
 #define PULSE_ON_TIME    250L
 
 to (for example)
 
 #define PWM_PERIOD      1000L
 #define PULSE_ON_TIME   50L
 
 | 
 50 is probably too short for the interrupt service routine.
 
 
  	  | Quote: |  	  | 
 or to (for example too)
 
 #define PWM_PERIOD       250L
 #define PULSE_ON_TIME   150L
 
 | 
 
 This leaves pulse_off_time equal to 100, which might also be too short for the interrupt service routine.
 
 One way to speed up the interrupt service routine from the one posted in the referenced thread is to replace the setup_ccp1 and setup_ccp2 functions with a single bit setting or bit clearing instruction that does the same thing.
 _________________
 Robert Scott
 Real-Time Specialties
 Embedded Systems Consulting
 |  | 
	
		|  | 
	
		|  |