;
/*
* Shutdown timer (Shutdown_timer03) (To shut off a light after a preset period and also if the battery voltage is too low.)
*
* Created: 03/09/2015
* Author: Les
* Version 2 being modified by adding low battery warning light
*/
; using ATTINY13
; Fuse bit settings
; Low 0x62 (0x6A is also OK)
; High 0xFF
; Extended 0xFF
; Lock 0xFF
;
;
;Use internal clock at 9.6 Mhz (Default value) and divide by 8 by setting CKDIV8 fuse bit (These are the default setting on a new chip.)
; 9.6 Mhz/8 = 1.2 Mhz
;(So Instruction time = 833.3 nS)
; So for 50 uS delay requires 50/0.8333 = 60 instructions
; Burst needs to be 5 mS long. This will be 50 cycles of 10 Khz
;
;**************************************************************************
.nolist
.include <tn13def.inc> ; ATtiny 13
.list
.listmac
;***************************************************************************
;*
;* Global Register Variables
;*
;***************************************************************************
; Note register number is in decimal
.def N200mS = r17 ;Number of 200 mS
.def Seconds = r18 ;Number of seconds
.def Minutes = r19 ;Number of minutes
.def count_L = r22 ;Used for time delay
.def Flags = r23 ;Bit 0 used for battery low warning flag
.equ Shutdown_volts = 0xA4 ;battery voltage shutdown value. (164 decimal. Divide battery voltage using a 4.7K resistor to ground and a 10 K resistor to the )
; (collector ofthe power switching transistor. This gives a ratio of 0.32. So for a cut off voltage )
; (of 10.0 we need to detect 3.2 volts This is 256 x 3.2/5 = 164 )
.equ Battery_Low = 0xB4 ;Battery voltage low warning level. (Set to come on at 11.0 volts so this will be 1.0 * 0.32 = 3.52 volts at ADC input
; (This will be a count of 256 * 3.52/5 = 180 = 0xB4 )
;
.equ Shutdown_minutes = 5 ;Time to shutdown in minutes.
;
;
;******************************** INTERRUPT VECTORS ***********************
.CSEG
.ORG 00
rjmp reset
reti
reti
rjmp TC_overflow ;Timer/Counter Overflow
reti
reti ; rjmp timer1_OVF
reti
reti
reti
reti
;
;******************************* RESET *************************************
;
; Initialise the stack-pointer
reset:
ldi R16,low(RAMEND)
out SPL,R16
; initialize PORTB
; Bit 0 Input (pin 5) (Input will be low when button is pressed.
; Bit 1 Input
; Bit 2 Input ADC input (Pin 7)
; Bit 3 Output (Pin 2) (Drive to low battery warning LED High for LED on)
; Bit 4 Output (Pin 3) (Drive to power control tansistor base.)
; Bit 5 Input
ldi R16,0x18 ; Bits 3 and 4 as outputs.
out DDRB,R16 ;
ldi R16,0x10
out PORTB,R16 ; PORTB Bit 3 low, bit 4 high
; initialize Flags
ldi Flags,0x00
;Initialize ADC
ldi R16,0x84 ;Enable , Prescale value 16, No auto triggering
out ADCSRA,R16
ldi R16,0b00000000
out ADCSRB,R16
ldi R16,0x21 ;Select AD1 (pin 7) input, Select VCC as analogue reference. ADLAR (Left justify result)
out ADMUX,R16
ldi R16,0x04 ;Set PB2 as analoge input
out DIDR0,R16
;Initialize timer / counter
ldi R16,0x00 ;Normal operation
Out TCCR0A,R16
ldi R16,0x05 ; Prescale value 1024 (Inc counter every 0.8333 uS x 1024 = 853.3 uS (1171.88 hZ)
Out TCCR0B,R16 ; Counter will overflow every 218.445 mS (4,58 hZ)
; Counting to 234 would give 199.7 mS ( 256 - 234 = 22 = 0x16)
ldi R16,0x02 ;TOIE0 (Bit1) : Timer/Counter0 Overflow Interrupt Enable
Out TIMSK0,R16
;Init time counters
ldi N200mS,0x05
ldi Seconds,0x00
ldi Minutes,0x00
;Wait for button to be released (Wait for input to go high
Wait_Button_High:
sbis PINB,0
rjmp Wait_Button_High
bset 7 ;Enable global interrupst.
rjmp main
;Timer/Counter Overflow interrupt handler.
TC_overflow:
ldi R20,0x16 ;Preset timer so interrupt occures every 199.7 mS
out TCNT0,R20
dec N200mS ;200mS
breq TC01
RETI
TC01:
ldi N200mS,0x05
Inc_Sec:
SBRS Flags, 0
CBI PORTB,0x03 ;Clear battery low warning LED
SBRS Flags,0 ;Bat_Warning ;Skip if battery warning bit is set
RJMP Inc_S2
in R20,PORTB
ldi R21,0x08 ;Bits 3
eor R20,R21 ; Toggle bit 3 (Pin 2) (Every second)
out PORTB,R20
Inc_S2:
ldi R20,0x3C ;60 decimal
inc Seconds ;Increment seconds counter
cpse Seconds,R20
rjmp TC_End
CLR Seconds
Inc_Min:
ldi R20,0x3C ;60 decimal
inc Minutes ;Increment minute counter
cpse Minutes,R20
rjmp TC_End
CLR Minutes
TC_End:
RETI
; ------------------------------------- End of interrupt handlers --------------------------------------
;
; Main program code
;
Main:
nop
nop
ldi R20,Shutdown_minutes
cpse Minutes,R20 ;Is it time to shutdown ?
rjmp Not_Time
cbi PORTB,4 ;Clear PORTB bit 4
rjmp End_Loop
Not_Time:
nop
nop
nop
; rjmp Main ; Just loop waiting for interrupt
;Read ADC input value
ldi R16,0x84 ;Enable , Prescale value 16, No auto triggering
out ADCSRA,R16
ldi R16,0x21 ;Select AD1 input (pin 7) Select VCC as analogue reference, ADLAR (Left justify result)
out ADMUX,R16
sbi ADCSRA,ADSC ; Start ADC conversion
nop
Wait_ADC_Ready:
sbic ADCSRA,ADSC ; Wait_ADC_Ready:
rjmp Wait_ADC_Ready
in R20,ADCL ;Read ADC result L (Value not used but need to read this register befor high byte.)
in R20,ADCH ;Read ADC result H
;Test for battery warning level
CBR Flags,0x01 ;Bat_Warning ;Clear battery warning flag
CLC ;Clear carry flag
SBCI R20,Battery_Low
BRBC 0x00,Test_Shutdown ;Branch if carry bit is clear
SBR Flags,0x01 ;Bat_Warning ;Set battery warning flag bit
;Test for battery shutdown level
Test_Shutdown:
in R20,ADCH ;Read ADC result H again
CLC ;Clear carry flag
SBCI R20,Shutdown_volts
BRBS 0x00,Bat_Low ;Branch if carry bit is set
RJMP Bat_OK
Bat_Low:
CBI PORTB,0x04 ; Shutdown
End_loop:
NOP
RJMP End_loop ; Loop until power removed.
Bat_OK:
Test_button: ;If button pressed input will be low.
sbic PINB,0
rjmp Main ; Just loop waiting for interrupt
;Now wait 100 mS and recheck that button is pressed. (De bounce switch contacts)
rcall Delay_100ms
sbic PINB,0
rjmp Main
cbi PORTB,4 ;Clear PORTB bit 4
rjmp End_Loop
;Test_button:
sbis PINB,0
rjmp Test_button ;Loop until button pressed
;Now wait 100 mS and recheck that button is pressed. (De bounce switch contacts)
rcall Delay_100ms
sbis PINB,0
rjmp Test_button ;Loop until button is pressed
Button_open_loop:
sbic PINB,0 ;
rjmp Button_open_loop; loop until pedal released
;Subroutines.
;
;
; ----------------------------------------------
; Instruction cycle time is 0.83333 uS
; Delay 1mS Rcall to get here takes 3 instruction cycles. ret instruction takes 4 instruction cycles, ldi takes 1 instruction cycle (total 8)
; For 1 mS (1000 uS) we need 1000/0.83333 = 1200 instructions so need additional 1192 instructions 5 cycles in loop.
Delay_1_mS:
ldi count_L,0xEE ;Decimal 238 0xEE (Once round the loop is 5 instructions)
D_1mS_Loop:
dec count_L ; Count_L is R22 (1 cycle)
nop ;(1 cycle)
nop ;(1 cycle)
brne D_1mS_Loop ;If not zero (2 cycles while looping, 1 on exit)
ret
Delay_100ms:
ldi R21,0x64 ;100 decimal
Del_100ms_Loop:
rcall Delay_1_mS
dec R21
brne Del_100ms_Loop
ret
; -------------End of subroutines --------------
;
Do not eliminate. It is just to feel better?
Not sure about those 10 instead 12 you mention. Could you elaborate?
The bargraph, what does it display, actually? Is there any numeric calculation for that?
/*********************************************************
CharlieScanner
Software to generate a Larson scanner pattern on 12 LEDs
Charlieplexing is used in order to control the LEDs with
only 4 IO ports. One port reads in a voltage. The
software then changes speed accordingly.
Uses internal RC-Osc at 9.6 MHz/8
Fuses should be set to default
Written by Thomas Frey http://tomscircuits.blogspot.com/
$Date:$
*********************************************************/
; defines
#define tmp R16
#define tmp2 R17
#define duration R18
#define LED R19
#define adc_result R20
#define mode R21
#include "tn13def.inc"
.MACRO LEDon
ldi LED, @0
rcall setled
.ENDMACRO
.cseg
/*********************************************************
Interrupt vectors
*********************************************************/
.org 0 rjmp reset
.org INT0addr rjmp reset ;External Interrupt0
.org PCI0addr rjmp reset ;Pin Change Interrupt0
.org OVF0addr rjmp reset ;Overflow0 Interrupt
.org ERDYaddr rjmp reset ;EEPROM write complete
.org ACIaddr rjmp reset ;Analog Comparator Interrupt
.org OC0Aaddr rjmp reset ;Timer/Counter0 Compare Match A
.org OC0Baddr rjmp reset ;Timer/Counter0 Compare Match B
.org WDTaddr rjmp reset ;Watchdog Timeout
.org ADCCaddr rjmp reset ;ADC Conversion Complete Handle
/*********************************************************
Initialisation
*********************************************************/
reset:
; set stack pointer
ldi tmp, LOW(RAMEND)
out SPL, tmp
; set clock to 1,2 MHz
ldi tmp, 0b10000000
out CLKPR, tmp
ldi tmp, 0b00000011 ; Divide by 8
out CLKPR, tmp
; init ADC
ldi tmp, (1<<ADLAR)|(1<<MUX1) ; Use ADC in 8bit mode, PB4; Vcc is reference
out ADMUX, tmp
ldi tmp, (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADEN) ; Slow conversion, ADC on
out ADCSRA, tmp
rjmp main
; init registers
ldi mode, 0
/*********************************************************
Main loop
*********************************************************/
main:
cpi mode,0
brne mode1
LEDon 1
LEDon 2
LEDon 3
LEDon 4
LEDon 5
LEDon 6
LEDon 7
LEDon 8
LEDon 9
LEDon 10
LEDon 11
LEDon 12
LEDon 11
LEDon 10
LEDon 9
LEDon 8
LEDon 7
LEDon 6
LEDon 5
LEDon 4
LEDon 3
LEDon 2
rjmp main
mode1:
cpi mode, 1
brne mode2
LEDon 1
LEDon 2
LEDon 3
LEDon 4
LEDon 5
LEDon 6
LEDon 7
LEDon 8
LEDon 9
LEDon 10
LEDon 11
LEDon 12
rjmp main
mode2:
cpi mode, 2
brne mode3
LEDon 1
LEDon 12
LEDon 2
LEDon 11
LEDon 3
LEDon 10
LEDon 4
LEDon 9
LEDon 5
LEDon 8
LEDon 6
LEDon 7
LEDon 7
LEDon 6
LEDon 8
LEDon 5
LEDon 9
LEDon 4
LEDon 10
LEDon 3
LEDon 11
LEDon 2
LEDon 12
LEDon 1
rjmp main
mode3:
LEDon 1
LEDon 2
LEDon 1
LEDon 3
LEDon 2
LEDon 4
LEDon 3
LEDon 5
LEDon 4
LEDon 6
LEDon 5
LEDon 7
LEDon 6
LEDon 8
LEDon 7
LEDon 9
LEDon 8
LEDon 10
LEDon 9
LEDon 11
LEDon 10
LEDon 12
LEDon 11
LEDon 12
rjmp main
/*********************************************************
Sub routine: wait
Function: Generates a pause, depending on ADC
input
Parameter: none / duration - lenght of the pause
*********************************************************/
wait:
sbi ADCSRA, ADSC ; start ADC conversion
wait_adc:
sbic ADCSRA, ADSC ; wait for the ADC to finish
rjmp wait_adc
in adc_result, ADCH
tst adc_result
brne wait_cont ; not minimum? -> go on
; else: change mode
inc mode
andi mode, 0b00000011 ; wrap around (four modes only)
wait_endmode:
sbi ADCSRA, ADSC ; start ADC conversion
wait_adc2:
sbic ADCSRA, ADSC ; wait for the ADC to finish
rjmp wait_adc2
in adc_result, ADCH
tst adc_result
breq wait_endmode
wait_cont:
mov duration, adc_result
inc duration
ldi tmp, 0
timer_loop:
dec tmp
brne timer_loop
dec duration
brne timer_loop
ret
/*********************************************************
Sub routine: setled
Function: switches one LED on and waits
Parameter: LED - which LED to activate
0 means none
*********************************************************/
setled:
rcall setport
ldi tmp, 250
rcall wait
ret
/*********************************************************
Sub routine: setport
Function: switches one LED on
Parameter: LED - which LED to activate
0 means none
*********************************************************/
setport:
clr tmp
ldi ZL, LOW(translation*2)
ldi ZH, HIGH(translation*2)
lsl LED ; LED * 2 - for LPM instruction
add ZL, LED
adc ZH, tmp
lpm tmp, Z+
out DDRB, tmp
lpm tmp, Z
out PORTB, tmp
ret
translation:
.db 0b00000000, 0b00000000
.db 0b00000011, 0b00000001
.db 0b00000101, 0b00000001
.db 0b00001001, 0b00000001
.db 0b00000011, 0b00000010
.db 0b00000110, 0b00000010
.db 0b00001010, 0b00000010
.db 0b00000101, 0b00000100
.db 0b00000110, 0b00000100
.db 0b00001100, 0b00000100
.db 0b00001001, 0b00001000
.db 0b00001010, 0b00001000
.db 0b00001100, 0b00001000
/*********************************************************
Main loop
*********************************************************/
main:
LEDon 1
LEDon 2
LEDon 3
LEDon 4
LEDon 5
LEDon 6
LEDon 7
LEDon 8
LEDon 9
LEDon 10
LEDon 11
LEDon 12
LEDon 11
LEDon 10
LEDon 9
LEDon 8
LEDon 7
LEDon 6
LEDon 5
LEDon 4
LEDon 3
LEDon 2
rjmp main
/*********************************************************
Sub routine: wait
Function: Generates a pause, depending on ADC
input
Parameter: none / duration - lenght of the pause
*********************************************************/
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?