#include <16f690.h>
#fuses INTRC_IO, NOWDT, PROTECT, PUT, BROWNOUT, MCLR, NOIESO, NOFCMEN
//INTRC_IO:内部クロックを使用する ピンはIOで使用可能
//NOWDT:ウォッチドッグ・タイマーを使用しない
//PROTECT:コード・プロテクトする
//PUT:パワーアップ・タイマーを使用する
//BROWNOUT:ブラウンアウト・リセットを使用する
//MCLR:MCLRピンを有効にする
//NOIESO:クロックの内部外部切替を無効にする
//NOFCMEN:クロックの監視を無効にする
//内部クロック8MHz
#use delay(clock=8000000)
//フォトカプラ(出力)
#define SW3 PIN_C0
#define SW4 PIN_C1
#define SW5 PIN_C2
#define SW8 PIN_B4
#define SW9 PIN_B5
#define SW10 PIN_B6
//7segLED(出力)
#define LED_LT PIN_C7 //F-9
#define LED_LB PIN_A4 //E-1
#define LED_CT PIN_C3 //A-7
#define LED_CM PIN_A5 //G-10
#define LED_CB PIN_C5 //D-2
#define LED_RT PIN_C6 //B-6
#define LED_RB PIN_C4 //C-4
//7segLED 点灯:0V 消灯:5V
#define LED_ON 0
#define LED_OFF 1
//送信スイッチ(入力)INT兼用
#define SW_SEND PIN_A2
//シフトインターバル時間設定スイッチ
#define SW_INTERVAL PIN_B7
//スイッチ ON:0V OFF:5V
//送信スイッチ 時間設定スイッチ用
#define SW_ON 0
#define SW_OFF 1
//グローバル変数、定数宣言
#define MAX_EEPROM 0x100 //最大アドレス(0xFF:256バイト)
#define MAX_SLEEPCOUNT 20 //2周分
int IntervalSec; //インターバル(秒)
int SleepCount; //スリープカウンタ
//プロトタイプ
void init(void);
int led_shift(int);
void led_display(int, int);
void led_flash(int, int, int);
void swSend(int);
/*********************************
* INT割り込み処理
*********************************/
#int_ext
void ext_isr(void)
{
delay_ms(10);
}
/*********************************
* 初期化関数
*********************************/
void init(void)
{
setup_oscillator(OSC_8MHZ); //内部クロックを8MHzにする
setup_adc_ports(NO_ANALOGS); //全ピンをデジタルIOモードにする
setup_comparator(nc_nc_nc_nc); //コンパレータは動作しない
//フォトスイッチ OFF
output_high(SW3);
output_high(SW4);
output_high(SW5);
output_high(SW8);
output_high(SW9);
output_high(SW10);
//7segLED 消灯
output_high(LED_LT);
output_high(LED_LB);
output_high(LED_CT);
output_high(LED_CM);
output_high(LED_CB);
output_high(LED_RT);
output_high(LED_RB);
//インターバル秒数を、EEPROMから読み込み
IntervalSec = read_eeprom(0);
//4,6,8秒、停止(10)以外なら、2秒にセット
if ((IntervalSec != 4) && (IntervalSec != 6) && (IntervalSec != 8) && (IntervalSec != 10))
IntervalSec = 2; //2秒(初期値)
led_flash(IntervalSec, 2, 250);
SleepCount = 0;
}
/*********************************
* メイン
*********************************/
void main(void)
{
int swNum; //送信スイッチナンバー
init();
//スイッチ番号を設定
//シフト停止の場合、前回の番号を読み込み
if (IntervalSec == 10) {
swNum = read_eeprom(1);
} else {
swNum = 1;
}
//グローバル割り込み許可
enable_interrupts(GLOBAL); //グローバル割り込み許可
while (1) {
//割り込み許可
enable_interrupts(INT_EXT); //INT(RA2)割り込み許可
//割り込み設定
ext_int_edge(H_TO_L); //INT立下がりエッジ指定
if (SleepCount >= MAX_SLEEPCOUNT) {
led_display(0, LED_OFF); //7segLED消灯
//送信スイッチを押すと、スリープ解除
sleep();
//割り込み設定
ext_int_edge(L_TO_H); //INT立上がりエッジ指定
//送信スイッチを離すと、スリープ解除
sleep();
SleepCount = 0;
}
//割り込み禁止
disable_interrupts(INT_EXT); //INT(RA2)割り込み禁止
//7segLEDシフト
swNum = led_shift(swNum);
SleepCount++;
}
}
/*********************************
* 7segLEDシフト
*********************************/
int led_shift(int swNum)
{
int swSendFlag;
long count, c_max;
int result;
if (IntervalSec == 10) {
c_max = (long)IntervalSec * 15;
} else {
c_max = (long)IntervalSec * 100;
}
count = 0;
//送信可にフラグをセットする
swSendFlag = 1;
//7segLED点灯
led_display(swNum, LED_ON);
while (count < c_max) {
//送信スイッチが押されていたら送信する
if (input(SW_SEND) == SW_ON) {
delay_ms(20); //チャタリング防止時間かせぎ 20ms
//送信スイッチが押されているか、もう一度チェック
if (input(SW_SEND) == SW_ON) {
//送信スイッチを押し続けても、一回しか送信しないようにする処理
if (swSendFlag == 1) {
//送信実行
swSend(swNum);
//送信実行したら、カウンターをリセットする
count = 0;
SleepCount = 0;
swSendFlag = 0; //送信不可にフラグをセットする
}
}
//送信スイッチが押されてない場合
} else {
//送信スイッチを離したら、送信可にフラグをセットする
swSendFlag = 1;
count++;
delay_ms(10);
//インターバル変更(2,4,6,8秒,停止)
if (input(SW_INTERVAL) == SW_ON) {
delay_ms(20); //チャタリング防止時間かせぎ 20ms
//インターバル変更スイッチが押されているか、もう一度チェック
if (input(SW_INTERVAL) == SW_ON) {
IntervalSec += 2;
if (IntervalSec > 10) {
IntervalSec = 2;
}
//7segLED Flash
led_flash(IntervalSec, 2, 250);
//7segLED点灯
led_display(swNum, LED_ON);
//インターバル秒数を、EEPROMに書き込み
write_eeprom(0, IntervalSec);
if (IntervalSec == 10) {
//シフト停止する番号を、EEPROMに書き込み
write_eeprom(1, swNum);
c_max = (long)IntervalSec * 15; //30秒
} else {
c_max = (long)IntervalSec * 100;
}
count = 0;
SleepCount = 0;
}
}
}
}
if (IntervalSec == 10) {
result = swNum;
} else {
if (swNum == 10) {
result = 1;
} else {
result = swNum + 1;
}
}
return result;
//7segLED消灯
//led_display(swNum, LED_OFF);
}
/*********************************
* 7segLED表示
*********************************/
void led_display(int swNum, int led_on_off)
{
if (led_on_off == LED_ON) {
//7segLED点灯
switch (swNum) {
case 1: //No1
output_high(LED_LT);
output_high(LED_LB);
output_high(LED_CT);
output_high(LED_CM);
output_high(LED_CB);
output_low(LED_RT);
output_low(LED_RB);
break;
case 2: //No2
output_high(LED_LT);
output_low(LED_LB);
output_low(LED_CT);
output_low(LED_CM);
output_low(LED_CB);
output_low(LED_RT);
output_high(LED_RB);
break;
case 3: //No3
output_high(LED_LT);
output_high(LED_LB);
output_low(LED_CT);
output_low(LED_CM);
output_low(LED_CB);
output_low(LED_RT);
output_low(LED_RB);
break;
case 4: //No4
output_low(LED_LT);
output_high(LED_LB);
output_high(LED_CT);
output_low(LED_CM);
output_high(LED_CB);
output_low(LED_RT);
output_low(LED_RB);
break;
case 5: //No5
output_low(LED_LT);
output_high(LED_LB);
output_low(LED_CT);
output_low(LED_CM);
output_low(LED_CB);
output_high(LED_RT);
output_low(LED_RB);
break;
case 6: //No6
output_low(LED_LT);
output_low(LED_LB);
output_low(LED_CT);
output_low(LED_CM);
output_low(LED_CB);
output_high(LED_RT);
output_low(LED_RB);
break;
case 7: //No7
output_low(LED_LT);
output_high(LED_LB);
output_low(LED_CT);
output_high(LED_CM);
output_high(LED_CB);
output_low(LED_RT);
output_low(LED_RB);
break;
case 8: //No8
output_low(LED_LT);
output_low(LED_LB);
output_low(LED_CT);
output_low(LED_CM);
output_low(LED_CB);
output_low(LED_RT);
output_low(LED_RB);
break;
case 9: //No9
output_low(LED_LT);
output_high(LED_LB);
output_low(LED_CT);
output_low(LED_CM);
output_low(LED_CB);
output_low(LED_RT);
output_low(LED_RB);
break;
case 10: //No10(0を表示)
output_low(LED_LT);
output_low(LED_LB);
output_low(LED_CT);
output_high(LED_CM);
output_low(LED_CB);
output_low(LED_RT);
output_low(LED_RB);
break;
}
} else {
output_high(LED_LT);
output_high(LED_LB);
output_high(LED_CT);
output_high(LED_CM);
output_high(LED_CB);
output_high(LED_RT);
output_high(LED_RB);
}
}
/*********************************
* 7segLED Flash
*********************************/
void led_flash(int num, int flash, int d_time)
{
int i;
for(i = 0; i < flash; i++) {
//7segLED点灯
led_display(num, LED_ON);
delay_ms(d_time);
//7segLED消灯
output_high(LED_LT);
output_high(LED_LB);
output_high(LED_CT);
output_high(LED_CM);
output_high(LED_CB);
output_high(LED_RT);
output_high(LED_RB);
delay_ms(d_time);
}
}
/*********************************
* 送信
*********************************/
void swSend(int swNum)
{
if (swNum == 1) {
output_low(SW3);
output_low(SW4);
output_low(SW5);
output_low(SW8);
} else if (swNum == 2) {
output_low(SW3);
output_low(SW4);
output_low(SW8);
output_low(SW9);
} else if (swNum == 3) {
output_low(SW3);
} else if (swNum == 4) {
output_low(SW4);
} else if (swNum == 5) {
output_low(SW5);
} else if (swNum == 6) {
output_low(SW3);
output_low(SW4);
output_low(SW9);
output_low(SW10);
} else if (swNum == 7) {
output_low(SW3);
output_low(SW4);
output_low(SW10);
output_low(SW5);
} else if (swNum == 8) {
output_low(SW8);
} else if (swNum == 9) {
output_low(SW9);
} else if (swNum == 10) {
output_low(SW10);
}
delay_ms(70);
output_high(SW3);
output_high(SW4);
output_high(SW5);
output_high(SW8);
output_high(SW9);
output_high(SW10);
}