//----------------------------------------------------------- // Nixie Clock Kennel Method // 2003/02/28 // 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, j, sinc; long ssec, psec, ksec; //***************************** // 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++; psec++; if (psec >= 6250) { psec = 0; } if (ssec >= 3125) { ssec = 0; sinc = 1; } } // Nixie Clock Main (Nixie Dynamic Drive, Setup) main() { // 初期化 ssec = 0; psec = 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 < 6 ; i++) { j = (digit[i] * 16) + i; // DPコントロールによる振り子 switch(i){ case 0 : if (((5250 > psec) && (4125 < psec)) || ((4875 > psec) && (3750 < psec))) { j = j + 8; } break; case 1 : if (((4000 > psec) && (3250 < psec)) || ((5750 > psec) && (5000 < psec))) { j = j + 8; } break; case 2 : if (((3500 > psec) && (3250 < psec)) || ((6000 > psec) && (5875 < psec)) || ((3125 > psec) && (2750 < psec)) || ((5750 > psec) && (5500 < psec))) { j = j + 8; } break; case 3 : if ((( 375 > psec) && ( 0 < psec)) || ((3125 > psec) && (2750 < psec)) || ((2625 > psec) && (2375 < psec)) || ((6250 > psec) && (5875 < psec))) { j = j + 8; } break; case 4 : if ((( 875 > psec) && ( 125 < psec)) || ((2625 > psec) && (1875 < psec))) { j = j + 8; } break; case 5 : if (((2125 > psec) && (1000 < psec)) || ((1750 > psec) && ( 625 < psec))) { j = j + 8; } break; } portb = j; pause(4); portb = 0xff; // 桁上がりチェック 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; } } // キーチェック j = porta; switch(j) { 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; } } } }