| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| jpos99 
 
 
 Joined: 10 Aug 2012
 Posts: 14
 
 
 
			    
 
 | 
			
				| PWM center-alignment |  
				|  Posted: Mon May 20, 2013 11:08 am |   |  
				| 
 |  
				| Hello everyone, 
 I'm trying to generate 4 pwm signal to control a H-bridge, but I want them to be center alignment to create a dead time to the bridge output by making the time of one of the igbt a bit longer, so it can desaturate the transformer that I have on the output of the bridge.
 
 So far I can put a PWM in complementary mode working fine with an analog input to change my duty-cycle.
 
 
  	  | Code: |  	  | #include <18f4431.h>
 #device *=16
 #device adc=10
 #fuses INTRC_IO, NOWDT, NOLVP, BROWNOUT
 #use delay(clock=8M)
 #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
 
 void main()
 {
 int freq;
 long int adc_val, period;
 
 freq = 10000;
 
 period = ((2000000/freq)-1)/4;  // having problems here not doing the correct math :)
 
 
 setup_power_pwm_pins(PWM_COMPLEMENTARY,PWM_OFF,PWM_OFF,PWM_OFF);
 //PPWM channels 0 and 1 are both on and always opposite values
 setup_power_pwm(PWM_CLOCK_DIV_4|PWM_FREE_RUN,1,0,period,0,1,12);
 //add dead time for reactive loads
 
 setup_adc_ports(sAN0);
 setup_adc(ADC_CLOCK_INTERNAL | ADC_CONT_A | ADC_WHEN_PPWM);
 set_adc_channel(0);
 
 while(true)
 {
 delay_us(10);
 adc_val = read_adc();
 set_power_pwm0_duty(adc_val*9);
 
 }
 }
 | 
 
 
 |-----------|
 1.............2
 |--o1  o2--|
 3.............4
 |-----------|
 
 
 
 What I want to do is:
 -Turn on 1 and 4
 -1/2 Period
 -Turn off 1
 -Delay 1us for example
 -Turn off 4
 -Dead time
 -Turn on 2 and 3
 -1/2 Period
 -Turn off 3
 -Delay 1us for example
 -Turn off 2
 -Dead time
 
 Repeat this cycle.
 
 What I can't implement is the center alignment in the CCS code or must I go to ASM to configure the bytes one by one?
 
 This is the new code I'm doing but no signal on the oscilloscope, The signal is 25kHz 50 duty for now.
 
 
  	  | Code: |  	  | #include <18f4431.h>
 #device *=16
 #device adc=10
 #fuses INTRC_IO, NOWDT, NOLVP, BROWNOUT
 #use delay(clock=4M)
 
 #byte PTCON0   =0xF7F
 #byte PTCON1   =0xF7E
 #byte PWMCON0   =0xF6F
 #byte PWMCON1   =0xF6E
 #byte DTCON      =0xF6D
 #byte OVDCOND   =0xF6B
 #byte OVDCONS   =0xF6A
 #byte FLTCONFIG =0xF6C
 #byte PTMRH      =0xF7C
 #byte PTMRL      =0xF7D
 #byte PTPERL   =0xF7B
 #byte PTPERH   =0xF7A
 #byte TRISB      =0xF93
 
 void main(){
 
 TRISB       =0;
 PTCON0      =0b00000100;
 PTCON1      =0b11000000;
 PWMCON0      =0b00110011;
 PWMCON1      =0b00000001;
 OVDCOND      =0b00001111;
 OVDCONS      =0b00000000;
 FLTCONFIG    =0b00000000;
 
 while (true){
 
 PTMRH    = 0b00001000;
 PTMRL    = 0b00110111;
 PTPERL    = 0b11111111;
 PTPERH    = 0b00001111;
 DTCON   = 0b00001101;
 
 }
 }
 
 | 
 
 The duty-cycle I don't understand how to code it.
 
 I'm using a PIC18F4431 and CCS compiler 4.093.
 
 Thanks to you all.
 |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon May 20, 2013 11:59 am |   |  
				| 
 |  
				|  	  | Quote: |  	  | void main(){ 
 TRISB       =0;
 PTCON0      =0b00000100;
 PTCON1      =0b11000000;
 PWMCON0      =0b00110011;
 PWMCON1      =0b00000001;
 OVDCOND      =0b00001111;
 OVDCONS      =0b00000000;
 FLTCONFIG    =0b00000000;
 | 
 In PTCON0, you have both of the bottom bits (PTMOD1 and PTMOD0)
 set = 0.  The data sheet says that setting those bits to 00 will enable
 Free Running mode:
 
  	  | Quote: |  	  | bit 1-0 PTMOD<1:0>: PWM Time Base Mode Select bits
 
 11 = PWM time base operates in a Continuous Up/Down Count mode with interrupts for double PWM
 updates
 10 = PWM time base operates in a Continuous Up/Down Count mode
 01 = PWM time base configured for Single-Shot mode
 00 = PWM time base operates in a Free-Running mode
 | 
 
 
 The 18F4431 data sheet says on page 177:
 
  	  | Quote: |  	  | The Continuous Up/Down Count modes produce center-aligned PWM generation.
 | 
 
 This means you should set those two bits to either 11 or 10.
 
 If you set the bits to 11, there are some erratas on it:
 http://ww1.microchip.com/downloads/en/DeviceDoc/80192c.pdf
 It's probably best if you use the 10 setting.
 |  |  
		|  |  
		| jpos99 
 
 
 Joined: 10 Aug 2012
 Posts: 14
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon May 20, 2013 4:21 pm |   |  
				| 
 |  
				| Thank you PCM Programmer 
 I've tried the change that you mentioned but still no signal.
 Is the rest correct. The period is well configured, because I've had some difficulties on understanding the "Time base" and "Period".
 
 Can I with the CCS configure these signals? (Meaning can I use the setup_power_pwm(...))
 
 Thanks again.
 
 Tomorrow I will run more tests.
 |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 21, 2013 1:24 am |   |  
				| 
 |  
				| I got center-aligned PWM working with compiler vs. 4.141.  I didn't try it with any other version yet.    To see it working, put your Channel 1
 scope probe on Pin D7 and sync on that channel.  Then put your Ch.2
 probe on pin B0, or on pin B1.    Channel 1 shows, roughly, the PWM
 Timer status.  You're looking at the PWM "cell" or time period.
 
 Then when you look at pins B0 and B1 (which are complements of each
 other, because we're running the PWM in Complementary mode) you
 will see that when the duty cycle changes, it changes equally on both
 sides of the PWM pulse.  This demonstrates it is running in center-aligned
 mode.   If it was in normal "Free Run" mode, only one side of the pulse
 would move when the duty cycle is changed.
 
  	  | Code: |  	  | #include <18F4431.h>
 #fuses HS,NOWDT,PUT,BROWNOUT,NOLVP
 #use delay(clock=20M)
 
 // Note: The following numbers work with a 20 MHz oscillator frequency.
 #define POWER_PWM_PERIOD 249  // Gives 10 KHz pwm freq with PWM_CLK_DIV_4
 #define DEAD_TIME  2    // Gives dead time of 1.6 usec
 
 
 // In the Up/Down Counting mode (Center-Aligned mode)
 // an interrupt occurs each time the value of the PTMR
 // register becomes zero and the PWM time base begins
 // to count upwards.
 //
 // The PWMTB interrupt latency and interrupt handler
 // overhead are at least 6 usec (at 20 MHz), so you
 // see an edge on Pin D7 at least 6 usec after the
 // middle of the center-aligned pulse.  The purpose
 // of this interrupt is so you can sync on Pin D7
 // with your scope, and then look at the PWM output
 // on pins B0 and B1.  You can then see the PWM
 // pulses expand or contract equally on both sides
 // of the pulse as it switches between 40% and 60%
 // duty cycle.  This shows that it's doing center-
 // aligned PWM.
 #int_pwmtb
 void pwmtb_isr(void)
 {
 output_toggle(PIN_D7);
 }
 
 //=======================================
 void main()
 {
 // Setup PWM0 and PWM1 pins as complementary PWM outputs.
 // All other PWM pins are configured as OFF (not used).
 setup_power_pwm_pins(PWM_COMPLEMENTARY, 0, 0, 0);
 
 // Mode = Up/Down Count
 // Postscale = 1   (1-16) Timebase output postscaler
 // TimeBase = 0    (0-65355) Initial value of PWM Timebase
 // Period = 249    (0-4095) Max value of PWM TimeBase
 // Compare = 0     (Timebase value for special event trigger)
 // Compare Postscale = 1 (Postscaler for Compare value)
 // Dead Time = 2
 setup_power_pwm(PWM_UP_DOWN | PWM_CLOCK_DIV_4 |  PWM_DEAD_CLOCK_DIV_16, 1, 0, POWER_PWM_PERIOD, 0, 1, DEAD_TIME);
 
 // Enable PWM Timebase interrupts.
 clear_interrupt(INT_PWMTB);
 enable_interrupts(INT_PWMTB);
 enable_interrupts(GLOBAL);
 
 // Change the duty cycle every 1/2 second, as a demonstration.
 while(1)
 {
 // The last value in this line gives a 40% duty cycle.
 set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * .4));
 delay_ms(500);
 
 // The last value in this line gives a 60% duty cycle.
 set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * .6));
 delay_ms(500);
 }
 
 }
 | 
 |  |  
		|  |  
		| jpos99 
 
 
 Joined: 10 Aug 2012
 Posts: 14
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu May 23, 2013 7:47 am |   |  
				| 
 |  
				| Thanks again PCM Programmer, 
 The code that you post works fine
  and I've made some changes. 
 
  	  | Code: |  	  | #include <18F4431.h>
 #fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
 #use delay(clock=8M)
 
 // Note: The following numbers work with a 8 MHz oscillator frequency.
 #define POWER_PWM_PERIOD 40  // Gives 25 KHz pwm freq with PWM_CLK_DIV_4
 //#define DEAD_TIME  8
 
 
 void main()
 {
 float adc_val;
 // Setup pins as ODD ON PWM outputs.
 
 setup_power_pwm_pins(PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON);
 
 // Mode = Up/Down Count
 // Postscale = 1   (1-16) Timebase output postscaler
 // TimeBase = 0    (0-65355) Initial value of PWM Timebase
 // Period = 40    (0-4095) Max value of PWM TimeBase
 // Compare = 0     (Timebase value for special event trigger)
 // Compare Postscale = 1 (Postscaler for Compare value)
 // Dead Time
 setup_power_pwm(PWM_UP_DOWN | PWM_CLOCK_DIV_4 |  PWM_DEAD_CLOCK_DIV_2, 1, 0, POWER_PWM_PERIOD, 0, 1, 0);
 
 // Enable PWM Timebase interrupts.
 //clear_interrupt(INT_PWMTB);
 //enable_interrupts(INT_PWMTB);
 //enable_interrupts(GLOBAL);
 
 setup_adc_ports(sAN0);   //continuously sample and sync with PPWM
 setup_adc(ADC_CLOCK_INTERNAL | ADC_CONT_A | ADC_WHEN_PPWM);
 set_adc_channel(0);
 
 // Change the duty cycle every 1/2 second, as a demonstration.
 while(1)
 {
 delay_us(1);
 adc_val = read_adc();
 
 // The last value in this line gives a variable duty cycle given by a analog signal.
 set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * (adc_val/255)));
 set_power_pwm2_duty((int16)((POWER_PWM_PERIOD *4) * (adc_val/255)));
 set_power_pwm4_duty((int16)((POWER_PWM_PERIOD *4) * (adc_val/240)));
 set_power_pwm6_duty((int16)((POWER_PWM_PERIOD *4) * (adc_val/240)));
 
 }
 }
 | 
 
 With this I have 4 PWM signal and 2 of them are +/- 500ns longer and center align.
 
 But now I've realized that this is not quite what I was after
  . I need to have 2 PWM signals with the same frequency but they are delayed T/2. As the code but one of the signals just happens half a period later with the same duty cycle.
 Can I use the trigger to go to a interrupt and execute another pwm signal? This said do I have to setup another power pwm?
 
 Thanks to all.
 |  |  
		|  |  
		| jpos99 
 
 
 Joined: 10 Aug 2012
 Posts: 14
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu May 23, 2013 10:51 am |   |  
				| 
 |  
				| PCM Programmer, 
 I've been reading the PIC18F4431, and for what I read the Power PWM module is synchronous.
 
 So what I want to do can not be done directly. I manage to do it with some signal manipulation and some values changes, but for some duty cycles the values change abruptly.
 When I have the final solution or if I'm stuck again I post it here.
 
 If you have any suggestion please feel free.
 
 Thanks again all.
 |  |  
		|  |  
		| jpos99 
 
 
 Joined: 10 Aug 2012
 Posts: 14
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri May 24, 2013 3:37 am |   |  
				| 
 |  
				| Hi, 
 I've been reading and came across these image that controls the bridge like I want.
 
 https://www.dropbox.com/s/2ktm2i0ngvphfpm/signals.jpg
 
 
 Can anyone help me, because I'm not understanding one thing if the Power PWM is synchronous how can I delay one of the signals S3? Its by changing the time base value?
 
 Thanks all
 |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri May 24, 2013 10:57 am |   |  
				| 
 |  
				| Post a link to the full web page where you got that timing diagram from. |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |