]> oss.titaniummirror.com Git - rgblamp.git/blobdiff - main.c
4 channel PWM with sample color changing
[rgblamp.git] / main.c
diff --git a/main.c b/main.c
index 5abba0107b3e38a843907e41ef0e90601224f71a..7fa14f2fab32eb238dd7f46eefd16f91731e43d6 100644 (file)
--- a/main.c
+++ b/main.c
@@ -6,10 +6,15 @@
 
 
 #include <htc.h>
-#include <pic16f1827.h>
+//#include <pic16f1827.h>
 
 #define RUNAT32MHZ /* else 16 MHz */
-#define LEDBIT          0x01 /* PORTB.0 */
+#define LEDBIT          0x01 /* Port RB0 */
+#define RED_CHAN    1
+#define GRN_CHAN    2
+#define BLU_CHAN    4
+#define WHT_CHAN    8
+#define ALL_CHAN    15
 
 #if defined(RUNAT32MHZ)
 __CONFIG(WDTE_OFF & FOSC_INTOSC);
@@ -33,34 +38,50 @@ void pic_init()
 
 void pwm_init()
 {
-    /* Initialize PWM on PORTB.3
+    /* Initialize PWM
+     * CCP1 on RB3, CCP2 on RA7, CCP3 on RA3, CCP4 on RA4
      * - Fosc = 32MHz
      * - Prescale = 16
      * - PRx value = 0xff
      * = f(pwm) = 1.95 kHz
      */
 
-    /* Disable output on PORTB.3 */
-    TRISB |= 0x08;
+    /* Disable output on PWM Rxn pins */
+    TRISA |= 0b10011000;
+    TRISB |= 0b00001000;
 
     /* Configure ECCP1 */
     CCP1CON = 0b00001100;
     CCPR1L = 0; /* Initial PWM value; only using 8 LSBs */
 
+    /* Configure ECCP2 */
+    APFCON0 |= 0b00001000; /* Use alternate output pin RA7 */
+    CCP2CON = 0b00001100;
+    CCPR2L = 0; /* Initial PWM value; only using 8 LSBs */
+
+    /* Configure CCP3 */
+    CCP3CON = 0b00001100;
+    CCPR3L = 0; /* Initial PWM value; only using 8 LSBs */
+
+    /* Configure CCP4 */
+    CCP4CON = 0b00001100;
+    CCPR4L = 0; /* Initial PWM value; only using 8 LSBs */
+
     /* Configure Timer2 */
-    CCPTMRS = CCPTMRS & ~0x03; /* bits 1:0 denote CCP1 uses Timer 2 */
+    CCPTMRS = 0; /* All CCPx use Timer 2 */
     TMR2IF = 0;
     PR2 = 0xff;
     T2CON = 0b00000111;
 
-    /* Enable PWM output, PORTB.3 */
-    while (!TMR2IF); /* wait until timer overflow */
-    TRISB &= ~0x08;
+    /* Enable PWM outputs after Timer 2 overflows */
+    while (!TMR2IF);
+    TRISA &= ~0b10011000;
+    TRISB &= ~0b00001000;
 }
 
 void led_init()
 {
-    PORTB &= ~LEDBIT; /* Led is PORTB.0 */
+    PORTB &= ~LEDBIT; /* Led is RB0 */
     TRISB &= ~LEDBIT;
 }
 
@@ -72,9 +93,16 @@ void led_set(unsigned char led)
         PORTB &= ~LEDBIT;
 }
 
-void pwm_set(unsigned char step)
+void pwm_set(unsigned char channels, unsigned char step)
 {
-    CCPR1L = step;
+    if (channels & RED_CHAN)
+        CCPR1L = step;
+    if (channels & GRN_CHAN)
+        CCPR2L = step;
+    if (channels & BLU_CHAN)
+        CCPR3L = step;
+    if (channels & WHT_CHAN)
+        CCPR4L = step;
 }
 
 void delay()
@@ -82,6 +110,32 @@ void delay()
     for (unsigned counter = 0; counter < 10000; counter++);
 }
 
+void ramp_up(unsigned char channels)
+{
+    unsigned char step = 0;
+
+    do {
+        pwm_set(channels, step++);
+        delay();
+    } while (step != 0);
+}
+
+void ramp_down(unsigned char channels)
+{
+    unsigned char step = 255;
+
+    do {
+        pwm_set(channels, step--);
+        delay();
+    } while (step != 255);
+}
+
+void ramp_up_down(unsigned char channels)
+{
+    ramp_up(channels);
+    ramp_down(channels);
+}
+
 int main(void)
 {
     unsigned char fwd = 1;
@@ -91,23 +145,15 @@ int main(void)
     led_init();
     pwm_init();
     while (1) {
-        pwm_set(step);
-        if (fwd == 0) {
-            step--;
-            if (step == 0xff) { /* rollover */
-                led_set(0);
-                fwd = 1;
-                step = 0;
-            }
-        } else /* fwd == 1 */ {
-            step++;
-            if (step == 0) { /* rollover */
-                led_set(1);
-                fwd = 0;
-                step = 0xff;
-            }
-        }
-        delay();
+        ramp_up(RED_CHAN);
+        ramp_up(GRN_CHAN);
+        ramp_down(RED_CHAN);
+        ramp_up(BLU_CHAN);
+        ramp_down(GRN_CHAN);
+        ramp_up(RED_CHAN);
+        ramp_up(GRN_CHAN + BLU_CHAN);
+        ramp_down(ALL_CHAN);
+        ramp_up_down(WHT_CHAN);
     }
     return 0;
 }