Strona 1 z 3

driver na ATtiny13A+ 2x AMC7124

: wtorek 30 gru 2014, 20:54
autor: magus
Witam,

Oto mój najnowszy projekt: driver do latarki na pojedynczą diodę.
ATtiny13A sterujący dwoma układami AMC7124.

Założenia:
1. 3 tryby 120mA, 360mA i 720mA
2. krótkie przyciśnięcie przycisku - zmiana trybu
3. długie (2 sek) naciśnięcie to wyłączenie sterownika
4. układ przystosowany do programowania ATtiny wlutowanego na płytce
5. zasilanie to pojedynczy aku 18650

Pierwsze podejście do schematu:

Obrazek

Program sterujący ATtiny:

Kod: Zaznacz cały

/*
 * Driver_Alfa_C.cpp
 *
 * Created: 2014-12-27 13:40:38
 *  Author: magus
 */ 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

// set 1MHz
#define F_CPU 1000000L

// power down after 2 sec push
//	prescaler set to 64
//	2xF_CPU/64/256 -> 122
#define PWR_DWN_DELAY 122

volatile int  timer=0;
volatile char counter=0;
volatile char but_state=0;
volatile char put_to_sleep=0;
//--------------------------
char button_down&#40;&#41;&#123;return &#40;PINB&1<<PB3&#41;>0;&#125;
//--------------------------
void tick_counter&#40;&#41;&#123;
	// counter modulo 4
	++counter;
	counter&=3;
		
	// update port
	PORTB=&#40;PORTB & 252&#41;+counter;
&#125;
//--------------------------
ISR&#40;TIM0_OVF_vect&#41; &#123;
	if&#40;++timer>PWR_DWN_DELAY&#41;&#123;
		// long push -> power down
		// 00 to out
		counter=3;
		tick_counter&#40;&#41;;
			
		// power down
		put_to_sleep=1;
	&#125;
&#125;
//--------------------------
ISR&#40;PCINT0_vect&#41;&#123;
	char bd=button_down&#40;&#41;;
	if&#40;bd&#41;&#123;
		if&#40;but_state==0&#41;&#123;
			// start timer
			timer=0;
			TIMSK0 |=1<<TOIE0;
			TCCR0B |= &#40;1<<CS01&#41; | &#40;1<<CS00&#41;;
			but_state=1;
		&#125;
	&#125;else&#123;
		// check timer
		// min delay is 32ms to handle bouncing
		if&#40;timer>1&#41;&#123;
			tick_counter&#40;&#41;;
			
			// turn off TIM0_OVF
			TIMSK0&=253;
			
			// button released
			but_state=0;
		&#125;
	&#125;
&#125;
//--------------------------
//--------------------------
//--------------------------	
int main&#40;void&#41;
&#123;
	//########### I/O ###########
	// PB0-PB1 -> out
	DDRB  |= &#40;1<<PB0&#41; | &#40;1<<PB1&#41;;
	    
	// int on pin3
	PCMSK |= &#40;1<<PCINT3&#41;;
	GIMSK  |= &#40;1<<PCIE&#41;;
	
	// timer int
	// prescale timer to 1/64 the clock rate
	// TCCR0B |= &#40;1<<CS01&#41; | &#40;1<<CS00&#41;;
			
	//##########################
	set_sleep_mode&#40;SLEEP_MODE_PWR_DOWN&#41;;
	sei&#40;&#41;;
	
	while&#40;1&#41;&#123;
		if&#40;put_to_sleep&#41;&#123;
			sleep_mode&#40;&#41;;
			put_to_sleep=0;
		&#125;
	&#125;
&#125;
ATtiny ma działać jak zwykły licznik modulo 4.
Czy zworka P0 jest potrzebna? Separuje ATtiny podczas jego programowania.
Czy w ATtiny13 podłączenie wejścia RESET do Vcc przez rezystor jest konieczne?

: wtorek 30 gru 2014, 21:28
autor: ElSor
Podłączenie Resetu nie jest konieczne ale warto czasem dać, nawet może być większy rezystor niż 10k.
Przycisk lepiej podłączyć do masy a nie Vcc, a jak do Vcc, to wejście musi być podciągnięte zewnętrznym rezystorem do masy (przy Vcc używa się podciągania wewnętrznego rezystora Pull-up).
Zamiast zworki lepiej dać diodę Schottky'ego przed wejściem Vcc do procka. Niezbędny może też się okazać kondensator ~10uF.
Kodu nie analizuję zbyt szczegółowo, bo bez komentarzy dużo rozkminiania jest :razz:

: czwartek 01 sty 2015, 15:34
autor: magus
Czy podłączając przycisk do masy potrzebny jest kondensator?
Nie mam pojęcia, jak wymienić zworkę na diodę :(

Podaję kod z komentarzami - (przycisk nadal podłączany do Vcc).
Kod nieco zoptymalizowany aby mieścił się w pamięci.

Kod: Zaznacz cały

/*
 * Driver_Alfa_C.cpp
 *
 * Created&#58; 2014-12-27 13&#58;40&#58;38
 *  Author&#58; magus
 */ 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

// zegar ustawiony na 1MHz
#define F_CPU 1000000L

// power down po 2 sek. nacisniecia przycisku
//	prescaler ustawiony na 64
//	2xF_CPU/64/256 -> 122
#define PWR_DWN_DELAY 122

volatile int  timer=0;	   // licznik przepelnien zegara
volatile char counter=0;     // stan wyjscia = tryb swiecenia 0,1,2,3
volatile char but_state=0;   // stan nacisniecia przycisku
volatile char put_to_sleep=0;// czas wylaczyc uklad

//--------------------------------------------
// obsluga przerwania przepelnienia licznika
//--------------------------------------------
ISR&#40;TIM0_OVF_vect&#41; &#123;
	// zwiekszamy licznik i sprawdzamy jak dlugo juz wlaczony
	if&#40;++timer>PWR_DWN_DELAY&#41;&#123;
		// trzymamy dlugo -> power down
		// wyzerowanie trybu/wyjscia
		counter=0;
		PORTB&=252;
			
		// power down -> ustawienie flagi
		// nie mozemy odpalic sleep_mode&#40;&#41; w procedurze przerwania!
		put_to_sleep=1;
	&#125;
&#125;
//---------------------------------------
// obsluga przerwania zmiany stanu pinu
// tu obslugujemy nacisniecie i puszczenie przycisku
//---------------------------------------
ISR&#40;PCINT0_vect&#41;&#123;
	if&#40;&#40;PINB&1<<PB3&#41;>0&#41;&#123; // odczytaj stan przycisku
		if&#40;but_state==0&#41;&#123;
			// jezeli wcisnelismy przycisk i nie byl juz nacisniety
			// to startujemy liczenie czasu 
			timer=0;

			// uruchamiamy przerwanie przepelnienia licznika
			TIMSK0 |= 1<<TOIE0;
			TCCR0B |= &#40;1<<CS01&#41; | &#40;1<<CS00&#41;;

			// zapamietac stan przycisku - wlaczony
			but_state=1;
		&#125;
	&#125;else&#123;
		// w momencie puszczenia przycisku
		// sprawdzamy, jak dlugo byl wlaczony
		// aby wyeliminowac problem drgania stykow, czekamy min 20ms
		// timer zyskuje 1 wartosc co 1/&#40;F_CPU/64/256&#41; ms
		// dla 1MHz to daje ok 16ms
		// dla timer==2 mamy 32ms, dosc czasu na ustabilizowanie stykow
		if&#40;timer>1&#41;&#123;
			// licznik/tryb modulo 4
			++counter;
			counter&=3;
	
			// update port
			PORTB=&#40;PORTB & 252&#41;+counter;
			
			// wylaczamy liczenie czasu - przerwanie TIM0_OVF
			TIMSK0&=253;
			
			// zapamietac stan przycisku - wylaczony
			but_state=0;

		&#125;
	&#125;
&#125;
//--------------------------
//--------------------------
//--------------------------	
int main&#40;void&#41;
&#123;
	//########### I/O ###########
	// ustawienie PB0-PB1 jako wyjscia
	DDRB  |= &#40;1<<PB0&#41; | &#40;1<<PB1&#41;;
	    
	// ustawiamy PB3 jako wejscie i ustawienie przerwania
	PCMSK |= &#40;1<<PCINT3&#41;;
	GIMSK  |= &#40;1<<PCIE&#41;;
	
	//ustawienie trybu usypiania na powerd down -> wylaczenie
	set_sleep_mode&#40;SLEEP_MODE_PWR_DOWN&#41;;
	sei&#40;&#41;;
	
	// petla robocza
	while&#40;1&#41;&#123;
		// flaga ustawiona w przerwaniu
		// tu realizacja, bo na tym poziomie wlaczone przerwania
		if&#40;put_to_sleep || counter==0&#41;&#123;
			// uspienie/wylaczenie procesora
			sleep_mode&#40;&#41;;
			put_to_sleep=0;
		&#125;
	&#125;
&#125;

: czwartek 01 sty 2015, 15:44
autor: GanzConrad
magus pisze:potrzebny jest kondensator?
wręcz niewskazany. Podczas zwarcia będzie rozładowywał się impulsowo dając zakłócenia.
http://mikrokontrolery.blogspot.com/
Osobiście zrobiłbym to na AMC7135 + PWM, ale to kwestia gustu i prostoty.

: czwartek 01 sty 2015, 15:53
autor: joon
GanzConrad pisze:Podczas zwarcia będzie rozładowywał się impulsowo dając zakłócenia.
proszę nie siać herezji

: czwartek 01 sty 2015, 16:16
autor: GanzConrad

: czwartek 01 sty 2015, 16:50
autor: joon
Tak tak, jak napiszę na jakieś stronce że ogień nie parzy to wsadzisz rękę w ognisko bo gdzieś to wyczytałeś?

: czwartek 01 sty 2015, 17:04
autor: dondu
Witam serdecznie jako nowy na tym forum :)

