;Copyright 2004 by the Dick Cappels. projects(at)cappels.org www.projects.cappels.org
;Copy and paste this into an assembler file.
.include "tn12def.inc" ;Note that no path is given for this file.
;DOOR BELL TIMER.
;Description: Keeps Portb B bit 1 low for the first 10 hours of each day. Port B bit 0 is a 1 Hz
;pulse to connect to an indicator LED or other monitoring device to indicate that interrupts are
;occuring - mainly to show that oscillator is working because you can't probe it without stopping it.
;Port B bit 2 is low for the first 30 seconds of each minute and high the rest of the time. This is
;for test purposes.
;This runs on an ATtiny12 with a 32768 Hz crystal connected between pins 2 and 3. No phase shift capacitors
;or other components should be connected to these pins.
;When Programming the chip:
;1. Select the Low Freuqency Crystal oscillator 67ms + 32k clock (CKSEL = 1000)
; bt040409D Most recent version.
.equ testpin = 2 ;Port B bit 2 is the test output - low for first 10 seconds.
.equ bellpin = 1 ;Port B bit 1 is the bell relay driver -low for first 10 hours.
.equ winkled = 0 ;Port B bit 0 winks at 1 Hz, changed during interrupt time.
;Contreg (Control Register) bit descriptions and associated constants
.equ readclockinh = 1 ;if 1, inhibits clock from being written to user buffer. Autocleared by write routine
.equ readclockinhflag = 2 ;value ored with contreg to set flag
.equ readclockinhmask=$FD ;used to clear the falg when task completed
.equ writeclock = 2 ;*if 1, commands user buffer to be written to clock. Autocleared by write routine
.equ writelcockorflag= 4 ;value ored with contreg to set flag.
.equ writeclockmask =$FB ;used to clear the flag when task completed
.equ disableclock = 3 ;if 1 disables clock and alarm maintenance during interrupt
.equ disableclockorflag=8 ;value ored with contreg to set flag
.equ disableclockmask=$F7 ;used to clear flag by anding with contreg
;intflags Internal Flags register bit assignments and associated constants
.equ extintmask =$FE ;used to clear flag by anding with contreg
.equ rbtorflag = 8 ;used to set bit
;.equ almaskinitial =$FF ;Defaul value of alarm mask loaded at startup
.def rectimer= r0 ;number of t0 interrupts within on second (used to filter attn line)
.def sregtemp= r1 ;temporary storage of status register during interrupt time
.def uyear = r5 ;user accesible year user register 2
.def umonth = r6 ;user accessible month user register 3
.def uday = r7 ;user accessible day
.def uhour = r8 ;user accessible hour
.def uminute = r9 ;user accessible minute
.def usecond = r10 ;user accessible second
.def ayear = r11 ;alarm year (user accessible)
.def amonth = r12 ;alarm month (user accessible)
.def aday = r13 ;alarm day (user accessible)
.def ahour = r14 ;alarm hour (user accessible)
.def aminute = r15 ;alarm minute (user accessible)
.def asecond = r16 ;alarm second (user accessible)
.def contreg = r17 ;device control register, user register F
;/////end of user accessible registers
.def intflags= r18 ;internal flags - not user accessible
.def second = r19 ;second
.def minute = r20 ;minute
.def hour = r21 ;hour
.def day = r22 ;day
.def month = r23 ;month
.def year = r24 ;year
.def temp = r25 ;scratch
.def tempi = r26 ;scratch for use during interrupt
reti ;external interrupt handler
reti ;pin change interrupt -return
rjmp tovflo ;timer overflow interrupt handler
reset: ;SET EVERYTING UP TO RUN.
ldi contreg,$00 ;Preload conreg flags
out TCCR0,temp ;Set timer prescaler
in intflags,eedr ;Get the data into temp
andi intflags,$78 ;MAKE NORMAL STATE "BAILED", only bits 4,5,6 of EEPROM
ldi temp,$FF ;Pre-load second in user register with $FF so it can
mov usecond,temp ;be determined if the reigster was read before
;values are written by clock
ldi asecond,$FF ;Similarly, put $FF into the alarm seconds
;so alarm cab't fire until initialized.
clr tempi ;presets 500 millisecond counter
ldi temp,0 ;preload timer counter
ldi temp,$02 ;enable timer overflow interrupts
ldi temp,$FF ;load data direction value for PORTB
out DDRB,temp ;no pullups on B0 and B1 ***
andi intflags,$78 ;MAKE NORMAL STATE "BAILED", only bits 4,5,6 of EEPROM
main: ;Main loop - do this after each awakening from sleep. Wakes from sleep 2 times per
;second by timer interrupt.
;Set state of testpin according to number of seconds elapsed within current minute.
cbi PORTB,testpin ;Come here if test pin is to be off (low). Set test pin low.
sbi PORTB,testpin ;Come here if test pin is to be on (high).Make test pin high.
;Set state of bellpin according to number of hours elapsed within current day.
cbi PORTB,bellpin ;Come here if bell pin is to be off (low). Set bell pin low.
sbi PORTB,bellpin ;Come here if bell is to be on (high. Make bell pin high.
;Go to sleep.
ldi temp,$22 ;enable sleep and set T0 to respond to falling edge
out MCUCR,temp ;enable sleep mode
ldi temp,$40 ;enable external interrupt 0
sei ;assure interrupts are enabled
sleep ;good night. Wait for the attention line to go low (interrupt 0)
;///////////////CODE BELOW IS ONLY TIMER INTERRUPT AND CLOCK CODE/////////////////
;///////////////TIMER OVERFLOW SERVICE//////////////////
tovflo: ;twice per second timer interrupt (assumes 32678 hz crystal)
in sregtemp,SREG ;save the status register contents
tst tempi ;Since the interrupt is twice a second, tempi will be used
brne even500ms ;to divide by two
cbi PORTB,winkled ;Set wink LED output low.
sbi PORTB,winkled ;Set wink LED output high.
andi intflags,$7F ;**** possible savings of one word - is this redundant with flag clear in bail?
;//////write to clock//////
sbrs contreg,writeclock ;write user time registers to clock
andi contreg,writeclockmask ;clear write flag
;/////begin clock/calendar maintenance/////
;Year counter runs to 255 years. Leap test year assumes
;that the year is a leap year if bits 0 and 1 are low.
sbrc contreg,disableclock ;Skip clock/alarm maintenance if flag is set
dohour: clr minute
doday: clr hour
;/////end clock/calendar maintenance/////
;//////read from clock to user registers//////
sbrc contreg,readclockinh ;read from clock to user time registers
skipclocktohere: ;Just skipped the clock and alarm
andi intflags,extintmask ;clear ext interrupt counter **** should move to before lateExit
out SREG,sregtemp ;restore the status register contents
;end of assembly souce listing
Liability Disclaimer and intellectual property notice (Summary: No warranties, use these pages at your own risk. You may use the information provided here for personal and educational purposes but you may not republish or use this information for any commercial purpose without explicit permission.)
I neither express nor imply any warranty for the quality, fitness for any particular purpose or user, or freedom from patents or other restrictions on the rights of use of any software, firmware, hardware, design, service,information, or advice provided, mentioned,or made reference to in these pages. By utilizing or relying on software, firmware, hardware, design, service,information, or advice provided, mentioned, or made reference to in these pages, the user takes responsibility to assume all risk and associated with said activity and hold Richard Cappels harmless in the event of any loss or expense associated with said activity. The contents of this web site, unless otherwise noted, is copyrighted by Richard Cappels. Use of information presented on this site for personal, nonprofit educational and noncommercial use is encouraged, but unless explicitly stated with respect to particular material, the material itself may not be republished or used directly for commercial purposes. For the purposes of this notice, copying binary data resulting from program files, including assembly source code and object (hex) files into semiconductor memories for personal, nonprofit educational or other noncommercial use is not considered republishing. Entities desiring to use any material published in this pages for commercial purposes should contact the respective copyright holder(s).