by K.S.Sankar - Mostek Electronics ( www.mostek.biz )
Originaly published in ELECTRONICS FOR YOU magazine ( INDIA - W W W . E F Y M A G . C O M )
An alarm clock using six 7-segment displays is used in this project to display
the time in HH-MM-SS format using a micro controller ATMEL-89s8252. Dedicated
Clock and Alarm chips seem to have vanished after the micro controllers took
over and only a micro controller with an RTC chip seems the solution now to
build a simple alarm clock.
To minimise the number of components, the circuit uses
a 7-segment driver IC from Maxim corp. max7219 and RTC chip from Dallas –
DS1307. The RTC is battery backed up with a 3v button cell to keep the clock
running even during power failures. The max7219 uses a serial interface to
drive the 6 digit clock avoiding software multiplexing and IC 4050 buffer s
used to drive a few Leds.
The AT89s8252 micro runs of a 6Mhz crystal not
critical to the time base since the RTC chip has its own 32k crystal.
Minimum no. of keys have been introduced in the circuit
to keep the setting simple and only 2 Leds are there in the circuit.
The salient features of this project:-
1- 12
hour format with PM led indicator
2- Alarm set
(hh/mm/ss)+/- with snooze 5 mins facility
3- Set hours/min/secs
/ Pm /Am with +/- switches
4- 15 level LED
brightness control.
5- Flashing colon
snooze indicator
6- ALARM set led
7- Buzzer output
8- PM led output
9- ALARM SET switch
10- ALARM off switch (dim/bright)
11- Mode switch
12- ADJ + SWITCH ( Brightness increase)
13- ADJ – SWITCH (Brightness decrease)
14- 1hz RTC led output
15- MODE & ADJ+ combination for RTC
INITIALISE
The
circuit used I2c communication with the RTC chip to get the time and a serial
communication protocol with the max7219 to get the output on the 7-seg leds.
For
the colon Leds between the HOURS and MINS two 3mm leds can be used which are
connected to the same 7-seg data bus and vary with the same intensity.
One
separate led for indicating PM is need and another Led to indicate ALARM
ACTIVE. The source code is given below:
' --------------------------------
' alarm1307.BAS 2-10-06
' Led display with ds1307 rtc chip and max7219-hh:mm:ss
' written by K.S. Sankar www.mostek.biz India
' for MCS ELECTRONICS - Holland
$large
$regfile = "89s8252.dat"
$crystal = 6000000
P0 = 0
P2 = 0
P1 = 0
P3 = &B11111111
P1.3 = 1
' ports
' p3.0-rx not used
' p3.1-tx not used
' p3.2-> sw alarm set/OFF
' p3.3-> sw mode 0=press
' p3.4-> sw set (+) 0=press
' p3.5-> sw alarm snooze 0=press
' p3.6-> i2c bus SCL
' p3.7-> i2c bus SDA
'--------------------
' p1.0-> clock
' p1.1-> din
' p1.2-> /chip select
' p1.3-> sw set (-) 0=press
' p1.4-> buzzer alarm
' p1.5-> led- PM indicator
' p1.6-> led- alarm active indicator
' p1.7 - not used
' P0- NOT USED
' P2- NOT USED
' press p3.3 + p3.4 together for INTI of RTC chip
On Int0 Int0_int
Set Tcon.0
' edge triggered
Enable Interrupts
Enable Int0
'enable the interrupt
Config Timer0 = Timer , Gate = Internal , Mode = 2
' 8 bit auto reload
On Timer0 Timer_0_overflow_int
Load Timer0 , 250
Priority Set Timer0
Enable Interrupts
Enable Timer0
Start Timer0
' define aliases
Sw_alarm_set Alias P3.2
Sw_alarm_snooze Alias P3.5
Sw_mode Alias P3.3
Sw_set Alias P3.4
Sw_set_minus Alias P1.3
Clock Alias P1.0
Din Alias P1.1
Cs Alias P1.2
Buzzer Alias P1.4
Led_pm Alias P1.5
Led_alarm_active Alias P1.6
'------------------------------------------
' config I2C bus
Config Scl = P3.6
' I2C Clock
Config Sda = P3.7
' I2C Data
'-------------------------------------------
Const Ds1307w = &HD0
' Write
Const Ds1307r = &HD1
' Read
Const Sec_addmap = &H00
Const Min_addmap = &H01
Const Hour_addmap = &H02
Const Control_addmap = &H07
Const Alarm_sec_addmap = &H08
Const Alarm_min_addmap = &H09
Const Alarm_hour_addmap = &H0A
Const Alarm_active_addmap =
&H0B
Const Brightness_addmap = &H0C
' buzzer ON time in seconds
Const Buz_time = 30
Const Snooze_mins = 5
' declare variables
'-------------------------------------------------------
Dim Num_hour As Byte , Num_min As Byte , Num_sec As Byte
Dim Alarm_num_hour As Byte , Alarm_num_min As Byte
Dim Alarm_num_sec As Byte
Dim Flicker_h As Bit , Flicker_m As Bit ,
Flicker_s As Bit
Dim Set_mode_count As Byte
Dim Temps As String * 2
Dim Reg_sec As Byte
Dim Reg_min As Byte
Dim Reg_hour As Byte
Dim Alarm_reg_sec As Byte
Dim Alarm_reg_min As Byte
Dim Alarm_reg_hour As Byte
Dim Alarm_toggle As Bit
Alarm_toggle = 0
Dim Snooze As Bit
Snooze = 0
Dim Pm_bit As Bit , Decrease As Bit
Dim Alarm_pm_bit As Bit
Dim Alarm_active As Bit , Alarm_active_byte As Byte
Dim Alarm_set As Bit , Buzzer_count As Byte , Diff As Byte
Dim Brightness As Byte , Bright_word As Word
Brightness = 7
Bright_word = 2560 + 7
Buzzer_count = 0
Alarm_set = 0
Alarm_active = 0
Alarm_active_byte = 0
Pm_bit = 0
Decrease = 0
' default alarm time
Alarm_pm_bit = 0
' am
Alarm_num_hour = 0
Alarm_num_min = 0
Alarm_num_sec = 0
Alarm_reg_hour = 0
Alarm_reg_min = 0
Alarm_reg_sec = 0
' Control
Dim Reg_mode As Byte
Dim Tempb As Byte
Dim Address As Byte
Dim Sec_count As Byte
Dim Clock_word As Word
Dim Sec_flag As Bit
Sec_count = 0
Sec_flag = 0
Clock_word = 0
'-----------------------------------------------------
Declare Sub Fni2cwrite(_slaveadd As Byte , _add As Byte , _num As Byte)
Dim _slaveadd As Byte
Dim _add As Byte
Dim _num As Byte
Declare Sub Fni2cwriteb(_slaveaddb As Byte , _addb As Byte , _numb As Byte)
Dim _slaveaddb As Byte
Dim _addb As Byte
Dim _numb As Byte
Declare Sub Fn7segh(_ih As Byte)
Dim _ih As Byte
Declare Sub Fn7segm(_im As Byte)
Dim _im As Byte
Declare Sub Fn7segs(_is As Byte)
Dim _is As Byte
Declare Sub Pulse_bit(bit1 As Bit)
Dim Bit1 As Bit
Declare Sub Pulse_word(w1 As Word)
Dim W1 As Word
Declare Sub Disp_digit(d1 As Byte , Num As Byte)
Dim D1 As Byte , Num As Byte
Declare Sub Disp_blank()
Dim I As Byte , Tens As Byte , Units As Byte
Dim J As Word
Dim K As Bit
Dim V As Integer
Dim V1 As Byte , V2 As Byte
Dim Del As Byte
Del = 1
Dim Maxdigits As Byte
Maxdigits = 8
V = &B1000111100001110
' format
' d15 d14 d13 d12 d11 d10 d09 d08 d7 d6 d5 d4 d3
d2 d1 d0
' x x x x address------ -------- data ---------
Dim Normal_mode As Word
' 0c00=shut down 0c01=normal
Normal_mode = &B0000110000000001
Dim Code_b As Word
' 09ff
Code_b = &B0000100111111111
' 0a0f led intesity
Dim Scan_limit As Word
' 0b07
Scan_limit = &B0000101100000111
' ALL 8 DIGITS
Dim Disp_test_off As Word
Disp_test_off = &B0000111100000000
Dim Disp_test_on As Word
Disp_test_on = &B0000111100000001
'Display-Test Register
'0f00 =normal 0f01 = test
Call Pulse_word(normal_mode)
Call Pulse_word(&H09ff)
Call Pulse_word(bright_word)
Call Pulse_word(scan_limit)
Call Pulse_word(disp_test_on)
Waitms 100
Call Pulse_word(disp_test_off)
Waitms 100
Gosub Read_ds1307
Gosub Read_alarm
Set_mode_count = 0
' write brightness in rtc chip
Brightness = 7
Bright_word = 2560 + 7
Call Pulse_word(bright_word)
Call Fni2cwrite(ds1307w ,
Brightness_addmap , Brightness)
'=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-
Main:
Gosub Read_ds1307
If Alarm_set = 0 Then
Call Fn7segh(reg_hour)
Call Fn7segm(reg_min)
Call Fn7segs(reg_sec)
If Pm_bit = 0 Then
Led_pm = 0
Else
Led_pm = 1
End If
End If
If Alarm_set = 1 Then
Gosub Read_alarm
Call Fn7segh(alarm_reg_hour)
Call Fn7segm(alarm_reg_min)
Call Fn7segs(alarm_reg_sec)
If Alarm_pm_bit = 0 Then
Led_pm = 0
Else
Led_pm = 1
End If
End If
' check for alarm condition
If Alarm_active = 1 Then
If Reg_hour = Alarm_reg_hour Then
If Reg_min = Alarm_reg_min Then
If Reg_sec = Alarm_reg_sec Then
If Pm_bit = Alarm_pm_bit Then
Buzzer = 1
Buzzer_count = 0
End If
End If
End If
End If
End If
If Alarm_active = 0 Then
Buzzer = 0
End If
If Buzzer_count >= Buz_time Then
Buzzer = 0
End If
' look for set key switches
If Sw_mode = 0 Then
' wait for keyrelease
While Sw_mode = 0
If Sw_set = 0 Then
' do a clock init
if both keys pressed
Gosub Clock_init
Gosub Setzero
Set_mode_count = 4
End If
Wend
Waitms 30
Sec_count = 0
' start a second
t0 timer
Gosub Swmode
End If
If Sw_set = 0 Then
Waitms 30
Decrease = 0
Gosub Swset
End If
If Sw_set_minus = 0 Then
Waitms 30
Decrease = 1
Gosub Swset
End If
If Set_mode_count > 0 Then
If Sec_count > 4 Then
' more than 4
secs in set operation in idle mode
' so quit
Set_mode_count = 0 : Alarm_set = 0
Flicker_h = 0 : Flicker_m = 0 :
Flicker_s = 0
If Alarm_active = 1 Then
Call Fn7segh(alarm_reg_hour)
Call Fn7segm(alarm_reg_min)
Call Fn7segs(alarm_reg_sec)
Wait 1
End If
End If
End If
If Alarm_set = 1 Then
If Alarm_active = 1 Then
If Sec_count > 3 Then
Alarm_set = 0
Led_alarm_active = 1
End If
End If
End If
If Alarm_active = 1 Then
If Alarm_set = 0 Then
Led_alarm_active = 1
End If
End If
If Alarm_active = 0 Then
Led_alarm_active = 0
End If
If Buzzer = 1 Then
If Sw_alarm_snooze = 0 Then
Waitms 30
' snooze sw
pressed
Snooze = 1
Buzzer = 0
' stop buzzer and
' make : colon
flicker
' increase alarm
time by 5 minutes
Gosub Snooze5
End If
End If
' check for alarm set switches
If Alarm_active = 0 Then
If Alarm_toggle = 1 Then
Waitms 30
' in alarm mode
Alarm_set = 1
Alarm_active = 1
Sec_count = 0
' write alarm act
in ram
Alarm_active_byte = &B00000001
Snooze = 0
Call Fni2cwrite(ds1307w , Alarm_active_addmap , Alarm_active_byte)
End If
End If
' check for alarm OFF
If Alarm_active = 1 Then
If Alarm_toggle = 0 Then
Waitms 30
' alarm
deactivated
Alarm_set = 0
Led_alarm_active = 0
Alarm_active = 0
Alarm_active_byte = &B00000000
Snooze = 0
Call Fni2cwrite(ds1307w , Alarm_active_addmap , Alarm_active_byte)
End If
End If
If Alarm_set = 1 Then
' flash led alarm
to indicate SET mode
Led_alarm_active = Led_alarm_active Xor 1
Waitms 10
End If
If Buzzer = 0 Then
If Sw_alarm_snooze = 0 Then
Waitms 30
' snooze pressed
without buzzer ON
' dim / bright
7-segment display
If Brightness = 1 Then
Brightness = 15
Else
Brightness = 1
End If
' write
brightness in rtc chip and 7219
Bright_word = 2560 + Brightness
Call Pulse_word(bright_word)
Call Fni2cwrite(ds1307w , Brightness_addmap , Brightness)
End If
End If
Goto Main
'=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Swmode:
Sec_count = 0
' in set mode now
' look for set sw and shift from hours to min set
' let hours flicker for set++
Incr Set_mode_count
Flicker_h = 0 : Flicker_m = 0 : Flicker_s = 0
' 1= hours set 2= min set 3= sec set
If Set_mode_count = 1 Then
Flicker_h = 1
End If
If Set_mode_count = 2 Then
Flicker_m = 1
End If
If Set_mode_count = 3 Then
Flicker_s = 1
End If
If Set_mode_count > 3 Then
Set_mode_count = 0 : Alarm_set = 0
Flicker_h = 0 : Flicker_m = 0 :
Flicker_s = 0
End If
Return
' =-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=
Swset:
' incr hh/mm/ or sec
Sec_count = 0
' reset our idle timer
If Set_mode_count = 1 Then
Gosub Set_hours
End If
If Set_mode_count = 2 Then
Gosub Set_minutes
End If
If Set_mode_count = 3 Then
Gosub Set_seconds
End If
' adjust brightness
If Set_mode_count = 0 Then
If Decrease = 0 Then
Incr Brightness
If Brightness >= 15 Then
Brightness = 15
' show
limit reached by flshing colon leds
Call Disp_digit(7 , 15)
Call Disp_digit(8 , 15)
Waitms 2
End If
Else
Decr Brightness
If Brightness = 0 Then
Brightness = 1
' show
limit reached by flshing colon leds
Call Disp_digit(7 , 15)
Call Disp_digit(8 , 15)
Waitms 2
End If
End If
Bright_word = 2560 + Brightness
Call Pulse_word(bright_word)
Call Fni2cwrite(ds1307w , Brightness_addmap , Brightness)
End If
Return
'-=-=-=-=-=-=-=-=-=-=-=-=-=
Read_ds1307:
'-=-=-=-=-=-=-=-=-=-=-=-=-=
' Read Clock Data
Address = Sec_addmap
I2cstart
' Generate start
I2cwbyte Ds1307w
' Slave adsress
I2cwbyte Address
' Address of SECONDS REG
I2cstop
' Generate Stop
I2cstart
' Repeated start
I2cwbyte Ds1307r
' Slave address (read)
I2crbyte Reg_sec , Ack
I2crbyte Reg_min , Ack
I2crbyte Reg_hour , Nack
I2cstop
' Generate Stop
' check for am/pm
If Reg_hour.5 = 1 Then
Pm_bit = 1
Else
Pm_bit = 0
End If
'reg_hour.6=1(12
hrmode) =0(24 hourmode)
'=-=-=-=-=-=-=-=-=-=-=-
Reg_hour = Reg_hour And
&B00011111
' remove 12/24 set and am/pm bits
' set numeric variables
Num_hour = Makedec(reg_hour)
Num_min = Makedec(reg_min)
Num_sec = Makedec(reg_sec)
' read brightness level
I2cstart
' Generate start
I2cwbyte Ds1307w
' Slave adsress
I2cwbyte Brightness_addmap
I2cstop
' Generate Stop
I2cstart
' Repeated start
I2cwbyte Ds1307r
' Slave address (read)
I2crbyte Brightness , Nack
I2cstop
Brightness = Makedec(brightness)
Bright_word = 2560 + Brightness
Return
'---------------------------------------------
Clock_init:
' double key stroke
Address = Sec_addmap
Tempb = Reg_sec And
&B01111111
' start Oscillator Enable bit 7 of seconds put 0
I2cstart
I2cwbyte Ds1307w
I2cwbyte Address
I2cwbyte Tempb
I2cstop
' Generate Stop
Address = Hour_addmap
Reg_hour.6 = 1
' 12-Hour Mode
Reg_hour.5 = 0
' am mode
I2cstart
I2cwbyte Ds1307w
I2cwbyte Address
I2cwbyte Reg_hour
I2cstop
' Generate Stop
Address = Control_addmap
' control address map
Tempb = &B10010000
' 1 Hz SQW Output
I2cstart
I2cwbyte Ds1307w
I2cwbyte Address
I2cwbyte Tempb
I2cstop
Return
'-------------------------------------------------
Setzero:
'=-=-=-=
' set time to 11:59:50 am for testing
Pm_bit = 0
Num_hour = 11
Reg_hour = Makebcd(num_hour)
Reg_hour.5 = 0
' above force am mode 0=am 1=pm
Reg_hour.6 = 1
' force 12 hour
Num_min = 59
Num_sec = 50
Call Fni2cwriteb(ds1307w ,
Hour_addmap , Reg_hour)
Call Fni2cwrite(ds1307w ,
Min_addmap , Num_min)
Call Fni2cwrite(ds1307w ,
Sec_addmap , Num_sec)
' -----
Alarm_num_hour = 12
Alarm_num_min = 00
Alarm_num_sec = 01
Alarm_active_byte = &B00000000
Alarm_active = 0
Alarm_reg_hour = Makebcd(alarm_num_hour)
Alarm_reg_min = Makebcd(alarm_num_min)
Alarm_reg_sec = Makebcd(alarm_num_sec)
Alarm_reg_hour.6 = 1
' 12-Hour Mode
Alarm_reg_hour.5 = 1
' pm mode
' alarm= 12:00:01 pm
Call Fni2cwriteb(ds1307w , Alarm_hour_addmap
, Alarm_reg_hour)
Call Fni2cwrite(ds1307w ,
Alarm_min_addmap , Alarm_num_min)
Call Fni2cwrite(ds1307w ,
Alarm_sec_addmap , Alarm_num_sec)
Call Fni2cwrite(ds1307w ,
Alarm_active_addmap , Alarm_active_byte)
' set min brightness
Brightness = 1
Bright_word = 2560 + Brightness
Call Pulse_word(bright_word)
Call Fni2cwrite(ds1307w ,
Brightness_addmap , Brightness)
Return
' =-=-=-=-=-=-=-
Set_seconds:
' set sec to 0
'=-=-=-=
If Alarm_set = 1 Then
Gosub Alarm_set_seconds
End If
If Decrease = 1 Then
Decrease = 0
Num_sec = 00
Else
Num_sec = 54
End If
Reg_sec = Makebcd(num_sec)
Call Fni2cwriteb(ds1307w , Sec_addmap , Reg_sec)
Gosub Read_ds1307
Waitms 5
Return
' =-=-=-=-=-=-=-==-=-=-=-=
Alarm_set_seconds:
' set sec to 0
'=-=-=-=
If Decrease = 1 Then
Decrease = 0
Alarm_num_sec = 00
Else
Alarm_num_sec = 54
End If
Alarm_reg_sec = Makebcd(alarm_num_sec)
Call Fni2cwriteb(ds1307w , Alarm_sec_addmap , Alarm_reg_sec)
Gosub Read_alarm
Waitms 5
Return
' =-=-=-=-=-=-=-
Set_minutes:
' set mins
'=-=-=-=
If Alarm_set = 1 Then
Gosub Alarm_set_minutes
Return
End If
Num_min = Makedec(reg_min)
If Decrease = 0 Then
Incr Num_min
If Num_min > 59 Then
Num_min = 0
Reg_min = 0
End If
Else
Decr Num_min
If Num_min = 255 Then
Num_min = 59
Reg_min = 59
End If
End If
Call Fni2cwrite(ds1307w , Min_addmap , Num_min)
Gosub Read_ds1307
Call Fn7segm(reg_min)
Waitms 5
Decrease = 0
Return
' =-=-=-=-=-=-=-
Alarm_set_minutes:
'=-=-=-=-=-=-=-=
Alarm_num_min = Makedec(alarm_reg_min)
If Decrease = 0 Then
Incr Alarm_num_min
If Alarm_num_min > 59 Then
Alarm_num_min = 0
Alarm_reg_min = 0
End If
Else
Decr Alarm_num_min
If Alarm_num_min = 255 Then
Alarm_num_min = 59
Alarm_reg_min = 59
End If
End If
Call Fni2cwrite(ds1307w , Alarm_min_addmap , Alarm_num_min)
Gosub Read_alarm
Call Fn7segm(alarm_reg_min)
Waitms 5
Decrease = 0
Return
' =-=-=-=-=-=-=-
Set_hours:
'=-=-=-=-=-=-=-=
If Alarm_set = 1 Then
Gosub Alarm_set_hours
Return
End If
If Decrease = 0 Then
Incr Num_hour
If Num_hour > 12 Then
Num_hour = 1
End If
Else
Decr Num_hour
If Num_hour = 0 Then
Num_hour = 12
End If
End If
If Decrease = 0 Then
If Num_hour = 12 Then
Pm_bit = Pm_bit Xor 1
End If
Else
If Num_hour = 11 Then
Pm_bit = Pm_bit Xor 1
End If
End If
Reg_hour = Makebcd(num_hour)
Reg_hour.6 = 1
' set 12 hr mode
If Pm_bit = 1 Then
Reg_hour.5 = 1
' pm
Else
Reg_hour.5 = 0
' am
End If
Call Fni2cwriteb(ds1307w , Hour_addmap , Reg_hour)
Gosub Read_ds1307
Call Fn7segh(reg_hour)
Waitms 5
Decrease = 0
Return
' =-=-=-=-=-=-=-
Alarm_set_hours:
' set alarm hours
'=-=-=-==-=-=-=-=
If Decrease = 0 Then
Incr Alarm_num_hour
If Alarm_num_hour > 12 Then
Alarm_num_hour = 1
End If
Else
Decr Alarm_num_hour
If Alarm_num_hour = 0 Then
Alarm_num_hour = 12
End If
End If
If Decrease = 0 Then
If Alarm_num_hour = 12 Then
Alarm_pm_bit = Alarm_pm_bit Xor 1
End If
Else
If Alarm_num_hour = 11 Then
Alarm_pm_bit = Alarm_pm_bit Xor 1
End If
End If
Alarm_reg_hour = Makebcd(alarm_num_hour)
Alarm_reg_hour.6 = 1
' set 12 hr mode
If Alarm_pm_bit = 1 Then
Alarm_reg_hour.5 = 1
' pm
Else
Alarm_reg_hour.5 = 0
' am
End If
Call Fni2cwriteb(ds1307w , Alarm_hour_addmap , Alarm_reg_hour)
Gosub Read_alarm
Call Fn7segh(alarm_reg_hour)
Decrease = 0
Return
' =-=-=-=-=-=-=-
' functions below
'=-=-=-=-=-= function below---- - -- -
Sub Fn7segh(_ih As Byte)
Tempb = Makedec(_ih)
Units = Tempb Mod 10
Tens = Tempb / 10
Call Disp_digit(5 , Units)
Call Disp_digit(6 , Tens)
Call Disp_digit(7 , 1)
Call Disp_digit(8 , 1)
If Flicker_h = 1 Then
' if in set mode
make display flicker
Waitms 5
' turn it on
again
Call Disp_digit(5 , 15)
Call Disp_digit(6 , 15)
Waitms 5
End If
If Snooze = 1 Then
' if in snooze
mode make : flicker
Waitms 2
' turn it on
again
Call Disp_digit(7 , 15)
Call Disp_digit(8 , 15)
Waitms 2
End If
End Sub
'-=-=-=-=-=-=-=-=
Sub Fn7segm(_im As Byte)
Tempb = Makedec(_im)
Units = Tempb Mod 10
Tens = Tempb / 10
Call Disp_digit(3 , Units)
Call Disp_digit(4 , Tens)
If Flicker_m = 1 Then
' if in set mode
make display flicker
Waitms 5
' turn it on
again
Call Disp_digit(3 , 15)
Call Disp_digit(4 , 15)
Waitms 5
End If
End Sub
'-=-=-=-=-=-=-=-=
Sub Fn7segs(_is As Byte)
Tempb = Makedec(_is)
Units = Tempb Mod 10
Tens = Tempb / 10
Call Disp_digit(1 , Units)
Call Disp_digit(2 , Tens)
If Flicker_s = 1 Then
' if in set mode
make display flicker
Waitms 5
' turn it on
again
Call Disp_digit(1 , 15)
Call Disp_digit(2 , 15)
Waitms 5
End If
End Sub
'-=-=-=-=-=-=-=-=
Sub Fni2cwrite(_slaveadd As Byte , _add As Byte , _num As Byte)
Dim _bcdnumber As Byte
_bcdnumber = Makebcd(_num )
I2cstart
I2cwbyte _slaveadd
I2cwbyte _add
I2cwbyte _bcdnumber
I2cstop
End Sub
'-=-=-=-=-=-=-=-=
Sub Fni2cwriteb(_slaveaddb As Byte , _addb As Byte , _numb As Byte)
I2cstart
I2cwbyte _slaveaddb
I2cwbyte _addb
I2cwbyte _numb
I2cstop
End Sub
'=-=-=-=-=-=-=-=-=-=-=-
Sub Pulse_bit(bit1 As Bit)
Din = Bit1
Clock = 1
Clock = 0
Din = 0
End Sub
'=-=-==-==-=-=-=-=-=-=-=-=
Sub Pulse_word(w1 As Word)
Cs = 0
Dim _i As Byte , _k As Bit
For _i = 1 To 16
J = W1 And &B1000000000000000
If J = &B1000000000000000 Then : _k = 1 : Else : _k = 0 : End If
Call Pulse_bit(_k)
Shift W1 , Left , 1
Next _i
Cs = 1
End Sub
'-=-=-=-=-==-=-=-=-=-=-=-=-=-==-=-=--=-=-=--==
Sub Disp_digit(d1 As Byte , Num As Byte)
W1 = D1 * 256
W1 = W1 + Num
Call Pulse_word(w1)
End Sub
'=-=-=-=-=-=-=-==-=-=-=-
Sub Disp_blank()
Dim _j As Byte
For _j = 1 To Maxdigits
Call Disp_digit(_j , 15)
Next _j
End Sub
' int subroutine -----------------
Timer_0_overflow_int:
Incr Clock_word
If Clock_word > 2000 Then
Clock_word = 0
Sec_flag = 1
Incr Sec_count
Incr Buzzer_count
End If
Return
'=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-==-
Read_alarm:
' Read alarm Data
Address = Alarm_sec_addmap
I2cstart
I2cwbyte Ds1307w
I2cwbyte Address
I2cstop
I2cstart
I2cwbyte Ds1307r
' Slave address (read)
I2crbyte Alarm_reg_sec , Ack
I2crbyte Alarm_reg_min , Ack
I2crbyte Alarm_reg_hour , Ack
I2crbyte Alarm_active_byte , Nack
I2cstop
' Generate Stop
' check for am/pm
'Alarm_active = 1
If Alarm_active_byte = 1 Then
Alarm_active = 1
Else
Alarm_active = 0
End If
If Alarm_reg_hour.5 = 1 Then
Alarm_pm_bit = 1
Else
Alarm_pm_bit = 0
End If
Alarm_reg_hour = Alarm_reg_hour And &B00011111
' remove 12/24 set and am/pm bits
' set numeric variables
Alarm_num_hour = Makedec(alarm_reg_hour)
Alarm_num_min = Makedec(alarm_reg_min)
Alarm_num_sec = Makedec(alarm_reg_sec)
Return
'-=-=-=-=-=-=-=-=-=-=-=-=-=--
Snooze5:
'increment alarm time by (snooze_mins) minutes
Gosub Read_alarm
Alarm_num_min = Makedec(alarm_reg_min)
Alarm_num_min = Alarm_num_min +
Snooze_mins
If Alarm_num_min > 59 Then
Diff = Alarm_num_min - 60
Alarm_num_min = Diff
Alarm_reg_min = Makebcd(alarm_num_min)
' inc hrs
Incr Alarm_num_hour
If Alarm_num_hour > 12 Then
Alarm_num_hour = 1
End If
If Alarm_num_hour = 12 Then
Alarm_pm_bit = Alarm_pm_bit Xor 1
End If
End If
Alarm_reg_hour = Makebcd(alarm_num_hour)
Alarm_reg_hour.6 = 1
' Set 12 Hr Mode
If Alarm_pm_bit = 1 Then
Alarm_reg_hour.5 = 1
' pm
Else
Alarm_reg_hour.5 = 0
' am
End If
Call Fni2cwriteb(ds1307w ,
Alarm_hour_addmap , Alarm_reg_hour)
Call Fni2cwrite(ds1307w ,
Alarm_min_addmap , Alarm_num_min)
Gosub Read_alarm
Return
'=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Rem The Interrupt Handler For The Int0 Interrupt
Int0_int:
Alarm_toggle = Alarm_toggle Xor 1
' p3.2
Return
End
' end of program 3742 bytes long

 |