PIC24F PWM Question

Discussion in 'Embedded Systems and Microcontrollers' started by rkrutz, Jun 26, 2013.

  1. rkrutz

    Thread Starter New Member

    Dec 2, 2009
    29
    1
    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
    Code ( (Unknown Language)):
    1.  
    2.  
    3. #include <stdio.h>
    4. #include <stdlib.h>
    5. #include "Config.h"
    6. #include <xc.h>
    7. #include "timer.h"
    8. #include <p24Fxxxx.h>
    9.  
    10. int main(void)
    11. {
    12.     OSCCON  =   0x2200;     //select Fast RC, no PLL
    13.     CLKDIV  =   0x0000;     //do not divide
    14.  
    15.     //Set up I/O Port
    16.     AD1PCFGL    =   0xFFFF;     //set to all digital I/O
    17.  
    18.         RPOR0bits.RP0R = 0;
    19.  
    20.         LATBbits.LATB0 = 0;
    21.         TRISBbits.TRISB0 = 0;
    22.  
    23.         OC1CON2 = 0x001F;
    24.         OC1CON1 = 0x1C08;
    25.         RPOR0bits.RP0R = 18;
    26.  
    27.         TRISA=0b00000000;//sets all ports on A to be outputs
    28.         while (1)
    29.         {
    30.        
    31.         PORTAbits.RA0=1;
    32.         OC1R = 0x7999;
    33.         OC1RS = 0x7999;
    34.         }
    35. }
    36.  
    Config.h
    Code ( (Unknown Language)):
    1.  
    2.  
    3. #include <p24Fxxxx.h>
    4.  
    5. // CONFIG4
    6. #pragma config DSWDTPS = DSWDTPSF       // DSWDT Postscale Select (1:2,147,483,648 (25.7 days))
    7. #pragma config DSWDTOSC = LPRC          // Deep Sleep Watchdog Timer Oscillator Select (DSWDT uses Low Power RC Oscillator (LPRC))
    8. #pragma config RTCOSC = SOSC            // RTCC Reference Oscillator  Select (RTCC uses Secondary Oscillator (SOSC))
    9. #pragma config DSBOREN = OFF            // Deep Sleep BOR Enable bit (BOR disabled in Deep Sleep)
    10. #pragma config DSWDTEN = OFF            // Deep Sleep Watchdog Timer (DSWDT disabled)
    11.  
    12. // CONFIG3
    13. #pragma config WPFP = WPFP63            // Write Protection Flash Page Segment Boundary (Highest Page (same as page 42))
    14. #pragma config SOSCSEL = IO             // Secondary Oscillator Pin Mode Select (SOSC pins have digital I/O functions (RA4, RB4))
    15. #pragma config WUTSEL = LEG             // Voltage Regulator Wake-up Time Select (Default regulator start-up time used)
    16. #pragma config WPDIS = WPDIS            // Segment Write Protection Disable (Segmented code protection disabled)
    17. #pragma config WPCFG = WPCFGDIS         // Write Protect Configuration Page Select (Last page and Flash Configuration words are unprotected)
    18. #pragma config WPEND = WPENDMEM         // Segment Write Protection End Page Select (Write Protect from WPFP to the last page of memory)
    19.  
    20. // CONFIG2
    21. #pragma config POSCMOD = EC             // Primary Oscillator Select (EC Oscillator mode selected)
    22. #pragma config I2C1SEL = PRI            // I2C1 Pin Select bit (Use default SCL1/SDA1 pins for I2C1 )
    23. #pragma config IOL1WAY = ON             // IOLOCK One-Way Set Enable (Once set, the IOLOCK bit cannot be cleared)
    24. #pragma config OSCIOFNC = ON            // OSCO Pin Configuration (OSCO pin functions as port I/O (RA3))
    25. #pragma config FCKSM = CSDCMD           // Clock Switching and Fail-Safe Clock Monitor (Sw Disabled, Mon Disabled)
    26. #pragma config FNOSC = FRCDIV           // Initial Oscillator Select (Fast RC Oscillator with Postscaler (FRCDIV))
    27. #pragma config PLL96MHZ = ON            // 96MHz PLL Startup Select (96 MHz PLL Startup is enabled automatically on start-up)
    28. #pragma config PLLDIV = DIV12           // USB 96 MHz PLL Prescaler Select (Oscillator input divided by 12 (48 MHz input))
    29. #pragma config IESO = ON                // Internal External Switchover (IESO mode (Two-Speed Start-up) enabled)
    30.  
    31. // CONFIG1
    32. #pragma config WDTPS = PS32768          // Watchdog Timer Postscaler (1:32,768)
    33. #pragma config FWPSA = PR128            // WDT Prescaler (Prescaler ratio of 1:128)
    34. #pragma config WINDIS = OFF             // Windowed WDT (Standard Watchdog Timer enabled,(Windowed-mode is disabled))
    35. #pragma config FWDTEN = OFF             // Watchdog Timer (Watchdog Timer is disabled)
    36. #pragma config ICS = PGx1               // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC1/PGED1)
    37. #pragma config GWRP = OFF               // General Segment Write Protect (Writes to program memory are allowed)
    38. #pragma config GCP = OFF                // General Segment Code Protect (Code protection is disabled)
    39. #pragma config JTAGEN = ON              // JTAG Port Enable (JTAG port is enabled)
    40.  
    41.  
    42.  
     
  2. rkrutz

    Thread Starter New Member

    Dec 2, 2009
    29
    1
    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: Jun 26, 2013
Loading...