PIC12F683でフルカラーLEDを使うためにPWMを3つ実装。
3つとは言っても、独立しているわけじゃなくて、全部同期している。
/* * File: main.c * Author: sakai * * Created on 2014/07/28, 5:11 */ #include <stdio.h> #include <stdlib.h> #include <xc.h> #define _XTAL_FREQ (4000000) #pragma config FOSC = INTOSCIO // INTOSCIO #pragma config MCLRE = ON #pragma config BOREN = ON // Brown Out Detect #pragma config WDTE = OFF #pragma config CPD = OFF // Data Code Protection bit #pragma config CP = OFF #pragma config PWRTE = ON #define RED_PORT GP2 #define GREEN_PORT GP0 #define BLUE_PORT GP1 #define WAIT while (tcounter != 0) {} volatile unsigned char tcounter = 0; volatile unsigned char red_vol = 0; volatile unsigned char green_vol = 0; volatile unsigned char blue_vol = 0; static void interrupt intr_timer0(void) { if (T0IF == 1) { // Timer0による割り込みか? if (tcounter == red_vol) { RED_PORT = 0; // カソードコモンなので } else if (tcounter == 0) { RED_PORT = 1; // カソードコモンなので } if (tcounter == green_vol) { GREEN_PORT = 0; // カソードコモンなので } else if (tcounter == 0) { GREEN_PORT = 1; // カソードコモンなので } if (tcounter == blue_vol) { BLUE_PORT = 0; // カソードコモンなので } else if (tcounter == 0) { BLUE_PORT = 1; // カソードコモンなので } tcounter++; TMR0 = 255; // タイマーの長さ調整 T0IF = 0; // Timer0による割り込みの処理完了 } } /* * */ int main(int argc, char** argv) { // クロックの設定 OSCCON = 0x60; // 4MHz (8MHzにするには0x70を設定) // 使わない機能を停止 CMCON0 = 0x07; // コンパレータを停止し、 ANSEL = 0x00; // アナログ入力を使わない(デジタルI/Oへ設定) // GPIOの入出力設定 TRISIO = 0x00; // 全部出力 // Timer0 OPTION_REG = 0x04; // T0CS = 0, T0SE=0, PSA=0, PS<2:0>=0b111; // 初期化 RED_PORT = 1; GREEN_PORT = 0; BLUE_PORT = 0; // 割り込みの設定(割り込みスタート) INTCON = 0xA0; // GIE=1, T0IE=1 while (1) { while (1) { WAIT red_vol++; if (red_vol > 32) { break; } _delay(10000); } while (1) { if (red_vol == 0) { break; } WAIT red_vol--; _delay(10000); } while (1) { WAIT green_vol++; if (green_vol > 32) { break; } _delay(10000); } while (1) { if (green_vol == 0) { break; } WAIT green_vol--; _delay(10000); } while (1) { WAIT blue_vol++; if (blue_vol > 32) { break; } _delay(10000); } while (1) { if (blue_vol == 0) { break; } WAIT blue_vol--; _delay(10000); } while (1) { WAIT red_vol++; if (red_vol > 32) { break; } _delay(10000); } while (1) { WAIT green_vol++; if (green_vol > 32) { break; } if (red_vol == 0) { break; } red_vol--; _delay(10000); } red_vol = 0; while (1) { WAIT blue_vol++; if (blue_vol > 32) { break; } if (green_vol == 0) { break; } green_vol--; _delay(10000); } green_vol = 0; while (1) { WAIT red_vol++; if (red_vol > 32) { break; } if (blue_vol == 0) { break; } blue_vol--; _delay(10000); } blue_vol = 0; while (1) { if (red_vol == 0) { break; } WAIT red_vol--; _delay(10000); } red_vol = 0; } return (EXIT_SUCCESS); }