Blikačka na jízdní kolo

Z MAM wiki

Přejít na: navigace, hledání

[editovat] Zadání

Sestrojte inteligentní blikačku na jízdní kolo.

Požadavky:

 * Spotřeba pod 1 uA ve vypnutém režimu při 25°C
 * Zapínání a vypínání jedním tlačítkem
 * Jediný mód blikání přibližně 4x za vteřinu bliknout
 * Při vybitých bateriích neblikat (pod 2V u NiMH akumulátorů)

Předpoklady pro nízkou spotřebu:

 * Využívání Power-Down módu ve vypnutém stavu
 * Využívání Idle módu při blikání
 * Vypnutí Watchdogu
 * Vypnutí Brownout detektoru
 * Vypnutí Resetu 
 * Připojení všech nepoužitých vývodů na zem
 * Vypnutí pull-upů
 * Měření napájecího napětí jen jednou při zapnutí s rozsvícenými diodami

Detaily:

 * Použití MOSFE tranzistoru pro spínání proudu LEDkami
 * Napájení děliče napětí pro měření napájení připojovat jen při měření

[editovat] Realizace

schéma
plošný spoj
osazení součástek bottom
osazení součástek top
realizace
realizace
; *************************************************************************************************
;
;  Program pro blikacku na jizdni kolo
;  Pri spusteni blikacky log. 0 na pinu PB1 se zmeri napeti na vstupu PB3(ADC3).
;  Pokud je nizsi nez hodnota nastavena v zahlavi programu tak se blikani nezapne.
;  Vystup pro led je pripojen na pin PB4 
;  Napajeni delice pro mereni napajeciho napeti je vyvedeno z pinu PB5
;
; 	Autor: Pavel Vitvar	 	
; 	Pro ATtiny13A
;
; *************************************************************************************************
.include "tn13adef.inc"
.dseg


;---------------------------------------------------
.org	0x60
panelak:		.byte	1
;.equ	wait		=	0
.equ	slp_req		=	1
.equ	power		=	2	;1=zapnuto 0=vypnuto
;---------------------------------------------------

.equ	tccr0b_on	=	0b00000101	;Timer clock = system clock/1024
.equ	tccr0b_off	=	0b00000000	;Timer clock = no clock

; vystupy a vstupy
.equ	led_out		=	4	;PB4
.equ	inbutton	=	1	;PB1
.equ	adin		=	3	;PB3
.equ	vinpin		=	5	;PB5


;definice minimalniho napeti
.equ	vcc_min		=	117	;256*min/4.4 (na pin ADC3/PB3 je pripojen delic napajeciho napeti 1/4)


.cseg
; Interrupt Vectore Table	
.org	0x00				; Reset-Address
	rjmp	start
.org	INT0addr			; External Interrupt 0
	rjmp	int0code
.org	PCI0addr			; External Interrupt Request 0
.org	OVF0addr			; Timer/Counter0 Overflow
.org	ERDYaddr			; EEPROM Ready
.org	ACIaddr				; Analog Comparator
.org	OC0Aaddr			; Timer/Counter Compare Match A
	rjmp	intOC0A
.org	OC0Baddr			; Timer/Counter Compare Match B
.org	WDTaddr				; Watchdog Time-out
.org	ADCCaddr			; ADC Conversion Complete

;---------------------------------------------------------------------------
;	Hlavni program
;---------------------------------------------------------------------------
start:	ldi	r16,low(RAMEND)	;inicializace stack pointeru
	out	SPL,r16

	;predpokladam 128kHz clock a reset je disabled

	rcall	Pinout_init
	rcall	Int_init

	ldi	r20,0x00		;napajeni je v poradku a probiha mereni
	sts	panelak,r20

	cbi	portb,led_out		;vypnuti vystupu

	in	r20,MCUCR
	ori	r20,0b00110000		;sleep enable with power_down mode
	out	MCUCR,r20

	lds	r20,panelak
	ori	r20,(1<<slp_req)	;pozadavek na uspani	
	sts	panelak,r20

	sei					;Global Interrupts enabled


;----- hlavni smycka -------------------------------

loop:	lds	r20,panelak
 	sbrs	r20,slp_req		;pokud je pozadovano uspani tak vymazat priznak a uspat
	rjmp	loop

	lds	r20,panelak		
	andi	r20,0xff^(1<<slp_req)	;nulovani xorem
	sts	panelak,r20

	sleep
	
	rjmp	loop

;---------------------------------------------------------------------------
;	Zpozdovaci smycka asi 200ms
;---------------------------------------------------------------------------
delay:	
	ldi	r16,34
delay1:	inc	r1
	brne	delay1
	dec	r16
	brne	delay1
	ret
;---------------------------------------------------------------------------
;	Obsluha preruseni
;---------------------------------------------------------------------------
intOC0A:
	in	r18,portb		;invertace vystupu
	ldi	r19,(1<<led_out)	;
	eor	r18,r19
	out	portb,r18

	lds	r16,panelak
	ori	r16,(1<<slp_req)	;pozadavek na uspani	
	sts	panelak,r16


	reti
;---------------------------------------------------------------------------
;	Obsluha preruseni
;---------------------------------------------------------------------------
int0code:

	lds	r16,panelak		;vyber stavu zapnuto vypnuto
	sbrc	r16,(power)		;pokud je vypnuto tak zapnem (skok)
	rjmp	int0c_v0	
	

;------------------------------------------
;---- Zapnuti -----------------------------
	lds	r16,panelak
	ori	r16,(1<<power)		;nastaveni ukazatele zapnuti
	sts	panelak,r16

	sbi	portb,led_out		;zapnuti vystupu
	sbi	portb,vinpin		;zapnuti napajeni na merici delic

	rcall	ADC_init		;inicializace ADC
	rcall	ADC_start		;spusteni mereni

