『赤外線リモコン作成 (TVの「d」ボタンが壊れたため)』で作成したリモコンが不要となったので、回路を有効活用するためにシーリングライト照明用にプログラムをすこし変更した。
回路
PIC12F1822 プログラム
/* * 赤外線リモコン 簡易送信機 * File: main.c * * Created on 2016/02/13, 19:50 */ #include <stdio.h> #include <stdlib.h> #define EEPROM_SIZE 256 #include <xc.h> // Generated with MPLABX (Window menu - PIC memory views - 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 disabled) #pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled) #pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input) #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 = OFF // Brown-out Reset Enable (Brown-out Reset disabled) #pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) #pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled) // CONFIG2 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config PLLEN = OFF // PLL Enable (4x PLL disabled) #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) #pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), high trip point selected.) #pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) #ifndef _XTAL_FREQ /* 例:4MHzの場合、4000000 をセットする */ #define _XTAL_FREQ 4000000 #endif /* * 赤外線発信時間(マイクロ秒)の定義:家電協フォーマット版 */ #define TIMING_START_HI 3500 #define TIMING_START_LO 1600 #define TIMING_SIGNAL_HI 540 #define TIMING_SIGNAL_1_LO 1200 #define TIMING_SIGNAL_0_LO 360 /* * パナソニックのシーリングライトのリモコンデータ(CH2版) */ // メーカーコード unsigned char code_maker1 = 0x34; unsigned char code_maker2 = 0x4A; // 点灯 unsigned char code_01_3 = 0x90; unsigned char code_01_4 = 0xAC; unsigned char code_01_5 = 0x3C; // 全灯 unsigned char code_02_3 = 0x90; unsigned char code_02_4 = 0x2C; unsigned char code_02_5 = 0xBC; // 常夜灯 unsigned char code_03_3 = 0x90; unsigned char code_03_4 = 0x6C; unsigned char code_03_5 = 0xFC; // 消灯 unsigned char code_04_3 = 0x90; unsigned char code_04_4 = 0xEC; unsigned char code_04_5 = 0x7C; /* * PWMで赤外線コード送信 * * @param c 送信するコード */ void decode_bit(unsigned char c) { for (int i = 0; i < 8; i++) { if (c & (0x80 >> i)) { // PORTAbits.RA2 = 1; // ← 単なる矩形波ではダメな例 CCP1CON = 0b00001100; __delay_us(TIMING_SIGNAL_HI); // PORTAbits.RA2 = 0; CCP1CON = 0b00000000; __delay_us(TIMING_SIGNAL_1_LO); } else { CCP1CON = 0b00001100; __delay_us(TIMING_SIGNAL_HI); CCP1CON = 0b00000000; __delay_us(TIMING_SIGNAL_0_LO); } } } /* * mainエントリー関数 */ int main(int argc, char** argv) { // 基本機能の設定 OSCCON = 0b01101010; // 内部オシレーター 4MHz TRISA = 0b00001000; // IOポートRA0〜RA5を出力モード(ただしRA3は入力専用) ANSELA = 0b00000000; // A/D変換をAN0,AN1,AN2,AN4を無効 PORTA = 0; CCP1SEL = 0; // RA2をCCP1(PWM)のP1Aで用いる CCP1CON = 0b00000000; // PWM(シングル) T2CON = 0b00000000; // TMR2プリスケーラ値を1倍に設定, Timer2はこの時点ではOFF // PR2 = Fosc / (Fpwm * 4 * Prescale) + 1 = 4000000 / (38000 * 4 * 1) + 1 = 27 PR2 = 0x19; // 経験値より27ではなく25とする CCPR1L = 0x08; // PR2=0x19の場合デューティ値は6bit CCPR1H = 0; TMR2 = 0; // Timer2カウンタを0 // EEPROMより発信信号の種類をロード(0x01:点灯, 0x02:全灯, 0x03:常夜灯, 0x04:消灯) unsigned char config_mode = (unsigned char) eeprom_read(0); if (config_mode < 0x01 || 0x04 < config_mode) { config_mode = 0x01; } __delay_ms(1); // EEPROMに次回の発信信号の種類を書き込み(電源を入れる毎、次の信号が出るようにする) unsigned char config_mode_next = config_mode + 1; if (0x04 < config_mode_next) { config_mode_next = 0x01; } eeprom_write(0, (unsigned char) config_mode_next); // PWM開始 TMR2ON = 1; // 0.05秒待つ __delay_ms(50); // 通電中は、赤外線信号を送信し続ける for (;;) { // スタートビット(リーダ) CCP1CON = 0b00001100; __delay_us(TIMING_START_HI); CCP1CON = 0b00000000; __delay_us(TIMING_START_LO); // 送信データ本体 decode_bit(code_maker1); decode_bit(code_maker2); switch (config_mode) { case 0x01: decode_bit(code_01_3); decode_bit(code_01_4); decode_bit(code_01_5); break; case 0x02: decode_bit(code_02_3); decode_bit(code_02_4); decode_bit(code_02_5); break; case 0x03: decode_bit(code_03_3); decode_bit(code_03_4); decode_bit(code_03_5); break; case 0x04: decode_bit(code_04_3); decode_bit(code_04_4); decode_bit(code_04_5); break; } // ストップビット(トレーラ) CCP1CON = 0b00001100; __delay_us(TIMING_SIGNAL_HI); CCP1CON = 0b00000000; __delay_us(TIMING_SIGNAL_HI); __delay_ms(20); } }