shows 12:00 AM. Three buttons, Set, Hour, and
Minute, work by switching 3 digital input pins on
the microprocessor. Our code defines 2 modes:
Display and Set. In Display mode, the PIC reads
time data from the RTC, then converts it for
display and transmits it to the display driver.
In Set mode, the two other buttons increment
the time shown on the display, working like keyboard buttons — advance one with each press,
and continuously if held down. As the PIC advances internal hour and minute variables, it updates
the display with the new time, and when it leaves
Set mode, it writes the new time out to the RTC.
On our finished clock we used tilt switches for
the Hour and Minute buttons, so you set the time
by physically picking it up and steering it around.
The display driver reads digits differently from
the way the RTC represents time, so our code
needs to convert between the two. The display
driver wants each digit in “binary coded decimal,”
where each digit is represented by a byte (even
though it really only requires 4 bits). The RTC
uses 4-bit binary coded decimal for separate
hours, minutes, and seconds registers, and bits 5
and 6 of the hours register determine if the clock
is in 12- or 24-hour mode, and in 12-hour mode,
whether it’s AM or PM. So, for example, the time
12: 35 PM is represented in the RTC hours and
minutes registers as:
%01110010 %00110101
But needs to be sent to the display driver as:
%00000001 %00000010 %00000011 %00000101
Below is a routine for converting the RTC time
into display digits:
digit0 = clockmin & $0F
digit1 = clockmin >> 4
digit2 = clockhour & $0F
digit3 = (clockhour & $EF) >> 4
PMlight = clockhour. 5
digit0 - 3 are the variables we use for the display.
clockmin and clockhour are the variables in which
we store the data from the clock. Rather than
using arithmetic operators, we can perform some
binary-fu with the bitwise operator AND (&) and
CIRCUITS
SHIFT (>>), which moves bits to the right and
drops the lower ones out. By using these with the
hexadecimal numbers $0F ( 15, or %1111) and $EF
(239, or %11101111) as masks, we have all the hour
and minute conversions we need. The last line of
the routine looks at bit 5 of clockhour, which is high
( 1) for PM times in 12-hour mode.
Besides converting real-time clock values for
the display driver, the other main thing our code
needs to do is handle Set mode, which is easy
once you can capture the button presses. You can
see how that’s done in the project code online.
Alarms and Other Enhancements
Moving forward with our clock, we will want to
add an alarm or two. To do this, you need any device that can make noise, and a way for the user
to set the alarm. We may want to show the date
and make the alarm settable for specific days of
the week, which the RTC will support. Perhaps we
will also add a light detector, to dim the display
at night. And we certainly need a nice case and
some pretty buttons.
These are the basics of using a PIC with peripheral devices. There are thousands of such devices
available, including accelerometers, temperature
sensors, digital potentiometers, and storage
devices. In this series of articles we have focused
on PICs and PicBasicPro, but you can apply much
of the information to other microcontrollers and
compilers. Have fun!
Datasheets
MAX7219-MAX7221 display driver
makezine.com/go/driver
DS1305 Real Time Clock
datasheets.maxim-ic.com/en/ds/DS1305.pdf
SA56-21GWA/A single digit numeric display
makezine.com/go/display
Materials list, development environment, code,
additional diagrams, and suggested reading
online at makezine.com/09/diycircuits_clock.
Amy Parness and Ariel Churi work at Sparkle Labs. Amy
is a digital artist and product designer who pets her
cats while working with new technologies and materials.
Ariel eats chapati and creates “hi-tech, hi-touch” toys
and environments for all ages.
Make: 137