;Dick Cappels' project pages projects@cappels.org - you should be able to copy and paste this text into an assembler file.
   ;©2002 Richard Cappels All Rights Reserved. No liability for resuls of use is assumed.See disclaimer on
;web site.email projects@cappels.org


;Use of information presented on this page is for personal, nonprofit educational ;and noncommercial use only. This material (including object files) is copyrighted ;by Richard Cappels and may not be republished or used directly for commercial ;purposes without explicit permission For commercial license, click HERE. ;
;HOME
; ;This is an AVR1200 that is intended to be used in a autozero circuit in a battery ;operated meter. It includes a PWM routine, an indicator to show whether it has zeroed the circuit ;or not and an indicator to show when the noninverting comparitor input is below the inverting ; comparitor input. ;It also includes a timer to shut of external circuits and indicators once the timeout perdiod ;has elapsed (about 20 minutes with a 2.8 volt power supply or 5 minutes with a 5 volt power supply). ;Voltage on the PWM output on pin 14 (PB2) starts from about a 1% duty cycle. ;The pulse duty cycle will increase until either pin 13 (the inverting comparitor input) ;exceeds the voltage on pin 12 (the noninverting comparitor input) or the duty cycle reaches ;its maximum of about 80%. The pulse changes in about 75 eual steps. ;The notCAL pin, pin 15, (PB3) will be low during this time. If the voltage on the comparitor's ;noninverting pin, pin 12 fails to exceed the voltage on teh comparitor's inverting input, pin 13, ;the notCAL pin, pin 15, will remain low (going high indicates that the zeroing process has completed. ;Momentarily grounding pin 2 (PD0) or pin 1 (reset) will restart the zeroing process, as will monetarily grounding ;the interrupt pin, pin 1. When rezeroing process is started by grounding pin 2, the timer is not reset. ;When the rezeroing process is started by grounding pin 1, the timer is restarted since the entire chip ;will be reset. ;There is a short delay after power is applied and the power on pins assert power being on ;(more about this later) before calibration starts. This gives time for the external circuits to settle. ;Power to external circuits and indicators is switched (or supplied) by pin 11, which goes high while ;power to the external circuits is supposed to be on, and pin 9, which goes low while power to the ;external circuit is supposed to be on. These pins are put in the "on" state when power is applied ;to the chip or the chip first comes out of reset, and the pins are switched to the "off" state ;when the timer times out. ;****************************************************** .include "1200def.inc" ;****************************************************** .def statstor = r15 .def pwmcounter = r16 ;keep track of how many ticks in PWM pules .def pwmvalue = r17 ;requested pwm width .def temp =r18 ;scratch .def intemp = r19 ;number of counts in timer cycle (don't know how to make a constant) .def loopdelay = r20 ;makes response really slow to avoid oscillations. In breadboard pwm lpf is .016 Hz single pole .def timset = r21 ;value to reload counter with after arithmetic .def loopdelay2 = r22 ;inner delay register .def loopdelay3 = r23 .def flagreg = r24 ;Flags .def sleepdelay = r25 .def sleepdelay1 = r26 .def sleepdelay2 = r27 .ORG $0000 rjmp start .ORG $0002 rjmp timerservice rjmp start start: ldi pwmvalue,$01 ldi flagreg, $00 ldi loopdelay, $01 ldi loopdelay2,$01 ldi temp,$60 ; set temp to all zeros out DDRD, temp ; set port D to inputs ldi temp,$43 ; set Port D bit 0 data high as pullup on pin ; and set PORT D bit 6 high to turn on circuit out PORTD,temp ldi temp,$1C out DDRB,temp ;Set PORTB direction out ldi temp,$02 ;Enable timer interrupt ldi temp, $00 out PORTB,temp ldi temp, $00 out ACSR, temp ;set up comparitor ldi intemp, $FF ; counter reload value 255 cycles ldi temp, $01 ; use temp to initaize prescaler to divide by 1 out TCCR0, temp ldi temp,$00 ; use temp to initialize counter out TCNT0,temp ldi temp, $02 ; use temp to initialize TIMSK out TIMSK,temp sbi PORTB,3 ldi loopdelay,$00 ldi loopdelay2,$00 ldi loopdelay3,$01 ;****START UP DELAY turnondelay: dec loopdelay cpi loopdelay,$00 brne turnondelay dec loopdelay2 cpi loopdelay2,$00 brne turnondelay dec loopdelay3 cpi loopdelay3,$00 brne turnondelay cbi PORTB,3 ldi loopdelay, $01 ldi loopdelay2,$01 ldi temp, $00 ; clear temp sei ; enable interrupts ;initiaization is finished ; CHECK - IF PIN 3 IS GROUNDED, SKIP TO LOOP, THAT IS, DON'T ALLOW SLEEP sbis PIND,$01 rjmp loop ;skipp sleep is pin is grounded ; WAIT UNTIL TIME FOR SLEEP ldi sleepdelay,$00 ldi sleepdelay1,$00 ldi sleepdelay2,$F0 ; $F0 gets about 20 min at 2.8V and 5 min at 5V ;****START UP DELAY sleepdelayroutine: ; SAMPLE COMPARITOR AND OUTPUT TO LED (PB4) WHILE WAITING TO SLEEP ; Set state of light on PB4 according to comparitor inputs sbic acsr,aco ; if + input is higher than - input, ligh on cbi PORTB,4 sbis acsr,aco ;if + input is not higher than - input, ligh off sbi PORTB,4 dec sleepdelay cpi sleepdelay,$00 brne sleepdelayroutine dec sleepdelay1 cpi sleepdelay1,$00 brne sleepdelayroutine dec sleepdelay2 cpi sleepdelay2,$00 brne sleepdelayroutine ; GO TO SLEEP cli ; dispable interupts ldi temp, $00 out TIMSK,temp ; clear TIMSK bit 1 - TOIE0 enable (disable timer interrupts) ldi temp, $18 out PORTB, temp ; turn off LEDs, set pulse output to zero ldi temp, $20 out PORTD, temp ; turn off port D bit 0 pullup and bit 6 power to external circuit ldi temp, $30 out MCUCR,temp ; set MCUCR bit 4 to set power down mode for sleep and ; set MCUCR bit 5 to enable sleep sleep ; enter sleep. Reset to wake up. loop: ; It only gets here if timer is bypassed by grounding pin 3 ; SAMPLE COMPARITOR AND OUTPUT TO LED (PB4) ; Set state of light on PB4 according to comparitor inputs sbic acsr,aco ; if + input is higher than - input, ligh on cbi PORTB,4 sbis acsr,aco ;if + input is not higher than - input, ligh off sbi PORTB,4 rjmp loop ; sit and spin timerservice: in statstor,SREG mov pwmcounter, pwmvalue andi pwmvalue, $FF breq zeroutput ; if the value is zero, don't turn on output sbi PORTB,2 ;set output bit high zeroutput: decpwm: dec pwmcounter ; wait time proportional to count brne decpwm cbi PORTB,2 ; now PWM is finished dec loopdelay ; decrement loop dealy counter brne down ; if not zero yet, skip to end of interrupt dec loopdelay2 brne down ldi loopdelay2,$02 ;**** STEPPING delay andi flagreg,$FF breq donturnlampoff sbi PORTB,3 ;turn off (N)cal inidicator donturnlampoff: andi flagreg,$FF brne down ; skip servo if all flag bits are high ; over/underflow prevention ldi temp,$4B cpse pwmvalue,temp ;if pwmvalue = 4B then set back to 4A rjmp servo ldi pwmvalue, $4A servo: sbic acsr,aco ; if comparator is tripped, inc PWM inc pwmvalue sbis acsr,aco ;if comparator isn't tripped, STOP searching ldi flagreg,$FF down: in temp,PIND ;Reset flag and value if button down sbrc temp,$00 rjmp donecheckingbutton ldi flagreg,$00 ldi pwmvalue,$01 cbi PORTB,3 ;turn off (N)cal inidicator donecheckingbutton: return: out SREG,statstor ;Restore SREG reti
;http://projects.cappels.org/ ;HOME