/////////////////////////////////////////////////////////////////////////////// // ロータリー・クロック(Ver.1.0) // for CCS C Compiler // 2007.1.17 //............................................................................. // // 無許可転載・転用を禁止します。 // 転載・転用許可は必ず office@nixie-tube.com までご連絡ください。 // Copyright 2006(C)nixie-tube.com. All rights Reserved. // Never reproduce or republicate without written permission. // // 万一、このプログラムを使用した結果に生じた損害などは一切補償いたしません。 // //............................................................................. // 関連情報などは下記よりお越しください。 // http://nixie-tube.com/cq // 携帯専用サイトからもどうぞ // http://nixie-tube.com/shop/m //............................................................................. #include <16F648A.h> #FUSES NOWDT //No Watch Dog Timer #FUSES HS //High speed Osc (> 4mhz) #FUSES NOPUT //No Power Up Timer #FUSES NOPROTECT //Code not protected from reading #FUSES NOBROWNOUT //No brownout reset #FUSES NOMCLR //Master Clear pin used for I/O #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O #FUSES NOCPD //No EE protection #use delay(clock=20000000) #use I2C(MASTER, SDA = PIN_B6, SCL = PIN_B7) int num_buffer[6] = {0,0,0,0,0,0}; int sec,min,hour,day,date,month,year; int set_flag = 0; #define ACK 1 #define NACK 0 //.................................................................... #define switch_plus_one PIN_A3 #define switch_set PIN_A4 #define switch_triger PIN_A5 //.................................................................... //.................................................................... // フォントの定義 int const led_seg[10][5] = { {0x07,0x05,0x05,0x05,0x07} //0 {0x02,0x02,0x02,0x02,0x02} //1 {0x07,0x01,0x07,0x04,0x07} //2 {0x07,0x01,0x07,0x01,0x07} //3 {0x05,0x05,0x07,0x01,0x01} //4 {0x07,0x04,0x07,0x01,0x07} //5 {0x07,0x04,0x07,0x05,0x07} //6 {0x07,0x01,0x01,0x01,0x01} //7 {0x07,0x05,0x07,0x05,0x07} //8 {0x07,0x05,0x07,0x01,0x07} //9 }; //.................................................................... //.................................................................... /// PICの初期設定 void init_setup() { setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); setup_oscillator(False); } //.................................................................... //.................................................................... // 対応するLEDを点灯する void led_on(int digit) { switch(digit) { case 0:{ OUTPUT_B(0b00000001); OUTPUT_A(0b00000001); return; } case 1:{ OUTPUT_B(0b00000010); OUTPUT_A(0b00000001); return; } case 2:{ OUTPUT_B(0b00000100); OUTPUT_A(0b00000001); return; } case 3:{ OUTPUT_B(0b00001000); OUTPUT_A(0b00000001); return; } case 4:{ OUTPUT_B(0b00010000); OUTPUT_A(0b00000001); return; } case 5:{ OUTPUT_B(0b00100000); OUTPUT_A(0b00000001); return; } case 6:{ OUTPUT_B(0b00000001); OUTPUT_A(0b00000010); return; } case 7:{ OUTPUT_B(0b00000010); OUTPUT_A(0b00000010); return; } case 8:{ OUTPUT_B(0b00000100); OUTPUT_A(0b00000010); return; } case 9:{ OUTPUT_B(0b00001000); OUTPUT_A(0b00000010); return; } case 10:{ OUTPUT_B(0b00010000); OUTPUT_A(0b00000010); return; } case 11:{ OUTPUT_B(0b00100000); OUTPUT_A(0b00000010); return; } case 12:{ OUTPUT_B(0b00000001); OUTPUT_A(0b00000100); return; } case 13:{ OUTPUT_B(0b00000010); OUTPUT_A(0b00000100); return; } case 14:{ OUTPUT_B(0b00000100); OUTPUT_A(0b00000100); return; } case 15:{ OUTPUT_B(0b00001000); OUTPUT_A(0b00000100); return; } case 16:{ OUTPUT_B(0b00010000); OUTPUT_A(0b00000100); return; } case 17:{ OUTPUT_B(0b00100000); OUTPUT_A(0b00000100); return; } default:{ OUTPUT_B(0b00000000); OUTPUT_A(0b00000000); return; } } } //.................................................................... //.................................................................... // RTCの初期化&時刻をセット void rtc_init() { i2c_start(); sec = 0; min = (num_buffer[3]*0x10) + num_buffer[2]; hour = (num_buffer[5]*0x10) + num_buffer[4]; i2c_write(0xd0); i2c_write(0x00); //Address i2c_write(sec); //Sec i2c_write(min); //Min i2c_write(hour); //Hour i2c_write(1); //Day (sun day =1) i2c_write(0x17); //Date i2c_write(0x01); //Month i2c_write(0x07); //Year i2c_write(0x00); i2c_stop(); } //.................................................................... //.................................................................... // 現在時刻を取得 void read_rtc() { int rx; i2c_start(); i2c_write(0xd0); i2c_write(0x00); i2c_start(); i2c_write(0xd1); sec = i2c_read(ACK);//sec min = i2c_read(ACK);//min hour = i2c_read(ACK);//hour day = i2c_read(ACK);//day date = i2c_read(ACK);//date month = i2c_read(ACK);//month year = i2c_read(NACK);//year i2c_stop(); num_buffer[0] = sec & 0x0f; num_buffer[1] = (sec & 0xf0)>>4; num_buffer[2] = min & 0x0f; num_buffer[3] = (min & 0xf0)>>4; num_buffer[4] = hour & 0x0f; num_buffer[5] = (hour & 0xf0)>>4; if((sec & 0x80) == 0x80){ hour = 0; min = 0; sec = 0; rtc_init(); } } //.................................................................... //.................................................................... // 時刻を表示 void disp_time() { int y, z = 4 ,buf; long t; for(y=0;y<5;y++){ for(t=0;t<0x80;t++){ //0-1 buf = led_seg[num_buffer[0]][z] + ((led_seg[num_buffer[1]][z]) << 3); OUTPUT_B(buf); OUTPUT_A(0b00000001); delay_us(5); OUTPUT_A(0b00000000); delay_us(5); //2-3 buf = led_seg[num_buffer[2]][z] + ((led_seg[num_buffer[3]][z]) << 3); OUTPUT_B(buf); OUTPUT_A(0b00000010); delay_us(5); OUTPUT_A(0b00000000); delay_us(5); //4-5 buf = led_seg[num_buffer[4]][z] + ((led_seg[num_buffer[5]][z]) << 3); OUTPUT_B(buf); OUTPUT_A(0b00000100); delay_us(5); OUTPUT_A(0b00000000); delay_us(5); } z--; } } //.................................................................... //.................................................................... // テストプログラム(LEDを左右に1往復) void test_a() { int x, y = 17; for(x=0;x<18;x++){ led_on(x); delay_ms(20); } for(x=0;x<18;x++){ led_on(y); delay_ms(20); y--; } led_on(19); } //.................................................................... //.................................................................... // テストプログラム(LEDで秒を表示) void test_b() { int sec_0, sec_10; while(1) { if(input(switch_triger) == 1){ return; } read_rtc(); sec_0 = num_buffer[0]; sec_10 = num_buffer[1] + 12; led_on(sec_0); delay_ms(5); led_on(sec_10); delay_ms(5); led_on(19); } } //.................................................................... //.................................................................... // 対応する位の時刻を+1する void add_time(int set_flag) { switch(set_flag) { case 1: //set hour 10 { if(num_buffer[5] >= 2){ num_buffer[5] = 0; } else{ num_buffer[5]++; } return; } case 2: //set hour 1 { if(num_buffer[5] == 2){ if(num_buffer[4] >= 3){ num_buffer[4] = 0; } else{ num_buffer[4]++; } return; } else{ if(num_buffer[4] >= 9){ num_buffer[4] = 0; } else{ num_buffer[4]++; } return; } } case 3: //set min 10 { if(num_buffer[3] >= 5){ num_buffer[3] = 0; } else{ num_buffer[3]++; } return; } case 4: //set min 1 { if(num_buffer[2] >= 9){ num_buffer[2] = 0; } else{ num_buffer[2]++; } return; } default: {return;} } } //.................................................................... //.................................................................... // 時刻セット void set_time() { int read_rtc_flag = 0; while(1) { if(input(switch_set) == 0){ //set button on? delay_ms(10); if(input(switch_set) == 0){ while(1) { if(input(switch_set) == 1){ set_flag++; break; } } } } if(input(switch_plus_one) == 0){ delay_ms(10); if(input(switch_plus_one) == 0){ while(1) { if(input(switch_plus_one) == 1){ if(set_flag != 0){ add_time(set_flag); break; } else{ //set 00 sec read_rtc(); sec = 0; rtc_init(); test_a(); test_b(); break; } } } } } switch(set_flag) { case 0: { return; //時刻セットモードではないので何もせずにreturn } case 1: //set hour 10 { if(read_rtc_flag == 0){ read_rtc(); read_rtc_flag = 1; } led_on(num_buffer[5]); delay_ms(5); led_on(17); delay_ms(5); led_on(19); //LED off continue; } case 2: //set hour 1 { led_on(num_buffer[4]); delay_ms(5); led_on(16); delay_ms(5); led_on(19); //LED off continue; } case 3: //set min 10 { led_on(num_buffer[3]); delay_ms(5); led_on(15); delay_ms(5); led_on(19); //LED off continue; } case 4: //set min 1 { led_on(num_buffer[2]); delay_ms(5); led_on(14); delay_ms(5); led_on(19); //LED off continue; } case 5: //set sec = 00 { set_flag = 0; rtc_init(); return; } } } } //.................................................................... //.................................................................... void main() { int x; init_setup(); test_a(); test_a(); test_b(); while(1) { set_time(); if(input(switch_triger) == 0){ //トリガーを検知したら時刻を取得し、それを表示する read_rtc(); disp_time(); } } } //....................................................................