Code:
Can you read binary ?
Made by my dear collegue Dick Goossens as a PIC programming tutorial project. You can buy a similar clock at www.thinkgeek.com, but this one is much cooler !
I've to build a nice box around it and a power supply. The coolest thing still has to come: use a webcam to show it 'ticking' away !
/*-------------------------------------------------------------------
*
* Product/Project : TestClock
* Program language: PICC C
* Author : Dick Goossens
*
* %name: clock.c %
* %created_by: nly00524 %
* %derived_by: nly00524 %
* %date_created: 21 augustus 2003%
* %date_modified: %
* %version: 231 %
*
* Copyright (C) PHILIPS Centre For Industrial Technology (CFT) 2002
* Mass Products & Technologies
* Sensors & Measurement
* Eindhoven - The Netherlands
*
* All right are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner
*-------------------------------------------------------------------
* Description:
* ============
*-------------------------------------------------------------------
* History :
* ============
* watch out with timing errors while displaying
*
*/
/*-------------------------------------------------------------------
* Global includes
*-------------------------------------------------------------------
*/
#include <16f84A.h>
#use DELAY(clock=16000000)
#ID 0x4567
#use FAST_IO(a)
#use FAST_IO(b)
#BYTE TMR0 = 0x01
#BIT T0IF = 0x0B.2 // timer 0 interrupt flag
#BIT T0IE = 0x0B.5 // timer 0 interrupt flag enable
#BIT ADJ = 0x05.0 // PIN_A0
#BIT A0 = 0x05.0 // PIN_A0
#BIT A1 = 0x05.0 // PIN_A1
#BIT A2 = 0x05.0 // PIN_A2
#BIT H24 = 0x05.3 // PIN_A3
#BIT A4 = 0x05.4 // PIN_A4
#BIT B6 = 0x06.6 // PIN_B6
#BIT B7 = 0x06.7 // PIN_B7
#BYTE OPTION_REG = 0x81
INT1 H24N;
INT Hour, HourD, Min, Sec;
INT IncVis;
INT PostScaler, SlowSet;
/*--------------------------------------------------------------------
*/
void init()
{
OPTION_REG=0x87;
set_tris_a(0x18); // Set bits A0, A1, A2 as output, bits A3, A4 as input
set_tris_b(0x00); // Set port b as output
T0IF =0; // Clear timer flag
T0IE =1; // Enable timer interrupt flag
PostScaler =0; // Extra division to slow down clock
IncVis =0; // Increase visibility
Hour =12;
HourD =0; // Hours that show up on display
Min =0;
Sec =0;
}
/*--------------------------------------------------------------------
*/
void H12_To_H24()
{
if (Hour>12 & !H24) // 12H (!H24) of 24H (H24) display
HourD=Hour-12;
else
HourD=Hour;
}
/*--------------------------------------------------------------------
*/
void display()
{
H24N=!H24;
if (!A4) // During "set time" no seconds needed and A0 is in use as input
{
OUTPUT_A(0); //Prevent timing problem
OUTPUT_B(Sec+0x80*H24+0x40*H24N);
OUTPUT_A(1); // select Column 1 : seconds
}
IncVis=0;
while(IncVis<5) // Increase visibility
++IncVis;
OUTPUT_A(0); // Prevent timing problem
OUTPUT_B(Min+0x80*H24+0x40*H24N);
OUTPUT_A(2); // Select Column 2 : minutes
IncVis=0;
while(IncVis<5) // increase visibility
++IncVis;
OUTPUT_A(0); // Prevent timing problem
OUTPUT_B(HourD+0x80*H24+0x40*H24N);
OUTPUT_A(4); // Select Column 3 : hours
}
/*--------------------------------------------------------------------
*/
void set()
{
Sec=0;
OPTION_REG=0x8F; // Enable Prescaler
while (A4)
{
set_tris_a(0x19); // Set bits A1, A2 as output, bits A0, A3, A4 as input
if (ADJ & !H24) // Increment minutes
++Min;
if (Min>60)
Min=0;
if (ADJ & H24) // Increment hours
++Hour;
if (Hour>24)
Hour=0;
H12_To_H24(); // Adjust hours to display
SlowSet=0; // Decrease adjusting speed
while (SlowSet<254)
{
++SlowSet;
While (!T0IF) // Wait loop
{
display();
};
T0IF = 0; // Reset Interrupt flag TMR0
TMR0 = 0; // Load Timer value
}
}
set_tris_a(0x18); // Set bits A0, A1, A2 as output, bits A3, A4 as input
OPTION_REG=0x87;
}
/*--------------------------------------------------------------------
*/
void time()
{
++Sec;
if ( sec > 60 )
{
Sec=0;
++Min;
if ( Min > 60 )
{
Min=0;
++Hour;
if ( Hour>24 )
{
Hour=0;
}; //Hour
}; //Min
}; //Sec
H12_To_H24();
}
/*---------------------------------------------------------------------
*/
void main( void )
{
init(); // Initialising
while(true)
{
if (T0IF) // Interrupt flag TMR0
{
T0IF=0; // Reset Interrupt flag TMR0
TMR0 = 190; // Load Timer value
if ( PostScaler > 15 ) // Prescaler + timer too fast. Divide by 15.
{
time(); // Adjust time
PostScaler=0;
}
else
++PostScaler;
} //end if (T0IF)
Display();
if (A4) // "set time" mode
set();
} // end while
}
Designed by Dick Goossens, our departement's electronics wizard.
If you don't understand this, don't worry, it's harmless.
It's hosted on YouTube ...
I'll try to attach the original AVI in the future.