Reader Mo Hsen wrote in with an interesting query about generating PWM output from the dsPIC30F4011 on two channels with equal duty cycle but 180 degrees out of phase (see the waveforms below for an example). I’ve created a short sample program (for the C30 compiler) which is included in full below. Mo needs the PWM frequency to be 25kHz, so I’m running at the highest clock speed possible with the internal RC oscillator and I’ve set the PWM prescaler to a ratio of 1:1 in order to achieve fine-grained control of the pulse timing.
The basic approach is as follows:
- Enable up-down counting for centre-aligned PWM (“_PTMOD = 0b10;”).
- Enable PWM channels 1 and 2 in complementary mode (“PWMCON1 = 0b00110011;”).
- Set your PWM period as normal (e.g. “_PTCKPS = 0; PTPER = 600”).
- Then, whenever you set the pulse width on channel 1, you set the pulse width on channel 2 to be the opposite, i.e. “PDC2 = (2*PTPER )- PDC1;”. In my example below, I’ve phrased this slightly differently, but basically the idea is the same: if you want a duty cycle of 20%, set PDC1 for 20% and PDC2 for 80%.
- Finally, your 180 degree phase separated outputs are on PWM1H and PWM2L (pins 37 and 36 respectively).
My example program sets up this type of output, then switches back and forth indefinitely between duty cycles of 25% and 75%. Here’s are screenshots of the output waveforms on both channels for each duty cycle:
In the next screenshot, the cursors are enabled so that the period and frequency are displayed above the waveforms (40us and 25 kHz respectively). Note also that due to the high PWM frequency, I have set the sample rate to 1 MHz so that the recorded signal will not be aliased.
I’m using the following software versions:
- MPLAB IDE v8.50
- Microchip C30 Toolsuite v3.23 (free version)
- PICkit 2 Application v2.61.00
- Windows XP (service pack 3, I think)
Here’s the complete code for the program. I’m using the C30 compiler. Also, in MPLAB I have specified Configuration Bits set in code (in MPLAB’s “Configure” menu, click “Configuration Bits…” and then tick the box).
// // This is a dsPIC30F4011 program to generate PWM on two channels // simultaneously with equal duty cycle but 180 degrees out of phase. // // Written by Ted Burke // https://batchloaf.wordpress.com // Last updated 6-4-2012 // #include <libpic30.h> #include <p30f4011.h> // Configuration settings _FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, Fcy=30MHz _FWDT(WDT_OFF); // Watchdog timer off _FBORPOR(MCLR_DIS); // Disable reset pin // Function prototypes void configure_pins(); void set_pwm_duty_cycle(double duty_cycle); unsigned int read_analog_channel(int n); int main() { // Set up digital i/o, analog input, PWM, UART and interrupt configure_pins(); // Switch back and forth between 25% and 75% duty cycle while(1) { _LATD1 = 1; // LED on set_pwm_duty_cycle(0.75); // 75% duty cycle __delay32(15000000); _LATD1 = 0; // LED off set_pwm_duty_cycle(0.25); // 25% duty cycle __delay32(15000000); } return 0; } // Sets the duty cycle on PWM channels 1 & 2 void set_pwm_duty_cycle(double duty_cycle) { PDC1 = duty_cycle * (2 * PTPER); PDC2 = (1 - duty_cycle) * (2 * PTPER); } // This function sets up digital i/o, analog input, PWM, // UART and timer interrupt. void configure_pins() { // Configure all four port D pins (RD0, RD1, RD2, RD3) // as digital outputs LATD = 0; TRISD = 0b1111111111110000; // Configure all three port C pins (RC13, RC14, RC15) // as digital inputs TRISC = 0b1111111111111111; // Configure AN0-AN8 as analog inputs TRISB = 0x01FF; // All 9 port B pins are inputs ADPCFG = 0xFE00; // Lowest 9 PORTB pins are analog inputs ADCON1 = 0; // Manually clear SAMP to end sampling, start conversion ADCON2 = 0; // Voltage reference from AVDD and AVSS ADCON3 = 0x0005; // Manual Sample, ADCS=5 -> Tad = 3*Tcy ADCON1bits.ADON = 1; // Turn ADC ON // Configure PWM for free running mode // // PWM period = 2 * Tcy * prescale * PTPER = 0.66ns * 1 * PTPER // PWM pulse width = Tcy * prescale * PDC // PWMCON1 = 0b00110011; // Enable channels 1 & 2 in complementary mode PTCON = 0; _PTCKPS = 0; // prescale=1:1 (0=1:1, 1=1:4, 2=1:16, 3=1:64) _PTMOD = 0b10; // Select up-down counting for centre-aligned PWM PTPER = 600; // 25kHz in up/down counting mode PDC1 = PTPER; // 50% duty cycle on PWM channel 1 PDC2 = PTPER; // 50% duty cycle on PWM channel 2 PTMR = 0; // Clear 15-bit PWM timer counter _PTEN = 1; // Enable PWM time base } // This function reads a single sample from the specified // analog input. It should take less than 2.5us if the chip // is running at about 30 MIPS. // Because the dsPIC30F4011 has a 10-bit ADC, the value // returned will be between 0 and 1023. unsigned int read_analog_channel(int channel) { ADCHS = channel; // Select the requested channel ADCON1bits.SAMP = 1; // Start sampling __delay32(30); // 1us delay @ 30 MIPS ADCON1bits.SAMP = 0; // Start Converting while (!ADCON1bits.DONE); // Should take 12 * Tad = 1.2us return ADCBUF0; }
Finally, here are two images of the breadboard circuit I used to test the code. I took these using my phone, so unfortunately the image quality is not very good. However, the main details should hopefully be visible. Note that AVdd and AVss (pins 39 and 40) should be connected to the positive and negative supply voltages too, but I ran out of bits of wire!
Greetings mr.Ted Burke from Greece.
Your example is the only one we have tried that worked with our dsPIC30F4011 concerning the pwm and we are really happy about this.We are students at technological educational institute and would like to make an inverter using SPWM.Specifically we want to produce a pulse to drive 4 mosfets in order to get a pure sine wave.Our 1st try was to compile a source code with flowcode to make a sinus change of the duty cycle but no chance at all.We are newbies at C code and we try by our owns to find a solution to make the code works and really we have no chance.
Is there a possibility to make some additions to your source code to achieve our goal??
Thanks in advance.
Greetings mr.Ted.
Did you checked my latest reply about using your c source code and the additions i would like to make?
Hi George. I only just saw your comments this minute. I’m delighted to hear that you found my code useful, and I’ll do my best to help you solve your problem. Yes, it should be possible to make some changes to the code to produce pulses that vary their width over time in a sinusoidal fashion. I’ll have a go, but I’ll need some more details from you, such as:
1. What frequency of sinusoid do you want to produce?
2. Does the frequency of the PWM signal matter for the MOSFETs? (bearing in mind that it will certainly need to be much higher than the frequency of the sinusoid).
3. What are the maximum and minimum duty cycles that you want? In other words, what should the pulse width be at the high and low point of the sinusoid?
If you can provide this information, I’ll put together some sample code and post it on my blog.
Ted
Hello again George. I’ve just posted some sample code which I hope is similar to what you’re looking for. Here’s the link:
https://batchloaf.wordpress.com/2012/05/02/sinusoidal-variation-of-pwm-duty-cycle-with-dspic30f4011/
I set the PWM frequency to 10kHz and the sinusoidal variation to 50Hz, which I hope is appropriate, but if not I can modify it to suit your requirements. It just varies the duty cycle on PWM channel 1 (pins 37 and 38). The PWM channel is in complementary mode, so whenever one pin is high the other is low. If I’m picturing your circuit correctly, I think you may need to use the output from both pins. It’s also possible that you need to introduce some “dead time” in between one pin going low and the other going high. It’s possible to do this automatically with the dsPIC, but I’ll have to look up the datasheet to find out exactly how.
Anyway, have a look and try out the code. Let me know if it does the trick for you.
Ted
Dear Mr Burke,
Hello there. I am working on a project of making bi-directional dc dc converter,wherein i need to generate 180 degree phase shifted PWM for triggering the IGBTS. Can this same concept be used if i were to use edge triggered waveforms?
i need to trigger two legs of IGBTs ,both 180 degree phase shifted, and the upper and lower IGBT of the same leg have complementry switching. The period and the duty cycle of the IGBT remain same.
I am using dsPIC30f4011, and MPLABIDE 8.46, HI-TECH C compiler. The switching frequency is 20kHz, duty cycle remains 73 % during Boost mode and 27 % degree during Buck mode of operation.
Kindly let me know if this program can work with little addons?
Thanks in advance
Hi Jil,
I’m pretty sure it’s possible to do what you want, but I’m not 100% clear yet on the waveforms you need to produce. A few questions:
From what you’ve described so far, I suspect that it might be easier to do this using the dsPIC’s output compare pins rather than the PWM outputs. That’s not too hard though. Here are a couple of output compare example that I posted before:
Dear Mr Burke,
Thank you for your earliest reply.The answer to the questions you asked are below:
I am using four IGBTs in total,two in each leg, and the upper and lower IGBTs will work in complementary ,mode. Thus i will need four outputs, for eg if using PWM pins,i will need PWM1H,PWM1L,PWM2H,PWM2L.
By edge triggered waveform i meant sawtooth waveform, as in the above example you have used center aligned waveform. The concept is that i need to compare the sawtooth waveform with the constant 0.73 to generate the PWM pulses.
I do hae a circuit diagram and a sketch of waveforms, but i am not able to post it here. Could you please let me know how to do it so that the idea would be clear to you.
I was told that it would be difficult using output compare so i thought of using PWM motor module.
Thanking you,
jil sutaria
This link will give you the circuit diagram.
https://plus.google.com/photos/108135073972355193003/albums/5826140484845437457?authkey=CN-AuIi1pJPSKQ
Thanks Jil. I’m just writing up some example code, which I’ll post here on the blog. If you have a picture of the four waveforms you want, it would be great to see that too just in case I’m picturing the IGBT activation sequence correctly.
Regards,
Ted
Hi Jil,
I’ve just posted a first draft of some code to generate the IGBT control waveforms. It’s not complete yet, but hopefully it will give you some idea of the direction I’m going with it. if you could try compiling it and let me know how you get on, that would be great. I don’t actually have the compiler installed on this PC, so I haven’t been able to compile it myself yet. I’m using the XC16 compiler by the way, but hopefully this will compile for you without too much modification.
Here’s the link:
https://batchloaf.wordpress.com/2012/12/26/igbt-control-in-a-buck-boost-dc-dc-converter/
Ted
Hello Mr Burke,
thank you for the code.i have compiled the code and checked the output on a scope. I am not getting the phase shift.
Also i have given the link to the waveforms below the code for Buck-Boost converter.
Thanking you,
jil
HI Mr Burke,
I had look at some of your dsPic30f4011 examaples, you’ve done a great job.
I am working on a SRM drive system for my Phd project and I am interested to do “2DLinear Interpolation” by using a microprocessor which I prefer dsPic30f4011 cause I am slightly familiar with it. Could you please advice me how can I compute the time that the PIC needed to do a 2Dlinear Interpolation. The link for interpolation are below and in this stage I just need to know can I do a 2dinterpolation in less than 1mSec ( somwhere between 10usec-100usec). Or in the other hand I need to know the time that the PIC needed to Interpolate one value. Please advice me.
http://en.wikipedia.org/wiki/Bilinear_interpolation
http://en.wikipedia.org/wiki/Linear_interpolation
Regards
Mote
Please refer to linke below which explained Piecewise linear interpolation for PIC12/14/16 is maximum 137 instruction per cycle and I need this for dspic30f4011 to workout the time required for linear interpolation, cause I need to do cubic spilne interpolation which definitely needs more time than linear interpolation for latter taslk.
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en020511
I highly appreciatye your help in advance Mr Bruke
Hi Mote,
Ok, let’s consider the bilinear interpolation first.
If you can supply some more information, perhaps including more details of the application (e.g. where the input to the interpolation process is coming from and where the output value is being used) hopefully we can get a clear answer to how fast it can be done.
Under certain circumstances, it should certainly be possible to do a bilinear interpolation within 1ms (and probably within 10-100us), but the time taken could vary considerably depending on the details of the application (data types, number of fixed points, etc).
Ted
Deat Ted
Fisr I have to appologies for late reply, my grandma passed away and I went to my country for her funeral thats why I could not reply on time.
Lets clarify the points you mentioned above:
1- I have to have a two dimentional grid of points, in the case of linear interpolation the grid size will be 20 columns and 61 rows (61×20=1220) and for cubic spline interpolation the grid size will reduce to 10 columns and 21 rows (21×10=210).I need to interpolate between nearest 4 points in each calculation for bilinear interpolation.
2-For bilinear interpolation the grid size is 61Rows*20Columns=1220
3-Data type that I would like to work with is minimum 5 digit number with 4decimal points (e.c 0.0000).
4-Data type are the same for all the intyerpolation process.
5-Input to the interpolation comes from a table which is a measured value of torque of a SRM machine.
6-The outpute value will store in a table to plote the torque of the machine.
Mote
Hi Mote,
I’m very sorry to hear about your grandmother.
Thanks for the additional details on the interpolation problem. I’ll need to have a think about this and try it out for myself to measure the time taken. At first glance, I can see that the lookup table will need to be stored in program memory, since each stored value will need to be a 16-bit number, and there isn’t enough RAM in the 30F4011 to store the grid values in data memory. That shouldn’t be a problem, but I suppose it will affect the execution time in some way.
Anyway, give me a day or two to think about this and I’ll get back to you.
Ted
Hi Ted
hope you are doing well. Just wanted to remind you about the computation of the time requires for interpolation in dsPic, I really appreciate if you have any idea please let me know.
Regards
Mote
Hi ted
Hope you are safe and sound, just want to know if you have thought about the interpolation’s time and if you couldn’t please advice me how can I estimate time requires for interpolations in dsPIC30f4011
Regards
Mohsen
Hi Mote,
Sorry I haven’t responded in full yet to your query, but I just haven’t had the time to get to the bottom of it because I’ve been very busy in work and there’s a backlog of queries on my blogs that I’ve been trying to get through. I have done some research on your question and I’m hoping to perform a complete experiment over the weekend to measure some actual computation times. I’ll let you know how I get on. Once I have my code written, I’ll probably put it up as a new blog post here.
Regards,
Ted
Hi Ted
I appreciate How busy you are as you have a very usefull site. Thanks again for your great help buddy.
Regards
Mote
Hi Mote,
I’m working on the interpolation problem now. I have a question though. I was re-reading your answers to my questions above and I’m still a bit confused about the input and output of the interpolation process. You said:
…but I think maybe you might have misunderstood my question. Am I right in thinking that you’re using the interpolation process to estimate torque in the SRM? If so, I assume that the grid of values has been populated with measured values that were obtained by varying two “input” parameters (current, speed, or something else?). Presumably, in your final application, you will measure the actual values of these two parameters using some kind of sensors and then use interpolation to estimate the torque?
The reason I ask is because the “input” values for the interpolation (the two measured parameters) will need to be scaled before being used as indices to the table. This is not a problem, but it’s an extra step that needs to be factored into the computation time.
I’ll keep working on it for the time being without assuming anything specific about the two parameter value ranges.
Ted
Hello Sir, thank you for the code. I am new at dspic and so i am unable to understand the logic.If PWM1H is having 25% duty then PWM2H will have 75% duty and PWM2L will have 25% duty, but PWM2L will start after PWM2H is low that is after 270 degrees from start of PWM1H/PWM2H. So how the phase shift is 180 degrees. Thank You.
https://plus.google.com/photos/111038221676542745551/albums/6118361690316013793/6118361697329459234?pid=6118361697329459234&oid=111038221676542745551
Hi Saptarshi,
Yes, I know it’s a bit confusing!
The way this works is that PWM channels 1 and 2 operate in a complementary fashion, so PWM1 generates positive pulses (i.e. it’s high during a pulse and low when there’s no pulse), whereas PWM2 generates negative pulses (i.e. it’s low during a pulse and high when there’s no pulse). So what “looks like” a positive pulse on channel 2 is actually the gap between two negative pulses!
The pulses on both channels (positive on PWM1 and negative on PWM 2) are centre-aligned, and the centre of the pulses on both channels happen at exactly the same time. However, the pulse on PWM2 is in the negative direction and we set its width so that the gap between pulses on PWM2 is the same length and the positive pulses on PWM1.
The net result of this is that we effectively end up with positive pulses of equal duration on both channels, but exactly 180 degrees out of phase.
Hopefully that helps to explain it!
Ted
Hi Sir, Thank you for the explanation, i understood the logic. Great work Sir.
Hi Ted, I am working on dspic30f2010 and I don´t have enough experience on C30 compiler. Generally I used to work with CCS and Assembler. I am doing an audio filter and I want to understand the next code if you want to support me:
Can you tell me, what is the output pwm in this code (PWM1 or PWM2 or PWM3)?
What is the meaning of XT_PLL8?
What more can you tell me about this code?
Anything else you can tell me is important for me…Greetings
#include
#include
#include
#include
#include
#include
#include “fdacoefs.h”
//////////////////////////////////////////////////
_FOSC(CSW_FSCM_OFF & XT_PLL8);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_OFF & MCLR_EN);
_FGS(CODE_PROT_OFF);
//////////////////////////////////////////////////
// xtal 7.327MHz
#define FOSC 7372000LL
#define FCY (FOSC/4)
#define milis (FCY/1000L)
#define micros (FCY/1000000LL)
//////////////////////////////////////////////////////
#define CicloTrabajo OC1RS
int X[32] = {};
int XP[10]={};
int PROM = 0;
int Y = 0;
int max=1023/2;
int min=1023/2;
unsigned int resultado = 0;
void ConfTimer();
void ConfADC();
void ConfPWM();
void ConfInt();
int ADCOK = 0;
int ERROR = 0;
int i = 0;
int j = 0;
void __attribute__((__interrupt__)) _T1Interrupt(void)
{
WriteTimer1(0);
IFS0bits.T1IF = 0;
if(ADCOK){
ERROR = 1;
}
else{
ERROR = 0;
ADCOK = 1;
resultado = ReadADC10(0);
ConvertADC10();
}
j++;
if(j>2756){
max=511;
min=511;
j=0;
}
}
int main(void){
TRISD = 0;
TRISE = 0;
ConfADC();
ConfPWM();
for(i = 0; i++; i0; i–) X[i]=X[i-1];
X[0]=(resultado>>2)-PROM;
//
Y=VectorDotProduct(BL, B, X);
CicloTrabajo = (Y+PROM) & 255;
ADCOK = 0;
}
}
}
void ConfTimer(){
//config timer – 11025Hz
ConfigIntTimer1(T1_INT_PRIOR_1 & T1_INT_ON);
WriteTimer1(0);
OpenTimer1(T1_ON & T1_GATE_OFF & T1_IDLE_STOP &
T1_PS_1_1 & T1_SYNC_EXT_OFF &
T1_SOURCE_INT, 1335);
}
void ConfADC(){
// AN0 versus -Vref
ADCON1 = 0b0010000000000111;
ADCON2 = 0x0000;
ADCON3 = 0x0180;
ADCHS = 0x0000;
ADPCFG = 0xFFFE;
ADCON1bits.ADON = 1;
}
void ConfPWM(){
PR2 = 0xFF;
OC1RS = PR2>>1;
OC1R = OC1RS;
OC1CON = 0x0206; //PWM – TIMER 2
//conf TIMER2
T2CON = 0xA000;
}
void calcularPromedio(){
if(resultado>max) max = resultado;
if(resultado>3;
}
sorry…the headers are:
#include
#include
#include
#include
#include
#include
#include “fdacoefs.h”
Hi Memo, WordPress is filtering out your header file names because they’re wrapped in angle brackets which makes them look like HTML tags. Just remove the angle brackets and post again – I’ll know the brackets are supposed to appear there anyway.
Ted
Hi Ted… I get the code from this link: http://www.udb.edu.sv/udb/archivo/guia/electronica-ingenieria/senales-y-sistemas-discretos/2012/ii/guia-10.pdf
The tutorial is in spanish and show me a digital filter. I can get fdacoefs.h with matlab and I can build this code with C30 compiler … my problem is that I can´t understand some instructions as XT_PLL8 and where is the PWM output? and what is doing exactly this code because there are many things I wish to do with this project … Greetings
#include p30f2010.h
#include libpic30.h
#include stdio.h
#include dsp.h
#include timer.h
#include adc10.h
#include “fdacoefs.h”
//////////////////////////////////////////////////
_FOSC(CSW_FSCM_OFF & XT_PLL8);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_OFF & MCLR_EN);
_FGS(CODE_PROT_OFF);
//////////////////////////////////////////////////
#define FOSC 7372000LL
#define FCY (FOSC/4)
#define milis (FCY/1000L)
#define micros (FCY/1000000LL)
//////////////////////////////////////////////////////
#define CicloTrabajo OC1RS
int X[32] = {};
int XP[10]={};
int PROM = 0;
int Y = 0;
int max=1023/2;
int min=1023/2;
unsigned int resultado = 0;
void ConfTimer();
void ConfADC();
void ConfPWM();
void ConfInt();
int ADCOK = 0;
int ERROR = 0;
int i = 0;
int j = 0;
void __attribute__((__interrupt__)) _T1Interrupt(void)
{
WriteTimer1(0);
IFS0bits.T1IF = 0;
if(ADCOK){
ERROR = 1;
}
else{
ERROR = 0;
ADCOK = 1;
resultado = ReadADC10(0);
ConvertADC10();
}
j++;
if(j>2756){
max=511;
min=511;
j=0;
}
}
int main(void){
TRISD = 0;
TRISE = 0;
ConfTimer();
ConfADC();
ConfPWM();
for(i = 0; i++; i0; i–) X[i]=X[i-1];
X[0]=(resultado>>2)-PROM;
Y=VectorDotProduct(BL, B, X);
CicloTrabajo = (Y+PROM) & 255;
ADCOK = 0;
}
}
}
void ConfTimer(){
ConfigIntTimer1(T1_INT_PRIOR_1 & T1_INT_ON);
WriteTimer1(0);
OpenTimer1(T1_ON & T1_GATE_OFF & T1_IDLE_STOP &
T1_PS_1_1 & T1_SYNC_EXT_OFF &
T1_SOURCE_INT, 1335);
}
void ConfADC(){
ADCON1 = 0b0010000000000111;
ADCON2 = 0x0000;
ADCON3 = 0x0180;
ADCHS = 0x0000;
ADPCFG = 0xFFFE;
ADCON1bits.ADON = 1;
}
void ConfPWM(){
PR2 = 0xFF; OC1RS = PR2>>1;
OC1R = OC1RS;
OC1CON = 0x0206;
T2CON = 0xA000;
}
void calcularPromedio(){
if(resultado>max) max = resultado;
if(resultado>3;
}
Hi,Ted
How can i set PWM for Push-Pull by only use PWM1H/1L one channel ,i use yor code in “PWM output on 2 channels of the dsPIC30F4011 with equal duty cycle and 180 degrees out of phase”
Hi Gunz,
Please give me some more details and I’ll write a short example.
1. What PWM frequency?
2. How does the duty cycle vary?
3. What are the max and min duty cycle values?
4. What is the required dead time (between one transistor switching off and the other one switching on)?
Ted
1.25kHz
2.I use Lookup Table MPPT for vary duty cycle.
3.min0.1,max0.45
4.In push-pull use equal duty cycle and 180 degrees out of phase
thank you
Hi Gunz,
I’ve just posted an example that does more or less what you want (minus the lookup table). Here’s the link:
When I was programming this example, I was working without an internet connection and unfortunately I misremembered your requested PWM frequency, so I wrote the example for 15kHz rather than 25kHz. However, it should be straightforward to change the frequency to 25kHz by changing the value of PTPER from 999 to 599. You might also want to change PDC1 from 400 to 240 to keep the initial duty cycle at 0.1
Hope that helps!
Ted
thank you very much Ted 🙂 i will try it
Hello Mr Burke,
i have try your upper code with the dspic33fj32mc204, but it is not working very well. I mean the duty cycles on the scope are not equals and the dead time as well.
I will be very please for your reply.
Hi Margo,
Sorry for the delay responding. I’ve been away on holidays and now I’m up to my eyes with other work, so I don’t have time to investigate your query. Sorry I can’t be more helpful!
Ted
Hi Margo,
Did you work out what the problem was? Perhaps you could explain a little bit more about how exactly the timing is different from what you expect on the scope?
On most of the PIC microcontrollers I’ve used, the number of clock cycles per instruction is 4. However, that’s definitely different on certain PICs. So, for example, if you’re seeing times that are all out by a factor of 2, then that could be the reason.
Ted
Hi Mr.Ted,
Please help me, am new to PIC family & using a dsPIC30F4011 for my project.
In my project i want to generate two 180 degree out of phase pulses as above but i want the frequency to be 40KHz annd duty cycle to be 0.6.
Please help me with the code modification. Am unable to understand what parameters should be modified to get 40KHz waveform.
Thank You,
Hi Chetan,
Please try the modified version below and see if it does what you need. The first change is lines 77 and 78, which set the period (and frequency) and the duty cycle:
The second change is in the for loop in the main function – I changed lines 31-34 so that the duty cycle remains constant at 0.6 rather than changing back and forth between two values as it did originally.
The full modified program is below.
Ted
PS Actually, since you only want a fixed frequency and duty cycle, a much simpler program will suffice. Here’s a simpler version of the previous program, but this time I stripped out most of the code you don’t need. Hopefully this will be a little easier to understand!
Ted
Hi Ted, first of all thank you so much for the code.
But there is a small problem in the output waveform, the pulses are not exactly 180 degrees apart.
F = 40Khz -> T = 25us.
D = 0.6 -> Ton = 15us & Toff = 10us
Pulses being 180degress out of phase -> the time difference between them should be 2.5us between rising edge of one waveform & the falling edge of other.
But its not happening, please help me.
Hii again, I think the problem is with the logic analyzer it is not displaying values on points like 2.5…
Thank you for the code.
Hi again Chetan,
If you’re having trouble capturing the fine details on your logic analyser, you could try slowing everything down by a factor of 16 for testing by changing the following line…
…to this…
That might make it easier to see the pulses clearly and once you’re happy that they’re being generated correctly you can speed everything back up to normal frequency by putting back the original line in the program.
The difference between the two lines is that the original one enables the 16x PLL multiplier on the internal fast RC oscillator, whereas the second version uses the same oscillator but with the PLL multiplier.
Hopefully that helps.
Ted
Thank You So Much…
I will check it.
Can you please recommend me some links or materials regarding dsPIC programming where I can learn some basics and can understand what all these “FSCM, FBORPOR, PTPER, PTCKPS etc etc.,” means. It will be very helpful for me & my project.
Hi Chetan,
The information you probably want is distributed through several different documents. I’ll try to point you to the ones I find myself looking at most often.
Ted
Hello Sir,
I working on a DC-DC converter, which requires two 180 degrees out of phase pulses with 40Khz frequency & duty cycle should be more than 60%. I want PI control for my project.
Please help me with the code.
Hello sir,
Im working on a project push-pull converter, which requiered two PWM pulse with equal duty cycle and 180 degree phase shift. The duty ratio have to varies between 10% to 45% depend upon requirement. The switching frequency is 25 kHz. How can I do this work,plz help me.
Hello sir,
I would like to know, how can we do simultaneous ADC sampling. I want to read current and voltage at same time and after a small interval need to take 2nd sample and compare with the first.
Hi Sandeeppv,
Although the dsPIC30F4011 only has one ADC, it has four sample-and-hold blocks, so it presumably is possible to sample up to four pins simultaneously, then convert them into digital values one at a time. I haven’t actually done it myself though, so I’m afraid I don’t have an example I can offer you.
Ted
Thanks, Sir.
Dear Sir,
I am currently working with dsPIC30F4011. dsPIC has 6 PWM pins (RE0 – RE1). I would like to ,make those pin working as input output pins. Please inform me how the configuration bits are to be set for that purpose.