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();
}
}