『赤外線リモコン作成 (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);
}
}
