Good day, I am working with a PIC24FJ64GA002 microcontroller and am struggling to get the PWM working for a servo I want to use. My code is as follows:
// PIC24FJ64GA002 Configuration Bit Settings
// 'C' source line config statements
// CONFIG2
#pragma config POSCMOD = NONE // Primary Oscillator Select (Primary oscillator disabled)
#pragma config I2C1SEL = PRI // I2C1 Pin Location Select (Use default SCL1/SDA1 pins)
#pragma config IOL1WAY = ON // IOLOCK Protection (Once IOLOCK is set, cannot be changed)
#pragma config OSCIOFNC = OFF // Primary Oscillator Output Function (OSC2/CLKO/RC15 functions as CLKO (FOSC/2))
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor (Clock switching and Fail-Safe Clock Monitor are disabled)
#pragma config FNOSC = FRC // Oscillator Select (Fast RC Oscillator (FRC))
#pragma config SOSCSEL = SOSC // Sec Oscillator Select (Default Secondary Oscillator (SOSC))
#pragma config WUTSEL = LEG // Wake-up timer Select (Legacy Wake-up Timer)
#pragma config IESO = ON // Internal External Switch Over Mode (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 = ON // Watchdog Timer Window (Standard Watchdog Timer enabled,(Windowed-mode is disabled))
#pragma config FWDTEN = ON // Watchdog Timer Enable (Watchdog Timer is enabled)
#pragma config ICS = PGx1 // Comm Channel Select (Emulator EMUC1/EMUD1 pins are shared with PGC1/PGD1)
#pragma config GWRP = OFF // General Code Segment Write Protect (Writes to program memory are allowed)
#pragma config GCP = OFF // General Code Segment Code Protect (Code protection is disabled)
#pragma config JTAGEN = OFF // JTAG Port Enable (JTAG port is disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
/*
* File: 34660046LAB2.c
* Author: leone
*
* Created on 06 September 2021, 1:27 PM
*/
#include "p24FJ64GA002.h"
#include "xc.h"
#define _LATR15 OC1R
int main(void) {
T2CON = 0x8010;
TMR2=0;
PR2=9999;
_T2IP=4; //Default priority value
_T2IF=0; //Clears interrupt flag before interrupt
_T2IE=1; //Enables interrupt
OC1CONbits.OC = 0; // Output compare channel is disabled
OC1R = 0x1388 ; // Initialize Compare Register1 with 50% duty cycle
OC1CONbits.OCSIDL = 0; // Output capture will continue to operate in CPU Idle mode
OC1CONbits.OCFLT = 0; // No PWM Fault condition has occurred (this bit is only used when OCM<2:0> = 111)
OC1CONbits.OCTSEL = 0; // Timer2 is the clock source for output Compare
OC1CONbits.OCM = 0x6; // PWM mode on OC, Fault pin disabled
TRISBbits.TRISB15=0;
_LATB15=0;
while(1)
{
if(TMR2>OC1R)
{
_LATB15=1;
}
else
{
_LATB15=0;
}
}
return 0;
}
I programmed the T1CON to have a period of 2 ms, and the OC1R to have half that period, which should lead to a duty cycle of 50%. I am using the FRC oscillator (8MHz) and my pre-scaler values were <0,1>. I understand the it's the OC1R pin that gives the period the cycle is high, but in the datasheets they refer to it as a pin, however they don't give what pin it is (i.e. A0,A1,R15 etc.) There is also very little example code I could find explaining the how to code this well. If anyone is a PIC expert of some kind help would be very much appreciated! The datasheet for the MCU can be downloaded at https://www.microchip.com/en-us/product/PIC24FJ64GA002.
First of all configure the IO pins for PWM output, I assume you use SPDIP package and wanna use the OC1 PWM output pin:
For the output pin configurations see the 10.4.3.2 Output Mapping section of the datasheet.
As per steps in the datasheet's 14.3 Pulse-Width Modulation Mode section:
Write the OCxR register with the initial duty cycle. Assign the
DUTY_VALUE
to the OCxR register right after OCxRS assignment:OCxR = DUTY_VALUE;
Enable interrupts, if required, for the timer and output compare modules. The output compare interrupt is required for PWM Fault pin utilization.
Configure the output compare module for one of two PWM Operation modes by writing to the Output Compare Mode bits, OCM<2:0> (OCxCON<2:0>).
From now on you should have the PWM working if the above steps are done correctly. Modify your code as per instructions here. Then try it and let me know the result.