/* * pic 10F222 * GP3 入力ボタン * GP0 LED出力 * * ボタンを押すとLEDが点灯・消灯 * ボタン長押し モード切替(LED消灯時に切り替え) *  モード1 LED点灯・消灯 *  モード2 LED点滅・消灯 * モード3 遅延点灯・消灯 * * ボタン押下しながら電源入力 *  押下しない PWM点灯 *  押下しながら 普通の点灯 * */ #include #include #include #pragma config IOSCFS = 4MHZ, MCPU = OFF, WDTE = OFF, CP = OFF, MCLRE = OFF #define _XTAL_FREQ 4000000 int main(void) { ADCON0bits.ANS0 = 0; //GP0 digital I/O ADCON0bits.ANS1 = 0; //GP1 digital I/O OSCCALbits.FOSC4 = 0; //GP2/T0CKI applied to GP2 OPTION = 0b00000000; //wakeup pullup TRISGPIO = 0b00001010; //GP1,GP3 Input unsigned char i; // 汎用 unsigned char startup; // 起動時の状態 unsigned char mode; // 動作モード unsigned int sw_time; // スイッチ押下時間計測用 unsigned char pwm_stat; // PWM動作状態 unsigned char pwm_inc; // PWMサイクル増加 unsigned char pwm_cycle; // PWMサイクル unsigned char pwm_duty; // PWMデューティー比 unsigned char pwm_reso; // PWMぶんかいのう unsigned char led_out; unsigned int led_out_delay; // LED点灯・消灯までの遅延時間 unsigned char led_out_stat; // LED点灯・消灯の判定用(点滅時にしか使わない) GP0 = 0; mode = 0; pwm_stat = 1; pwm_inc = 1; pwm_cycle = 0; pwm_duty = 0; pwm_reso = 150; led_out = 0; led_out_delay = 0; led_out_stat = 0; startup = 0; // 起動時の判定 if( STATUSbits.nPD == 1 ) // 電源投入時 { GP0 = 1; __delay_ms(100); GP0 = 0; if( GP1 == 0 ) // 電源投入時にGP1の状態を判定(結線されているか) { __delay_ms(100); GP0 = 1; __delay_ms(100); GP0 = 0; } } // 通常点灯・PWM点灯 判定 if( GP1 == 0 ) // 電源投入時にGP1の状態を判定(結線されているか) { startup = 1; } while(1){ if( startup == 1 ) // 普通の点灯・消灯(ボタン押しながら起動) { // スイッチ入力待ち if( GP3 == 0 ) { __delay_ms(50); // チャタリング防止 if( GP3 == 0 ) { GP0 = !GP0; // LED消灯・点灯切り替え while( GP3 == 0 ); // スイッチ離すまで待ち __delay_ms(50); // チャタリング防止 } } // LED消灯の時はスリープ if( GP0 == 0 ) { SLEEP(); } } else // PWM点灯・消灯(ボタン押さずに電源起動) { // PWM出力(サイクル) if(pwm_stat == 1) { // LED PWM出力 if( pwm_cycle < pwm_duty ) { GP0 = 1; } else { GP0 = 0; } pwm_cycle++; if( pwm_cycle > pwm_reso ) { pwm_cycle = 0; } } // LED点灯 if( led_out == 1 ) { // PWMサイクルの最初まで待つ if( pwm_cycle == 0 ) { // PWMデューティー比を上げて行く(LED明るくなる) if( pwm_duty < pwm_reso ) { pwm_duty += pwm_inc; // PWMデューティ比を上げる // デューティー比を100%で止める if( pwm_duty == pwm_reso ) { pwm_inc = 0; } } else // PWMデューティ比100%の時 { GP0 = 1; } } } else // LED消灯 { // PWMサイクルの最初まで待つ if( pwm_cycle == 0 ) { // PWMデューティー比を下げる(LED暗くなる) if( pwm_duty > 0 ) { pwm_duty += pwm_inc; // PWMデューティ比を下げる // デューティー比を0%で止める if( pwm_duty == 0 ) { pwm_inc = 0; } } else // PWMデューティー比0%の時 { GP0 = 0; if( mode == 0) SLEEP(); // LED消灯の時はスリープ(通常モード時) } } } // モード別動作 if( mode == 0 ) { led_out_delay = 0; } else if( (mode == 1) && (led_out_stat == 1) ) // 点滅 { if( pwm_inc == 0 ) // デューティー比が0%か100%の時 { led_out = !led_out; if( led_out == 1 ) { pwm_inc = 1; } else { pwm_inc = -1; } } } else if( mode == 2 ) // 遅延 { led_out_delay = 9000; // 大体10秒 } // スイッチ入力待ち if( GP3 == 0 ) { __delay_ms(50); // 押下時のチャタリング防止 if( GP3 == 0 ) { // スイッチ離すまで待ち sw_time = 0; while( GP3 == 0 ) { // スイッチ長押し判定 sw_time++; if( sw_time == 0xFFFF ) { sw_time = 0; // モード切り替え mode++; if( mode > 2 ) { mode = 0; led_out_delay = 0; } // モード切り替え字LED点滅(モード数分) for( i = 0; i < mode + 1; i++ ) { GP0 = 1; __delay_ms(100); GP0 = 0; __delay_ms(100); } led_out = 1; // モード切り替えの時はLED点灯・消灯を切り替えさせないため } } __delay_ms(50); // 離した時のチャタリング防止 // 点灯・消灯切り替え led_out = !led_out; if( led_out == 1 ) { pwm_inc = 1; led_out_stat = 1; } else { pwm_inc = -1; led_out_stat = 0; } // 遅延点灯・消灯用待ち時間 while(led_out_delay > 0) { led_out_delay--; __delay_ms(1); } } } } } }