/* (set tabs to 4) Project; BinClock.c "Black-standard binary clock" using PIC 16F628 v1.2 (converted to C code on 16 June 2009) www.RomanBlack.com This is code to make a binary clock that displays; quarter hours ** hours **** minutes **** using 10 leds. It was converted from and is basically the same operation as my .ASM version of the clock. This binary clock is a little unusual as it only has hours and mins variables, BUT the hours is also "quarter hours" shown as 2 leds in the lower 2 bits of the hours variable. For info on the "Black-standard for binary clock faces" and schematic etc see my web page; www.RomanBlack.com */ //---------------------------------------------------------------------- // config for 16F628 (setup these in C compiler) // use _XT_OSC for 4Mhz, use _HS_OSC for higher xtals. //__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _MCLRE_ON & _BODEN_ON & _LVP_OFF // include // define the main 1-second timer constant (is xtal / 4) // you can also "trim" this value to finely calibrate clock speed; // (increasing the value makes the clock run slower) #define SECOND 1000000 // 4Mhz xtal //#define SECOND 2000000 // 8Mhz xtal //#define SECOND 2500000 // 10Mhz xtal //#define SECOND 4000000 // 16Mhz xtal //#define SECOND 5000000 // 20Mhz xtal // define the debounce count, controls clock "setting" speed. // use a higher value to slow down the clock setting buttons #define DEB_COUNT 5 // 4MHz xtal //#define DEB_COUNT 10 // 8MHz xtal //#define DEB_COUNT 12 // 10MHz xtal //#define DEB_COUNT 20 // 16MHz xtal //#define DEB_COUNT 25 // 20MHz xtal // variables unsigned long bres; // used for bresenham 1second timer unsigned char secs; // 3 vars, binary clock data unsigned char mins; // unsigned char hours; // unsigned char debounce; // counter to time button debounce //---------------------------------------------------------------------- void main() { //--------------------------------------------- // setup the PIC registers etc CMCON = 0b00000111; // set all pins to digital, comparators off PORTA = 0; TRISA = 0b00000000; // PORTA all outs PORTB = 0; TRISB = 0b11000000; // RB7 is "set mins", RB6 is "set hours" OPTION_REG = 0b00000111; // pullups ON, TMR0 prescaled at 256:1 VRCON = 0; // turn off stuff we don't use PIE1 = 0; T1CON = 0; T2CON = 0; CCP1CON = 0; INTCON = 0; // no interrupts used //--------------------------------------------- // setup variables bres = SECOND; // so clock start immediately secs = 0; mins = 0; hours = 4; // is also quarter hours, so 4 = 1:00 when clock starts //--------------------------------------------- // main running loop here // all we do is wait for TMR0 to overflow, then use a // bresenham clock system to generate 1 second events. // TMR0 is at 256:1 prescaler // and also check the clock set buttons. while(1) { if(INTCON.T0IF) // if TMR0 overflowed { INTCON.T0IF = 0; bres += 65536; // add 65536 ticks (256*256 ticks) if(bres >= SECOND) // if we reached 1 second! { bres -= SECOND; // subtract a second // gets here every second, so update clock. secs++; if(secs >= 60) { secs = 0; mins++; if(mins >= 15) // if >= quarter hour { mins = 0; hours++; // this var is quarters AND hours if(hours >= 52) // if >= 13:00 { hours = 4; // reset back to 1:00 } } } // display the new clock value PORTA = mins; PORTB = hours; } // gets here every 65536 ticks, so check the "set" buttons debounce++; if(debounce >= DEB_COUNT) // DEB_COUNT sets the update speed { debounce = 0; // "set hours" button if(!PORTB.F6) // lo = pressed { hours++; // so inc the hours if(hours >= 52) hours = 4; PORTB = hours; // display the new hours } // "set minutes" button if(!PORTB.F7) // lo = pressed { mins++; // so inc the mins if(mins >= 15) mins = 0; secs = 0; // also reset the seconds PORTA = mins; // display the new mins } } } } } //----------------------------------------------------------------------