Ponieważ zostałem wywołany do tablicy:
joon pisze:Tak tak, jak napiszę na jakieś stronce że ogień nie parzy to wsadzisz rękę w ognisko bo gdzieś to wyczytałeś?
... a jeśli to jest oficjalna nota producenta tego mikrokontrolera (firmy Atmel) o numerze AVR042 opisana jedynie (w tym zakresie) we wskazanym przez kolegę wyżej artykule?

Sądzę jednak, że kol.
ElSor pisze:Niezbędny może też się okazać kondensator ~10uF.
miał na myśli 10uF na zasilaniu, a nie na pinie Reset. Czy tak?

: czwartek 01 sty 2015, 17:34
autor: ElSor
dondu pisze:Sądzę jednak, że kol.

ElSor napisał/a:
Niezbędny może też się okazać kondensator ~10uF.

miał na myśli 10uF na zasilaniu, a nie na pinie Reset. Czy tak?
No oczywiście. Wspominam o nim w linijce o zasilaniu procesora przez zworkę, o resecie była 1wsza linijka.
dondu pisze:Ponieważ zostałem wywołany do tablicy
Skąd wiedziałeś, po ~1h, że ktoś Cię tutaj linkuje/przywołuje?
dondu pisze:Witam serdecznie jako nowy na tym forum :)
Witam również. Mam nadzieję, że zostaniesz u nas na dłużej i może pokażesz coś ciekawego związanego z oświetleniem.

: czwartek 01 sty 2015, 17:49
autor: dondu
Google Alerts - i wszystko jasne :)
Z przyjemnością zaglądnę, jeśli będę mógł w czymś pomóc.

: czwartek 01 sty 2015, 18:09
autor: magus
To ja poproszę o dokładniejszy opis (mile widziana rycinka :) ) poniższego rozwiązania:
ElSor pisze:...
Zamiast zworki lepiej dać diodę Schottky'ego przed wejściem Vcc do procka. Niezbędny może też się okazać kondensator ~10uF.
...
Nie jestem elektronikiem i jak czegoś skądś nie skopiuję to sam raczej nie wymyślę :)

Co do przycisku podłączanego do masy.

W necie znalazłem dwa rozwiązania -> jedno bez kondensatora, drugie z kondensatorem. Jeżeli kondensator ma za zadanie tylko rozwiązać problem drgania styków to chyba jest zbyteczny, skoro rozwiązałem (mam nadzieje) problem programowo...

: czwartek 01 sty 2015, 18:15
autor: ElSor
Obrazek
D1 - dioda Schottkyego (na schemacie zwykła jest). C1 to kondensator 10uF ale można też równolegle podłączyć 100nF. Reszta połączeń Ciebie nie dotyczy.

