/* *グリーテイングカードライト用プログラム(紙のホワイトステージを使ったインテリアライト) * * PIC 16F628A * 発信器:内臓4MHz * 電源:乾電池3本(4.5V) * RB1,2は白、  RB4,5は赤、 RB6は黄色(点灯パターンインジケータ) * RA0は緑、RA1は青、RA2は白(小 天井灯) * RB0はスイッチ(割り込み)、RB3はPWM、RB7 はCds(wake up用) * Device Flags: _BODEN_OFF _BOREN_OFF _CP_OFF _PWRTE_ON _WDT_OFF *        _LVP_OFF _MCLRE_OFF _INTRC_OSC_NOCLKOUT * 言語 MikroC v7.0.0.3 */ //プロトタイプ宣言 unsigned int i; unsigned int m; unsigned int act_select; void my_Pwm_Change_Duty(unsigned int duty_ratio); void good_sleep(); void my_Pwm(); void my_Pwm_Fast(); void my_Pwm_Dark(); void my_Pwm_Very_Dark(); //メインプログラム void main() { act_select = 1; PORTA = 0b00000000; PORTB = 0b00000000; TRISA = 0b00000000; TRISB = 0b10000001; //PORTBをRB0, RB7を入力に設定 Pwm_Init(5000); Delay_ms(500); OPTION_REG.INTEDG = 0; //立ち下りエッジで割り込み PORTB.F6 = 1; Delay_ms(500); PORTB.F6 = 0;//電源ONの点灯 do{ if(PORTB.F7 == 1) { //明るければスリープへ(昼間は動作しない) good_sleep(); } INTCON.INTE = 1; //RB0/INT割り込み許可 INTCON.GIE = 1; //全体割り込み許可 if (act_select == 1){ //速い点滅(白X2) PORTB.F1 = 1;PORTB.F2 = 1; my_Pwm_Fast(); PORTB.F1 = 0;PORTB.F2 = 0; } if (act_select == 2){ //速い点滅(赤X2) PORTB.F4 = 1;PORTB.F5 = 1; my_Pwm_Fast(); PORTB.F4 = 0;PORTB.F5 = 0; } if (act_select == 3){ //ゆっくり点滅(白X2) PORTB.F1 = 1;PORTB.F2 = 1; my_Pwm(); PORTB.F1 = 0;PORTB.F2 = 0; } if (act_select == 4){ //ゆっくり点滅(赤X2) PORTB.F4 = 1;PORTB.F5 = 1; my_Pwm(); PORTB.F4 = 0;PORTB.F5 = 0; } if (act_select == 5){ //ゆっくり点滅(白小X1) PORTA.F2 = 1; my_Pwm(); PORTA.F2 = 0; } if (act_select == 6){ //ゆっくり暗く点滅(白小X1) PORTA.F2 = 1; my_Pwm_Dark(); PORTA.F2 = 0; } if (act_select == 7){ //ゆっくり点滅(白X1,緑x1) PORTA.F0 = 1; PORTB.F1 = 1; my_Pwm(); PORTA.F0 = 0; PORTB.F1 = 0; } if (act_select == 8){ //ゆっくり点滅(白X1,青x1) PORTA.F1 = 1; PORTB.F1 = 1; my_Pwm(); PORTA.F1 = 0; PORTB.F1 = 0; } if (act_select == 9){ //ゆっくり暗く点滅(白X1) PORTB.F1 = 1;PORTB.F2 = 1; my_Pwm_Dark(); PORTB.F1 = 0;PORTB.F2 = 0; } if (act_select == 10){ //ゆっくりさらに暗く点滅(白X1) PORTB.F1 = 1;PORTB.F2 = 1; my_Pwm_Very_Dark(); PORTB.F1 = 0;PORTB.F2 = 0; } } while(1); } //メインプログラム終わり //割込み関数 //プッシュスイッチで照明パターンをかえる。 //パターン番号(act_select)ををLED点滅回数で知らせる。 void interrupt() { INTCON.GIE = 0; //すべての割り込み禁止(この行は非常に重要!!!) if (INTCON.INTF==1) { //割込み種がRB0/INT割込みの場合 act_select = act_select + 1; if (act_select > 10) { act_select = 1; } for(m=0; m < act_select; m++) { PORTB.F6 = 1;Delay_ms(80);PORTB.F6 = 0;Delay_ms(150); } INTCON.INTF = 0; //割込みフラグクリア(この位置は重要!) } INTCON.GIE = 1; //全体割り込み許可 } //PWMを1024分解能に設定する関数(***PicとMikroC http://kuri6005.sakura.ne.jp/pic/ から引用***) void my_Pwm_Change_Duty(unsigned int duty_ratio) { // duty_ratio:0〜1023 0:Min 1023:Max //duty_ratio上位8ビットをCCPR1Lレジスタへ格納 CCPR1L = duty_ratio >> 2; //duty_ratio下位2ビットをCCP1CONレジスタの6,7ビットへ格納 CCP1CON.F6 = duty_ratio & 0b00000001; CCP1CON.F7 = (duty_ratio & 0b00000010) >> 1; } //省電力モードの関数 void good_sleep() { // GPIO.F3のポート状態変化で目覚めるスリープ関数 INTCON = 0; //すべての割り込み禁止(この行は非常に重要!!!) Delay_ms(400); INTCON.RBIE = 1; //ポート状態変化割り込み許可 INTCON.INTE = 1; //RB0/INT割り込み許可 sleep_start: asm{ //ここからアセンブラプログラム nop nop nop nop sleep nop nop nop nop //ここまでアセンブラプログラム } PORTB.F4 = PORTB.F4; INTCON.RBIE = 0;//ポート状態変化割り込み禁止 INTCON.INTE = 0; //割込みフラグクリア INTCON.RBIF = 0; //ポート状態変化割り込みフラグをクリア INTCON.INTF = 0; //割込みフラグクリア Delay_ms(300); //この待ち時間は重要! INTCON.GIE = 1; //全体割り込み許可 } //ゆっくり徐々に duty ratio を増減する関数 void my_Pwm() { Pwm_Start(); //PWM機能の起動 for(i = 1; i < 70; i++) { my_Pwm_Change_Duty(i); Delay_ms(100); } for(i = 70; i < 600; i++) { my_Pwm_Change_Duty(i); Delay_ms(15); } for(i = 0; i < 530; i++) { my_Pwm_Change_Duty(599-i); Delay_ms(15); } for(i = 530; i < 599; i++) { my_Pwm_Change_Duty(599-i); Delay_ms(100); } } //やや速く徐々に duty ratio を増減する関数 void my_Pwm_Fast() { Pwm_Start(); //PWM機能の起動 for(i = 1; i < 70; i++) { my_Pwm_Change_Duty(i); Delay_ms(20); } for(i = 70; i < 600; i++) { my_Pwm_Change_Duty(i); Delay_ms(3); } for(i = 0; i < 530; i++) { my_Pwm_Change_Duty(599-i); Delay_ms(3); } for(i = 530; i < 599; i++) { my_Pwm_Change_Duty(599-i); Delay_ms(20); } } // 1024分の70を限度に徐々に duty ratio を増減する関数 void my_Pwm_Dark() { Pwm_Start(); //PWM機能の起動 for(i = 6; i < 70; i++) { my_Pwm_Change_Duty(i); Delay_ms(700); } for(i = 69; i > 5; i--) { my_Pwm_Change_Duty(i); Delay_ms(700); } } // 1024分の20を限度に徐々に duty ratio を増減する関数 void my_Pwm_Very_Dark() { Pwm_Start(); //PWM機能の起動 for(i = 6; i < 20; i++) { my_Pwm_Change_Duty(i); Delay_ms(2500); } for(i = 19; i > 5; i--) { my_Pwm_Change_Duty(i); Delay_ms(2500); } }