PWM generation with the dsPIC30F4011

This is a simple example of PWM waveform generation using the dsPIC30F4011 microcontroller. This chip has three PWM channels (pins 33-38), each channel consisting of a pair of pins which can be configured in various ways. The code below enables all three PWM channels in complementary mode, which means that the two pins belonging to each channel always have opposite values. The three channels’ waveforms always have the same period, but the pulse width can be set independently on each channel.

In the example below, the PWM waveform period is set to 20ms. The pulse widths on the three channels alternate between two different configurations – they are either set to 1.0ms, 1.2ms and 1.4ms respectively, or else they are all set to 2ms. Switching between the two configurations occurs once every second.

Here’s the code:

// dsPIC30F4011 UART Example
// Written by Ted Burke
// Last updated 27-8-2012

#include <xc.h>
#include <stdio.h>
#include <libpic30.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

int main()
	// Configure PWM for free running mode
	//   PWM period = Tcy * prescale * PTPER = 0.33ns * 64 * PTPER
	//   PWM pulse width = (Tcy/2) * prescale * PDCx
	PWMCON1 = 0x00FF;     // Enable all PWM pairs in complementary mode
	PTCONbits.PTCKPS = 3; // prescale=1:64 (0=1:1, 1=1:4, 2=1:16, 3=1:64)
	PTPER = 9375;         // 20ms PWM period (15-bit period value)
	PTMR = 0;             // Clear 15-bit PWM timer counter
	PTCONbits.PTEN = 1;   // Enable PWM time base

		_LATD0 = 1;
		PDC1 = 938;  // channel 1 pulse width = 1.0ms
		PDC2 = 1125; // channel 2 pulse width = 1.2ms
		PDC3 = 1312; // channel 3 pulse width = 1.4ms
		__delay32(30000000); // 1 second delay

		_LATD0 = 1;
		PDC1 = 1875; // channel 1 pulse width = 2.0ms
		PDC2 = 1875; // channel 2 pulse width = 2.0ms
		PDC3 = 1875; // channel 3 pulse width = 2.0ms
		__delay32(30000000); // 1 second delay

	return 0;

Using the PICkit2 application, it’s easy to measure the waveforms produced.

In the following screenshot, I have enabled the cursors to measure the time difference between successive pulses. As you can see, the period of each waveform is very close to 20ms:

In the following screenshot, I have changed the sample rate and zoom setting in order to take a closer look at the pulse width on channel 2 and measure it with a cursor. As you can see, it’s very close to the intended value of 1.2ms.

This entry was posted in Uncategorized and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s