: czwartek 01 sty 2015, 18:50
autor: joon
dondu pisze:... a jeśli to jest oficjalna nota producenta tego mikrokontrolera (firmy Atmel) o numerze AVR042 opisana jedynie (w tym zakresie) we wskazanym przez kolegę wyżej artykule?
przez dziesięciolecia takie układy były realizowane przez wiodących producentów elektroniki i nagle prawa fizyki zmieniły się? Proszę mi pokazać/pomierzyć/udokumentować zniszczony przycisk. Bo sama teoria nawet podparta notami nie ma nic wspólnego z praktyką.
magus pisze:W necie znalazłem dwa rozwiązania -> jedno bez kondensatora, drugie z kondensatorem. Jeżeli kondensator ma za zadanie tylko rozwiązać problem drgania styków to chyba jest zbyteczny, skoro rozwiązałem (mam nadzieje) problem programowo...
piszesz teraz o kondensatorze na zasilaniu czy przy przycisku?

: czwartek 01 sty 2015, 18:56
autor: dondu
joon pisze:
dondu pisze:... a jeśli to jest oficjalna nota producenta tego mikrokontrolera (firmy Atmel) o numerze AVR042 opisana jedynie (w tym zakresie) we wskazanym przez kolegę wyżej artykule?
przez dziesięciolecia takie układy były realizowane przez wiodących producentów elektroniki i nagle prawa fizyki zmieniły się? Proszę mi pokazać/pomierzyć/udokumentować zniszczony przycisk. Bo sama teoria nawet podparta notami nie ma nic wspólnego z praktyką.
Jaki zniszczony przycisk? Przecież nie o to chodzi :) Kol. GanzConrad zwrócił uwagę na coś zupełnie innego. Czy dla tego projektu będzie to istotne ? Pewnie nie, ale czasami warto dodać jeden rezystor za 4 grosze, by mieć pewność prawidłowego działania urządzenia.

Drobna uwaga do programu.

Zamiast

Kod: Zaznacz cały

if&#40;&#40;PINB&1<<PB3&#41;>0&#41;
wystarczy:

Kod: Zaznacz cały

if&#40;PINB&1<<PB3&#41;
aby nigdy się nie pomylić sugeruję dodatkowe nawiasy tak jak stosujesz w innych miejscach:

Kod: Zaznacz cały

if&#40;PINB & &#40;1<<PB3&#41;&#41;

: czwartek 01 sty 2015, 20:27
autor: Pyra
Witam
Panowie, nie ma się co kłócić o ten kondensator. Jego zastosowanie lub nie, jest uzależnione od aplikacji i zjawisko rezonansu obwodu LC, powodujące powstawanie szpilek, występuje w różnym stopniu. Od dawna znane są zależności rządzące rezonansem obwodów LC, i wiadomo, że wprowadzenie dodatkowej rezystancji, znacznie zjawisko ogranicza a wręcz może je wyeliminować. Kwestia tylko dobrania odpowiedniej rezystancji i miejsca jej zabudowania. Można ją dać w obwodzie szeregowo ze stykiem, lub szeregowo z kondensatorem. De facto, wystarcza już mała wartość, nie wpływająca na resztę układów.
Jedyne ograniczenie wartości tej rezystancji od góry, jest określone wartością rezystora podciągającego, który w przypadku wykorzystania rezystancji wewnętrznej, co w omawianym układzie będzie miało na pewno zastosowanie, ma wartość około 50k&#937;. Biorąc pod uwagę, że stan "zero" na pinie wejściowym musi mieć wartość nie większą niż 0,3Vcc (w omawianym układzie), czyli przy zasilaniu z 3V minus 0,2V na diodę zabezpieczającą, daje nam około Vcc = 2,8V
więc
2,8V x 0,3 = 0,8V

No cóż, przyjmując spory margines bezpieczeństwa, można przyjąć 0,5V. Teraz można wyliczyć sobie wartość owego rezystora, przyjmując go jako element dzielnika napięcia, dającego na wyjściu 0,5V.
No cóż, jak widać, wychodzi kilka k&#937;, a taka wartość potrafi już skutecznie ograniczyć prąd rozładowania kondensatora. W praktyce, 100&#937;, jest w zupełności wystarczające, a eliminuje kawałek kodu odpowiedzialny za zniwelowanie efektu drgań styków.

Pozdrawiam