Nerdegutta's logo

nerdegutta.no

PIC16F628A - RGB LED Fade in and out

26.12.24

Embedded

This program utilize the functions from RBG leds. It starts with the red color. The red color of the RGB is faded in and out 3 times. Then it moves on to the green color. Same here. Fades in and out 3 times. Lastly the blue part of the RGB is faded in and out three times.

The code is fairly good commented, so it should be quite easy to understand whats going on.

Here's the circuit.


// Include libraries
#include < xc.h >

// Configuration Bits
#pragma config FOSC     = INTOSCIO  // Internal oscillator
#pragma config WDTE     = OFF       // Watchdog timer disabled
#pragma config PWRTE    = OFF       // Power-up timer disabled
#pragma config MCLRE    = ON        // MCLR pin function is digital input
#pragma config BOREN    = OFF       // Brown-out reset disabled
#pragma config LVP      = OFF       // Low-voltage programming disabled
#pragma config CPD      = OFF       // Data memory code protection off
#pragma config CP       = OFF       // Code protection off

// Defines
#define _XTAL_FREQ 20000000         // Set crystal frequency to 4 MHz
#define LED_PIN RB3                 // Define the PWM Pin
#define RED_PIN PORTBbits.RB4       // Red led NPN
#define GRN_PIN PORTBbits.RB5       // Green led NPN
#define BLU_PIN PORTBbits.RB6       // Blue led NPN

// Variables
int i;
int cycleCounter = 0;

// Function prototype
void InitPWM(void);
void SetPWMDutyCycle(unsigned int DutyCycle);
void UpdatePWM();


// Functions
void InitPWM(void)
{
	CCP1CON = 0x0C;         // Configure CCP1 module in PWM mode
	PR2   = 0xFF;           // Configure the Timer2 period
	T2CON = 0x01;           // Set Prescaler to be 4, hence PWM frequency is set to 4.88KHz.

	SetPWMDutyCycle(0);     // Intialize the PWM to 0 duty cycle

	T2CON |= 0x04;          // Enable the Timer2, hence enable the PWM.
}

void SetPWMDutyCycle(unsigned int DutyCycle) // Give a value in between 0 and 1024 for DutyCycle
{
	CCPR1L   = DutyCycle>>2;        	// Put MSB 8 bits in CCPR1L
	CCP1CON &= 0xCF;                	// Make bit4 and 5 zero
	CCP1CON |= (0x30&(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++;
    
    // if cycleCounter is equal to 3, set TRISB4 to input and low. Set TRISB5 to output and high. Red off and green on
    if (cycleCounter == 3) {
        TRISB4 = 1;
        RED_PIN = 0;
        TRISB5 = 0;
        GRN_PIN = 1;  
    }
    
    // if cycleCounter is equal to 6, set TRISB5 to input and low. Set TRISB6 to output and high. Green off and blue on    
    if (cycleCounter == 6) {
        TRISB5 = 1;
        GRN_PIN = 0;
        TRISB6 = 0;
        BLU_PIN = 1;
    }
    
    // if cycleCounter is equal to 9, set TRISB6 to input and low. Set TRISB4 to output and high. Red on and blue on    
    if (cycleCounter == 9) {
        TRISB6 = 1;
        BLU_PIN = 0;
        TRISB4 = 0;
        RED_PIN = 1;
    }

    // Reset the cycleCounter    
    if (cycleCounter > 9) {
        cycleCounter = 1;
    }
}


// Main function
void main()
{	
    TRISB3 = 0;             // Make CCP1 pin as output
    TRISB4 = 0;             // Red Pin set to output
    TRISB5 = 1;             // Gree Pin set to input
    TRISB6 = 1;             // Blue Pin set to input
    
    RED_PIN = 1;            // Program starts with the Red led on
    
	InitPWM();				// Initialize PWM at RB3 pin
    
	while(1) {
        UpdatePWM();
	}
}