//----------------------------------------------------------- // Nixie Clock Kennel Method CD11 Version // 2004/01/25 // kennel.org //----------------------------------------------------------- #pragma PROC_CODE_WORD_VAL 0x3ffa #pragma INTERRUPT_LOC 0x04 // 割り込みベクタアドレス #pragma INTERRUPT_SAVE_LOC 0x0c // #include "16F84.h" //***************************** // define //***************************** # define TRUE 1 # define FALSE 0 //-- intcon Bits -- # define intcon_GIE 0x7 # define intcon_EEIE 0x6 # define intcon_T0IE 0x5 # define intcon_INTE 0x4 # define intcon_RBIE 0x3 # define intcon_T0IF 0x2 # define intcon_INTF 0x1 # define intcon_RBIF 0x0 //-- option Bits -- # define option_NOT_RBPU 0x7 # define option_INTEDG 0x6 # define option_T0CS 0x5 # define option_T0SE 0x4 # define option_PSA 0x3 # define option_PS2 0x2 # define option_PS1 0x1 # define option_PS0 0x0 // -- Interrupt bit -- # define RTCC_ZERO intcon_T0IE // 0x20 # define GLOBAL intcon_GIE // 0x80 int tmr0 @ 0x01; int porta @ 0x05; int portb @ 0x06; int intcon @ 0x0B; int option @ 0x81; int trisa @ 0x85; int trisb @ 0x86; // // Global Value // unsigned int digit[6]; int i ,k ,t ,sinc; long ssec, ksec, tsec, dsec, j; //***************************** // Idle Loop //***************************** pause(t) unsigned int t; { unsigned int d; while( t ) { for(d = 0 ; d < 255 ; d++ ); t--; } } // Timer Interrupt Routine (Clock Count Up) __interrupt() { asm(BCF intcon, 0x2); // Clear tmr0 Overflow Flag ssec++; if (ssec >= 3125) { ssec = 0; sinc = 1; dsec++; if (dsec >= 480) { dsec = 0; } } } // Nixie Clock Main (Nixie Dynamic Drive, Setup) main() { // 初期化 ssec = 0; ksec = 0; option = 0x01; // Pullup enable, Prescaler TM0, Scale Factor 4 trisa = 0xff; // Port A all input trisb = 0x0; // Port B all output portb=0; // Clear Port B tmr0 = 0; // 12.8M / 4 * 256 = 3125Hz intcon |= (1 << RTCC_ZERO); // Enable Timer 0 Interrupt intcon |= (1 << GLOBAL); // Enable Interrupt for (i = 0 ; i < 7 ; i++) { digit[i] = 0; } // Main Loop while(TRUE) { for (i = 0 ; i < 5 ; i++) { k = porta; if (k > 7 && i != 4 ) { t = dsec % 8; if (t == 0 || t == 1 || t == 2) { switch (i) { case 0 : j = (digit[0] * 16) + 0; break; case 1 : j = (digit[1] * 16) + 1; break; case 2 : j = (digit[4] * 16) + 2; break; case 3 : j = (digit[5] * 16) + 3; } } else if (t == 3) { switch (i) { case 0 : j = (digit[0] * 16) + 0; break; case 1 : j = (digit[1] * 16) + 1; break; case 2 : j = (digit[3] * 16) + 2; break; case 3 : j = (digit[4] * 16) + 3; } } else if (t == 4 || t == 5 || t == 6 || t == 7) { switch (i) { case 0 : j = (digit[0] * 16) + 0; break; case 1 : j = (digit[1] * 16) + 1; break; case 2 : j = (digit[2] * 16) + 2; break; case 3 : j = (digit[3] * 16) + 3; } } k = k - 8; } else { j = (digit[i+2] * 16) + i; // Display HH:MM } portb = j; if (i != 4) { // Display Dots pause(4); portb = 0xff; } else { tsec = ssec / 4; if (tsec > 521) { tsec = tsec - 391; } else { tsec = 521 - tsec; } for ( j = 1 ; j < tsec ; j++) { } portb = 0xff; for ( j = 1 ; j < (1042 - tsec) ; j++) { } } // 桁上がりチェック if (sinc !=0) { sinc = 0; digit[0]++; if (digit[0] > 9) { digit[0] = 0; digit[1]++; } if (digit[1] > 5) { digit[1] = 0; digit[2]++; } if (digit[2] > 9) { digit[2] = 0; digit[3]++; } if (digit[3] > 5) { digit[3] = 0; digit[4]++; } if (digit[4] > 9) { digit[4] = 0; digit[5]++; } if ((digit[5] > 1) && (digit[4] > 3)) { digit[4] = 0; digit[5] = 0; } } // キーチェック switch(k) { case 3 : digit[0] = 0; digit[1] = 0; break; case 5 : ksec++; if (ksec > 100) { ksec = 0; digit[2]++; if (digit[2] > 9) { digit[2] = 0; digit[3]++; } if (digit[3] > 5) { digit[3] = 0; } } break; case 6: ksec++; if (ksec > 100) { ksec = 0; digit[4]++; if (digit[4] > 9) { digit[4] = 0; digit[5]++; } if ((digit[5] > 1) && (digit[4] > 3)) { digit[4] = 0; digit[5] = 0; } } break; } } } }