int0c_z0:
	in	r16,ADCSRA
	sbrs	r16,(ADIF)		;pokud je znam vysledek tak jej zpracujem (skok)
	rjmp	int0c_z0		;pokud neni tak to zkousej dal
	
	cbi	portb,vinpin		;vypnuti mericiho delice	

	in	r16,ADCH		;nacteni zmerene hodnoty a porovnani
	cpi	r16,vcc_min
	brlo	int0c_v0		;pokud je nizsi tak skok na vypinaci vetev


;---- pokud je hodnota nizsi tak jen uspi 
int0c_z1:	
	in	r16,MCUCR
	ori	r16,0b00100000		;sleep enable 
	andi	r16,0b11100111		;with idle mode
	out	MCUCR,r16

	lds	r16,panelak
	ori	r16,(1<<slp_req)	;pozadavek na uspani	
	sts	panelak,r16

	rcall	ADC_off

int0c_z2:
	sbis	pinb,inbutton
	rjmp	int0c_z2

	rcall	T0_on			;spusteni casovace

	rjmp	int0c_end


;------------------------------------------
;---- Vypnuti -----------------------------
int0c_v0:
	lds	r16,panelak		
	andi	r16,0xff^(1<<power)	;vynulovani priznaku zapnuti
	sts	panelak,r16

	in	r16,MCUCR
	ori	r16,0b00110000		;sleep enable 
	andi	r16,0b11110111		;with power_down mode
	out	MCUCR,r16

	lds	r16,panelak
	ori	r16,(1<<slp_req)	;pozadavek na uspani	
	sts	panelak,r16

	rcall	T0_off			;vypnuti periferii
	rcall	ADC_off

	sbi	portb,led_out		;zapnuti vystupu po dobu stisknuti tlacitka

int0c_v1:
	sbis	pinb,inbutton
	rjmp	int0c_v1

	cbi	portb,led_out		;vypnuti vystupu

int0c_end:

	rcall	delay

	reti
;---------------------------------------------------------------------------
;	Nastaveni vstupu a vystupu
;---------------------------------------------------------------------------
Pinout_init:
; Define pull-ups and set outputs high
; Define directions for port pins
	in	r16,MCUCR
	ori	r16,0x40	;0x40=>PullUp=disabled, 0x00=>PullUp=enabled	
	out	MCUCR,r16
				;DDxn	PUD
				;  0	 0	Bidirectional	
				;  0	 1	Input only = Open collector
				;  1	 x	Push - Pull
	
	ldi 	r16,((1<<inbutton)|(1<<adin))
	ldi 	r17,0xff^((1<<inbutton)|(1<<adin))
	out 	PORTB,r16
	out 	DDRB,r17
	
	; Insert nop for synchronization
	nop
	ret
;---------------------------------------------------------------------------
;	Nastaveni externiho preruseni 
;---------------------------------------------------------------------------
Int_init:
	in	r16,MCUCR
	andi	r16,0b11111100	;low level interrupt generation
	out	MCUCR,r16

	ldi	r16,0b01000000	;enable of int0 interrupt
	out	GIMSK,r16

	ldi	r16,0b00000000	;clear all interrupt flags
	out	GIFR,r16

	ldi	r16,0b00000000	;enable of interrupt
	out	PCMSK,r16
			
	ret
;---------------------------------------------------------------------------
;	Nastaveni a spusteni timeru 0
;---------------------------------------------------------------------------
T0_on:
	ldi	r16,16		;OCR0A = 16
	out	OCR0A,r16

	ldi	r16,0b00000010
	out	TCCR0A,r16	;Timer mode = CTC

	ldi 	r16,tccr0b_on
	out 	TCCR0B,r16 	;Timer clock = system clock/1024

	ldi	r16,0b00000100
	out	TIMSK0,r16	;Interrupt from OCR0A

	ldi 	r16,0b00000000
	out 	TIFR0,r16 	;Clear pending interrupts

	ldi	r16,0		
	out	TCNT0,r16	;Reset timer internal counting register
	ret
;---------------------------------------------------------------------------
;	Vypnuti timeru 0
;---------------------------------------------------------------------------
T0_off:

	ldi 	r16,tccr0b_off
	out 	TCCR0B,r16 	;Timer clock = system clock/1024

	ret
;---------------------------------------------------------------------------
;	Nastaveni ADC
;---------------------------------------------------------------------------
ADC_init:
	ldi	r16,0b10000000	;Enable ADC system clk/2
	out	ADCSRA,r16

	ldi	r16,0b01100011	;Input PB3 selected and internal reference and data left alignment
	out	ADMUX,r16

	ldi	r16,0b00000000	;Free running mode
	out	ADCSRB,r16		

	ldi	r16,0b00001000	;Digital input ADC3 disable
	out	DIDR0,r16

	;ldi	r16,0b11000000	;Enable ADC + prescaler setup + Start conversion
	;out	ADCSRA,r16
	ret
;---------------------------------------------------------------------------
;	Spusteni konverze ADC
;---------------------------------------------------------------------------
ADC_start:
	in	r16,ADCSRA
	ori	r16,0b01000000	;Start conversion
	out	ADCSRA,r16
	ret
;---------------------------------------------------------------------------
;	Vypnuti ADC
;---------------------------------------------------------------------------
ADC_off:
	in	r16,0b00000000
	out	ADCSRA,r16
	ret
;---------------------------- konec -----------

--Vitvapav 17. 5. 2012, 07:30 (UTC)

Osobní nástroje