PIC24F PWM Question

Thread Starter

rkrutz

Joined Dec 2, 2009
29
Hello,

I have been trying to get PWM to work on the PIC24F series and have noticed that it is done a little different then on the 8 bit chips. After reading through the 24F family reference manual and the 24FJ64GB002 data sheet I am not sure what I am missing. I have configured it to work on RP0 which is RB0. I feel like I am missing either a timer command, configuration bit, or the port is not actually being turned on.

I am using MPLABX with XC16.

Thanks

Main
Rich (BB code):
#include <stdio.h>
#include <stdlib.h>
#include "Config.h"
#include <xc.h>
#include "timer.h"
#include <p24Fxxxx.h>

int main(void)
{
    OSCCON	=	0x2200;		//select Fast RC, no PLL
 	CLKDIV	=	0x0000;		//do not divide

 	//Set up I/O Port
	AD1PCFGL	=	0xFFFF;		//set to all digital I/O

        RPOR0bits.RP0R = 0;

        LATBbits.LATB0 = 0;
        TRISBbits.TRISB0 = 0;

        OC1CON2 = 0x001F;
        OC1CON1 = 0x1C08;
        RPOR0bits.RP0R = 18;

        TRISA=0b00000000;//sets all ports on A to be outputs
        while (1)
        {
        
        PORTAbits.RA0=1;
        OC1R = 0x7999;
        OC1RS = 0x7999;
        }
}
Config.h
Rich (BB code):
#include <p24Fxxxx.h>

// CONFIG4
#pragma config DSWDTPS = DSWDTPSF       // DSWDT Postscale Select (1:2,147,483,648 (25.7 days))
#pragma config DSWDTOSC = LPRC          // Deep Sleep Watchdog Timer Oscillator Select (DSWDT uses Low Power RC Oscillator (LPRC))
#pragma config RTCOSC = SOSC            // RTCC Reference Oscillator  Select (RTCC uses Secondary Oscillator (SOSC))
#pragma config DSBOREN = OFF            // Deep Sleep BOR Enable bit (BOR disabled in Deep Sleep)
#pragma config DSWDTEN = OFF            // Deep Sleep Watchdog Timer (DSWDT disabled)

// CONFIG3
#pragma config WPFP = WPFP63            // Write Protection Flash Page Segment Boundary (Highest Page (same as page 42))
#pragma config SOSCSEL = IO             // Secondary Oscillator Pin Mode Select (SOSC pins have digital I/O functions (RA4, RB4))
#pragma config WUTSEL = LEG             // Voltage Regulator Wake-up Time Select (Default regulator start-up time used)
#pragma config WPDIS = WPDIS            // Segment Write Protection Disable (Segmented code protection disabled)
#pragma config WPCFG = WPCFGDIS         // Write Protect Configuration Page Select (Last page and Flash Configuration words are unprotected)
#pragma config WPEND = WPENDMEM         // Segment Write Protection End Page Select (Write Protect from WPFP to the last page of memory)

// CONFIG2
#pragma config POSCMOD = EC             // Primary Oscillator Select (EC Oscillator mode selected)
#pragma config I2C1SEL = PRI            // I2C1 Pin Select bit (Use default SCL1/SDA1 pins for I2C1 )
#pragma config IOL1WAY = ON             // IOLOCK One-Way Set Enable (Once set, the IOLOCK bit cannot be cleared)
#pragma config OSCIOFNC = ON            // OSCO Pin Configuration (OSCO pin functions as port I/O (RA3))
#pragma config FCKSM = CSDCMD           // Clock Switching and Fail-Safe Clock Monitor (Sw Disabled, Mon Disabled)
#pragma config FNOSC = FRCDIV           // Initial Oscillator Select (Fast RC Oscillator with Postscaler (FRCDIV))
#pragma config PLL96MHZ = ON            // 96MHz PLL Startup Select (96 MHz PLL Startup is enabled automatically on start-up)
#pragma config PLLDIV = DIV12           // USB 96 MHz PLL Prescaler Select (Oscillator input divided by 12 (48 MHz input))
#pragma config IESO = ON                // Internal External Switchover (IESO mode (Two-Speed Start-up) enabled)

// CONFIG1
#pragma config WDTPS = PS32768          // Watchdog Timer Postscaler (1:32,768)
#pragma config FWPSA = PR128            // WDT Prescaler (Prescaler ratio of 1:128)
#pragma config WINDIS = OFF             // Windowed WDT (Standard Watchdog Timer enabled,(Windowed-mode is disabled))
#pragma config FWDTEN = OFF             // Watchdog Timer (Watchdog Timer is disabled)
#pragma config ICS = PGx1               // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC1/PGED1)
#pragma config GWRP = OFF               // General Segment Write Protect (Writes to program memory are allowed)
#pragma config GCP = OFF                // General Segment Code Protect (Code protection is disabled)
#pragma config JTAGEN = ON              // JTAG Port Enable (JTAG port is enabled)
 

Thread Starter

rkrutz

Joined Dec 2, 2009
29
It looks like I was just missing OC1CON1bits.OCM = 6; which is what turns it on, but is there anything else?

Also could I get clarification on if I am doing my math correct? If I want to power a servo that requires a pulse every 20ms with a duration of 1ms using the internal 8MHZ oscillator I need to set OC1RS to 0x7999 and OC1R to 400.

I used the equation from the data sheet which is:
PWM_Period = [OCxRS + 1] * Tcy* pre-scaler

.002 = [OCxRS +1] *2.5 e-7*1

Which sets OCxRS = 0x7999 and since 1ms is 1/20 of that pulse OCxR becomes 0x400, is that correct?
 
Last edited:
Top