Nerdegutta's logo

nerdegutta.no

PIC12F1822 - Fade 6 RGB LED in and out

05.01.25

Embedded

This program in close to this, but for another MCU. It does the same thing, but we're using all I/O-pins except one. Although this MCU is far to advanced for this circuit, and we're only using 10% of data memory and 9% of the program memory.

// INCLUDE LIBRARIES
#include < xc.h > // Remove extra spaces

// CONFIGURATION BITS
// CONFIG1
#pragma config FOSC     = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE     = OFF       // Watchdog Timer Enable (WDT enabled)
#pragma config PWRTE    = OFF       // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE    = ON        // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP       = OFF       // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD      = OFF       // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN    = ON        // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF       // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO     = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN    = ON        // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)

// CONFIG2
#pragma config WRT      = OFF       // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN    = ON        // PLL Enable (4x PLL enabled)
#pragma config STVREN   = ON        // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV     = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config DEBUG    = OFF       // In-Circuit Debugger Mode (In-Circuit Debugger disabled, ICSPCLK and ICSPDAT are general purpose I/O pins)
#pragma config LVP      = ON        // Low-Voltage Programming Enable (Low-voltage programming enabled)

// DEFINITIONS
#define _XTAL_FREQ  4000000         // Compiler reference
#define PWM_PIN     PORTAbits.RA2   // This is the PWM output pin

#define RED_LED 0b000010    // RA1 HIGH
#define GRN_LED 0b010000    // RA4 HIGH
#define BLU_LED 0b100000    // RA5 HIGH

#define RED_DIR 0b110000    // RA5, RA4 set to input
#define GRN_DIR 0b100010    // RA5, RA1 set to input
#define BLU_DIR 0b010010    // RA4, RA1 set to input

// VARABLES
unsigned int i;
int cycleCounter = 0;
unsigned int dutyCycle = 0;

// FUNCTION PROTOTYPE
void initPWM(void);
void setPWMDutyCycle(unsigned int DutyCycle);
void updatePWM();

// FUNCTIONS
void initPWM(void) {
    TRISA2 = 0;             // Set RA2 (CCP1 output) as output       
    CCP1CON = 0b00001100;   // Configure CCP1 in PWM mode
    PR2 = 255;              // Set PWM frequency (using Timer2)
    T2CON = 0b00000100;     // Timer2 ON, Prescaler 1:1        
    CCPR1L = 0;             // Set initial duty cycle. Duty cycle low byte
    CCP1CONbits.DC1B = 0;   // Least significant bits of duty cycle
}

void setPWMDutyCycle(unsigned int DutyCycle) {
    CCPR1L      = DutyCycle>>2;             // Put MSB 8 bits in CCPR1L
    CCP1CON     &= 0xCF;                    // Make bit 4 and 5 zero
    CCP1CON     |= (0x03&(DutyCycle<<4));   // Assign last 2 LSBs to CCP1CON
}

void updatePWM() {
    // Fade LED in
    for (i=0;i<1023;i++) {
        setPWMDutyCycle(i);
        __delay_us(1000);
    }
    
    // Fade LED out
    for (i=1023;i>0;i--) {
        setPWMDutyCycle(i);
        __delay_us(1000);
    }
    cycleCounter++;
    
    // Activate the green LED
    if (cycleCounter == 3) {
        TRISA = GRN_DIR;
        PORTA = GRN_LED;
    }
    
    // Activate the blue LED
    if (cycleCounter == 6) {
        TRISA = BLU_DIR;
        PORTA = BLU_LED;
    }

    // Activate the red LED
    if (cycleCounter == 9) {
        TRISA = RED_DIR;
        PORTA = RED_LED;         
    }    
    
    // Reset cycleCounter
    if (cycleCounter > 9) {
        cycleCounter = 1;
    }
} // End updatePWM

void main(void) {
    OSCCONbits.IRCF = 0b1101;   // Configure oscillator. Internal 4MHz
    
    initPWM();                  // Initialise PWM

    // Start with red LED
    TRISA = RED_DIR;
    PORTA = RED_LED;      
    while (1) {
            updatePWM();
    }
}