I have been working with pic microcontroller but this is my first time working with PWM to achieve breathing/fading effect on pin rb0. Please help me in achieving fading LED functionality on rb0. I have gone trough every possible way to troubleshoot the error but failed to achieve same. According to me the code is almost correct and I have checked every setting but the led at rb0 is keep glowing solid with no PWM fading effect. My timer 2 isr is also working great in order to check that I have also used LED at rb1 as a debug led so that I know when the isr is functional or not but rb1 is toggling great which means isr is working. Please guide me where in my code I'm going wrong so that LED at rb0 glows with fading effect. I'm using 32 MHz external oscillator. I'm sharing my code below.
#include <xc.h> #include <libpic30.h> // For __delay_ms() #pragma config FNOSC = PRIPLL // Primary Oscillator Mode #pragma config POSCMOD = HS // High-Speed Oscillator #pragma config FCKSM = CSDCMD // Clock switching and monitoring disabled #pragma config FWDTEN = OFF // Watchdog Timer disabled #define FCY 3200000UL // FRC default frequency #define PWM_FREQ 1000 // 1 kHz PWM volatile unsigned int duty = 0; volatile int step = 40; void __attribute__((interrupt, no_auto_psv)) _T2Interrupt(void) { static unsigned int counter = 0; IFS0bits.T2IF = 0; LATBbits.LATB1 ^= 1; // Blink for debug counter++; if (counter >= 20) { // Change duty every 20 ms counter = 0; duty += step; if (duty >= PR2) { duty = PR2; step = -step; } else if (duty <= 0) { duty = 0; step = -step; } OC1RS = duty; } } void PWM_Init(void) { AD1PCFG = 0xFFFF; // All analog pins set to digital TRISBbits.TRISB1 = 0; // RB1 (debug toggle) LATBbits.LATB1 = 0; AD1PCFGbits.PCFG0 = 1; // RB0 as digital TRISBbits.TRISB0 = 0; // Set RB0 as output LATBbits.LATB0 = 0; // Start low // Disable ADC AD1CON1bits.ADON = 0; // Disable ADC // ===== MAP OC1 TO RB0 (RP0) ===== __builtin_write_OSCCONL(OSCCON & ~(1 << 6)); // Unlock PPS RPOR0bits.RP0R = 18; // Map OC1 to RP0 (RB0) __builtin_write_OSCCONL(OSCCON | (1 << 6)); // Lock PPS // Timer2 for PWM base T2CON = 0; T2CONbits.TCKPS = 0b00; // 1:1 prescaler PR2 = FCY / PWM_FREQ - 1; // For 1 kHz PWM TMR2 = 0; // OC1 PWM Setup OC1CON1 = 0; duty = PR2 / 2; // Start at 50% OC1R = duty; OC1RS = duty; OC1CON1bits.OCTSEL = 0b000; // Timer2 as source OC1CON2bits.SYNCSEL = 0b11111; // No sync OC1CON1bits.OCM = 0b110; // Edge-aligned PWM IFS0bits.T2IF = 0; // Clear Timer2 interrupt flag IEC0bits.T2IE = 1; // Enable Timer2 interrupt IPC1bits.T2IP = 4; // Priority level 4 T2CONbits.TON = 1; __builtin_enable_interrupts(); } int main(void) { PWM_Init(); // Set everything up while (1); // Everything is handled in ISR return 0; }
~~~before & after. \$\endgroup\$