logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

sterowanie diod 20 led- kod atmega16 przenieś na atmega8

matii_speed 24 Sty 2011 14:34 10979 36
  • #1 9050206
    matii_speed
    Poziom 16  
    Witam.
    Szukam pomocy w napisaniu kodu do wydaje mi się prostego układu, chodzi o sterowanie 20 diodami led.

    Zasada działania
    Wciskam przycisk (np zwarcie do masy) zapalają się diody od prawej do lewej, ale zapala się dioda 1 i świeci potem 2 i świeci, i tak dalej aż do 20 i wtedy świecą już wszystkie. Następnie po np 3 sekundach zaczynają gasnąć od diody 20 do 1 aż zgasną wszystkie. Czynność ta miała by się uruchamiać po naciśnięciu włącznika.

    Oraz po naciśnięciu 2 przycisku zaczyna się robić to samo ale w odwrotnej kolejności czyli od lewej do prawej.
    A jeszcze czas zapalania się kolejnych diod to 0.4s.

    Robię makietę pasa startowego, myślę że potrafię zaprogramować µC bo kiedyś się trochę bawiłem ale nie potrafię napisać kodu..

    Po rozmowie z kolegą Mictronic dostałem kod ale na atmega16:
    switche są na PA.0 i PA.1
    LED na PORTB,C,D
    kwarc wewnętrzny standardowy 1Mhz

    Kod:
    
    $sim
    $regfile = "m16def.dat"
    $crystal = 1000000                                          'przykładowo masz zegar 1Mhz
    
    Ddrb = 255
    Ddrc = 255
    Ddrd = 255
    
    Ddra.0 = 0
    Ddra.1 = 0
    
    
    Dim A As Byte
    Dim Flaga As Bit
    Dim Program As Bit
    
    Do
    
       If Flaga = 0 Then
    
        Porta.0 = 1
        Porta.1 = 1
    
          If Pina.0 = 0 Then : Program = 0 : Flaga = 1 : End If
          If Pina.0 = 0 Then : Program = 1 : Flaga = 1 : End If
    
       End If
    
    If Flaga = 1 Then
    
       If Program = 0 Then
        Portb.0 = 1
             For A = 1 To 7
                Shift Portb , Left , 1
                waitms 150
                Next A
    
                Portc.0 = 1
                Portb.7 = 0
    
                For A = 1 To 7
                Shift Portc , Left , 1
                waitms 150
                Next A
    
                Portd.0 = 1
                Portc.7 = 0
    
                For A = 1 To 7
                Shift Portd , Left , 1
                waitms 150
             Next A
    
    
          For A = 1 To 7
                Shift Portd , Right , 1
                waitms 150
                Next A
    
                Portc.7 = 1
                Portd.0 = 0
    
                For A = 1 To 7
                Shift Portc , Right , 1
                waitms 150
                Next A
    
                Portb.7 = 1
                Portc.0 = 0
    
                For A = 1 To 7
                Shift Portb , Right , 1
                waitms 150
             Next A
    
             Portb.0 = 0
    
       End If
    
       If Program = 1 Then
    
          Portd.7 = 1
             For A = 1 To 7
                Shift Portd , Right , 1
                waitms 150
                Next A
    
                Portc.7 = 1
                Portd.0 = 0
    
                For A = 1 To 7
                Shift Portc , Right , 1
                waitms 150
                Next A
    
                Portb.7 = 1
                Portc.0 = 0
    
                For A = 1 To 7
                Shift Portb , Right , 1
                waitms 150
             Next A
    
             Portb.0 = 1
    
             For A = 1 To 7
                Shift Portb , Left , 1
                waitms 150
                Next A
    
                Portc.0 = 1
                Portb.7 = 0
    
                For A = 1 To 7
                Shift Portc , Left , 1
                waitms 150
                Next A
    
                Portd.0 = 1
                Portc.7 = 0
    
                For A = 1 To 7
                Shift Portd , Left , 1
                waitms 150
             Next A
    
       End If
       Portb = 0
       Portc = 0
       Portd = 0
       Flaga = 0
    End If
    
    Loop 


    Czy dało by się zmodyfikować całość żeby działało by to na atmega8?
    Pozdrawiam.

    Proszę, zgodnie z regulaminem pkt 11.1, o usunięcie słów PROBLEM lub/i POMOC z tytułu. Prośba dotyczy także wszelkich wariacji typu: kłopot, pomocy, problemy itd.
    Proszę równocześnie, o poprawienie błędów w poście. - arnoldziq
  • #2 9051982
    Krauser
    Poziom 26  
    Każdy kiedyś zaczynał. Program da się przerobić. Dla ułatwienia kod kolegi Mictronic'a z komentarzem:

    
    $sim 'ta linia tylko do symulacji, przed zaprogramowaniem usunąć
    $regfile = "m16def.dat" 'wybór procesora, zmienić na m8def.dat
    $crystal = 1000000                                          'przykładowo masz zegar 1Mhz 
    
    Ddrb = 255 'konfiguruje wszystkie linie portu jako wyjścia inny zapis to &B11111111
    Ddrc = 255 
    Ddrd = 255 
    
    Ddra.0 = 0 'konfiguracja wybranej linii portu jako wejście
    Ddra.1 = 0 
    
    
    Dim A As Byte 'zmienne wykorzystane w programie Byte - 8 bitów - 0-255, Bit - 0 lub 1
    Dim Flaga As Bit 
    Dim Program As Bit 
    
    Do 'początek nieskończonej pętli (wszystko co zawarte pomiędzy DO a LOOP będzie sie wykonywać cyklicznie)
    
       If Flaga = 0 Then 'tłumacząc z angielskiego jeśli Flaga jest równa 0 to
    
        Porta.0 = 1 'ustawienie podciągania dla linii wejściowej (gdyby były wyjściami to ta sama komenda zmienia stan linii portu) wtedy do wejścia wystarczy dołączyć tylko przycisk który zwiera do masy
        Porta.1 = 1 
    
          If Pina.0 = 0 Then : Program = 0 : Flaga = 1 : End If 'jeśli wejście zwarte do masy to Program = 0 i Flaga = 1
          If Pina.0 = 0 Then : Program = 1 : Flaga = 1 : End If 'mały błąd bo powinno być Pina.1 dla drugiego przycisku
    
       End If 'koniec If Flaga = 0
    
    If Flaga = 1 Then 
    
       If Program = 0 Then 
        Portb.0 = 1 'ustawienie stanu wybranego wyjścia na 1
             For A = 1 To 7 ' Dla A = 1 do A=7 wykonuj to co do linii Next A czyli 8 razy
                Shift Portb , Left , 1 'przesuń stan portu o 1 w lewo czyli z np. 00000001 zmiana na 00000010
                waitms 150 'czekaj 150 mili sekund
                Next A 'koniec pętli For A = 1 To 7
    
                Portc.0 = 1 'ustawia stan linii wyjściowej na 1
                Portb.7 = 0 'ustawia stan linii wyjściowej na 0
    
                For A = 1 To 7 
                Shift Portc , Left , 1 
                waitms 150 
                Next A 
    
                Portd.0 = 1 
                Portc.7 = 0 
    
                For A = 1 To 7 
                Shift Portd , Left , 1 
                waitms 150 
             Next A 
    
    
          For A = 1 To 7 
                Shift Portd , Right , 1 
                waitms 150 
                Next A 
    
                Portc.7 = 1 
                Portd.0 = 0 
    
                For A = 1 To 7 
                Shift Portc , Right , 1 
                waitms 150 
                Next A 
    
                Portb.7 = 1 
                Portc.0 = 0 
    
                For A = 1 To 7 
                Shift Portb , Right , 1 
                waitms 150 
             Next A 
    
             Portb.0 = 0 
    
       End If 
    
       If Program = 1 Then 
    
          Portd.7 = 1 
             For A = 1 To 7 
                Shift Portd , Right , 1 
                waitms 150 
                Next A 
    
                Portc.7 = 1 
                Portd.0 = 0 
    
                For A = 1 To 7 
                Shift Portc , Right , 1 
                waitms 150 
                Next A 
    
                Portb.7 = 1 
                Portc.0 = 0 
    
                For A = 1 To 7 
                Shift Portb , Right , 1 
                waitms 150 
             Next A 
    
             Portb.0 = 1 
    
             For A = 1 To 7 
                Shift Portb , Left , 1 
                waitms 150 
                Next A 
    
                Portc.0 = 1 
                Portb.7 = 0 
    
                For A = 1 To 7 
                Shift Portc , Left , 1 
                waitms 150 
                Next A 
    
                Portd.0 = 1 
                Portc.7 = 0 
    
                For A = 1 To 7 
                Shift Portd , Left , 1 
                waitms 150 
             Next A 
    
       End If 
       Portb = 0 
       Portc = 0 
       Portd = 0 
       Flaga = 0 
    End If 
    
    Loop ' skocz do DO
    
  • #3 9053222
    Konto nie istnieje
    Poziom 1  
  • #4 9055072
    matii_speed
    Poziom 16  
    Zasada działania:

    załóżmy że wszystkie diody ustawimy w rzędzie jedna za drugą(diody nie świecą)
    wciskam przycisk pierwszy i diody zaczynają się zapalać w prawo w kolejności 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20 (w tym że zapalone diody nie gasną po zapaleniu kolejnych) mijają 3 sekundy diody zaczynają gasnąć w odwrotnej kolejności 20-19-18-17-16-15-14-13-12-11-10-9-8-7-6-5-4-3-2-1 i zgasły wszystkie.
    Drugi przycisk ma działać tak samo tylko w kierunku od lewej do prawej,
    nie ma np znaczenia czy użyje przycisku np 1 - 10 razy a 2 tylko raz albo inaczej maiło by to się tylko uruchamiać gdy nacisnę dowolny przycisk.

    Nie wiem czy zrozumiale pisze.. Podaje link na którym znalazłem podobny efekt tyle że działa to w jedną stronę np w lewo
    http://www.youtube.com/watch?v=mh2LyQl25IA
  • #6 9062496
    matii_speed
    Poziom 16  
    sterowanie diod 20 led- kod atmega16 przenieś na atmega8

    Schemat nie będzie jakoś rozbudowany i program też nie musi. Na schemacie nie ma tranzystorów przed diodami
  • #7 9062960
    LordBlick
    VIP Zasłużony dla elektroda
    Ten schemat jest tylko ściśle teoretyczny, nie można tak przeciążać układu, szczegóły w nocie katalogowej w sekcji "Electrical Characteristics". Zastosuj ULN2003 lub ULN2803 lub po tranzystorze NPN (np. BC547) na kanał z rezystorem 4,7kΩ na bazie, LED z rezystorem 360Ω÷470Ω w szeregu na kolektor, emiter do GND. Dodatkowo można dać 10kΩ na /RESET do Vcc.
  • #8 9063575
    matii_speed
    Poziom 16  
    Ale to dale nie rozwiązuje mojego problemu z kodem..
  • Pomocny post
    #9 9067133
    Przemo1268
    Poziom 20  
    Witam
    Oto kod w języku C. Odnośnie schematu - będzie wszystko działało prawidłowo, gdy zastosujemy diody LED niskoprądowe (np. takie o prądzie 2 mA)

    
    /*	Czestotliwosc taktowania procesora 1 MHz (korzystamy z wewn. RC 1MHz)
     *	Procesor ATmega 8
     */
    #define F_CPU 1000000UL
    
    #include <avrio.h>
    #include <utildelay.h>
    
    #define Czas_zalaczania 400	//Czas oczekiwania na zapalenie/wylaczenie kolejnej diody
    #define Czas_zalacz_wylacz 3000 //Czas oczekiwania od momentu zalaczenia wszystkich diod do rozpoczecia cyklu kolejnego wylaczania
    
    typedef enum
    {
    	WYLACZ = 0,
    	ZALACZ = 1
    } StanDiody;
    
    typedef enum
    {
    	ZADEN = 0,
    	PRAWO = 1,
    	LEWO = 2
    } Klawisz;
    
    /* Klawisze sterujace na PD0 i PD1
     * Klawisz "Prawo" (D1->D20) 
     * Klawisz "Lewo" (D1<-D20)
     * 
     * Diody:
     * D1 	PortD.2
     * D2 	PortD.3
     * D3 	PortD.4
     * D4 	PortB.6
     * D5 	PortB.7
     * D6 	PortD.5
     * D7 	PortD.6
     * D8 	PortD.7
     * D9 	PortB.0
     * D10	PortB.1
     * D11	PortB.2
     * D12	PortB.3
     * D13	PortB.4
     * D14	PortB.5
     * D15	PortC.0
     * D16	PortC.1
     * D17	PortC.2
     * D18	PortC.3
     * D19	PortC.4
     * D20	PortC.5
     */
    
    void InicjalizacjaPortow()
    {
    	//Piny klawiatury jako wejscia (piny D0 do D1)
    	DDRD &= ~0x03;
    	//Pull-up
    	PORTD |= 0x03;
    
    	//Piny diod jako wyjscia, stan niski (diody wylaczone)
    	DDRB |= 0xFF;
    	PORTB &= ~0xFF;
    
    	DDRC |= 0x3F;
    	PORTC &= ~0x3F;
    
    	DDRD |= 0xFC;
    	PORTD &= ~0xFC;
    }
    
    void SterujLed(int dioda, StanDiody stan)
    {
    	int *Port;
    	int Pin;
    
    	switch(dioda)
    	{
    		case 1:
    			Port = &PORTD;
    			Pin = 2;
    			break;
    		case 2:
    			Port = &PORTD;
    			Pin = 3;
    			break;
    		case 3:
    			Port = &PORTD;
    			Pin = 4;
    			break;
    		case 4:
    			Port = &PORTB;
    			Pin = 6;
    			break;
    		case 5:
    			Port = &PORTB;
    			Pin = 7;
    			break;
    		case 6:
    			Port = &PORTD;
    			Pin = 5;
    			break;
    		case 7:
    			Port = &PORTD;
    			Pin = 6;
    			break;
    		case 8:
    			Port = &PORTD;
    			Pin = 7;
    			break;
    		case 9:
    			Port = &PORTB;
    			Pin = 0;
    			break;
    		case 10:
    			Port = &PORTB;
    			Pin = 1;
    			break;
    		case 11:
    			Port = &PORTB;
    			Pin = 2;
    			break;
    		case 12:
    			Port = &PORTB;
    			Pin = 3;
    			break;
    		case 13:
    			Port = &PORTB;
    			Pin = 4;
    			break;
    		case 14:
    			Port = &PORTB;
    			Pin = 5;
    			break;
    		case 15:
    			Port = &PORTC;
    			Pin = 0;
    			break;
    		case 16:
    			Port = &PORTC;
    			Pin = 1;
    			break;
    		case 17:
    			Port = &PORTC;
    			Pin = 2;
    			break;
    		case 18:
    			Port = &PORTC;
    			Pin = 3;
    			break;
    		case 19:
    			Port = &PORTC;
    			Pin = 4;
    			break;
    		case 20:
    			Port = &PORTC;
    			Pin = 5;
    			break;
    		default:
    			return;
    	}
    
    	if(stan == ZALACZ) *Port |= (1 << Pin);
    	else if(stan == WYLACZ) *Port &= ~(1 << Pin);
    }
    
    Klawisz SprawdzStanKlaw()
    {
    	int Licznik;
    
    	//sprawdzamy stan przycisku "Prawo"
    	if((PIND & 0x01) == 0)
    	{
    		//stan niski - przycisk wcisniety
    		//testujemy stan przycisku w czasie 100ms
    		//w celu eliminacji wplywu zaklocen
    		for(Licznik = 0;Licznik < 10;Licznik++)
    		{
    			_delay_ms(10);
    			if((PIND & 0x01) > 0) return ZADEN; //stan niestabilny wychodzimy z funkcji
    		}
    		return PRAWO; //stan przycisku stabilny, klawisz "prawo"
    	}
    
    	//sprawdzamy stan przycisku "Lewo"
    	if((PIND & 0x02) == 0)
    	{
    		//stan niski - przycisk wcisniety
    		//testujemy stan przycisku w czasie 100ms
    		//w celu eliminacji wplywu zaklocen
    		for(Licznik = 0;Licznik < 10;Licznik++)
    		{
    			_delay_ms(10);
    			if((PIND & 0x02) > 0) return ZADEN; //stan niestabilny wychodzimy z funkcji
    		}
    		return LEWO; //stan przycisku stabilny, klawisz "prawo"
    	}
    	return ZADEN; //zaden z przyciskow nie zostal wybrany
    }
    
    int main()
    {
    	int licznik;
    	Klawisz przycisk;
    
    	InicjalizacjaPortow();
    
    	while(1)
    	{
    		przycisk = SprawdzStanKlaw();
    		if(przycisk == PRAWO)
    		{
    			//wybrano przycisk PRAWO
    			//zapalamy kolejno diody od D1 do D20
    			for(licznik = 1;licznik < 21;licznik++)
    			{
    				if(licznik > 1) _delay_ms(Czas_zalaczania); //pierwsza dioda zalaczana bez opoznienia
    				SterujLed(licznik,ZALACZ);
    			}
    
    			//wszystkie diody zalaczone, czekamy czas opoznienia wylaczania
    			_delay_ms(Czas_zalacz_wylacz);
    
    			//wylaczamy kolejno diody
    			for(licznik = 20;licznik > 0;licznik--)
    			{
    				if(licznik < 20) _delay_ms(Czas_zalaczania);
    				SterujLed(licznik,WYLACZ);
    			}
    		}
    		else if(przycisk == LEWO)
    		{
    			//wybrano przycisk LEWO
    			//zapalamy kolejno diody od D20 do D1
    			for(licznik = 20;licznik > 0;licznik--)
    			{
    				if(licznik < 20) _delay_ms(Czas_zalaczania); //pierwsza dioda zalaczana bez opoznienia
    				SterujLed(licznik,ZALACZ);
    			}
    
    			//wszystkie diody zalaczone, czekamy czas opoznienia wylaczania
    			_delay_ms(Czas_zalacz_wylacz);
    
    			//wylaczamy kolejno diody
    			for(licznik = 1;licznik < 21;licznik++)
    			{
    				if(licznik > 1) _delay_ms(Czas_zalaczania);
    				SterujLed(licznik,WYLACZ);
    			}
    		}
    	}
    }
    


    Program pisałem w AVR Studio 4 + WinAVR. Procesor pracuje z wewnętrznym oscylatorem RC 1MHz. Czasy są takie, jakie życzył sobie Autor (400ms opóźnienia pomiędzy kolejnymi załączeniami/wyłączeniami diod, 3s pomiędzy cyklem załączania i wyłączania diod). W załączniku znajduje się kompletny projekt. Filmik przedstawia działanie programu na układzie testowym.





    Pozdrawiam, Przemo
  • #10 9068035
    matii_speed
    Poziom 16  
    Witam, jesteś wielki!! :) dziękuje bardzo za pomoc właśnie o takie coś chodziło:)
  • #11 9074726
    matii_speed
    Poziom 16  
    Witam,czy mogę zastosować taki tranzystor: BD135 bo takie posiadam wiem że są 1,5 A ale mi to nie przeszkadza prąd pobierany przez diody na kanał będzie ok 0,3 A, i chciał bym to zasilić z innym napięciem 12v.

    sterowanie diod 20 led- kod atmega16 przenieś na atmega8

    Będzie coś z tego? Proszę o wyrozumiałość dopiero się uczę.
  • #12 9074832
    LordBlick
    VIP Zasłużony dla elektroda
    Lepiej będzie zastosować BC337-16 z rezystorem 4,7kΩ na bazie. BD135 wymagałby mniejszej rezystancji, ze względu na mniejszą β, co może doprowadzić do przeciążenia wyjść µC. Sprawdzone w praktyce - właśnie w pracy skonstruowałem coś podobnego do sterowania 8 lampkami ostrzegawczymi (LED 4x1W szeregowo z rezystorem 6,8Ω ) z 12V (instalacja el. samochodu).
  • #13 9075306
    matii_speed
    Poziom 16  
    Tylko że chciałem zrobić z tego co mam na stanie u siebie.. Nie da się tego jakoś obejść?
  • #14 9075646
    Przemo1268
    Poziom 20  
    Możesz jeszcze połączyć te tranzystory które posiadasz w układ Darlingtona (klik)
  • #15 9075736
    matii_speed
    Poziom 16  
    Czyli 2x więcej tranzystorów?.. mam tylko 25 sztuk

    Light-I możesz podać jakiś link do tme o podobnych tranzystorach o których mówiłeś bo takich nie mają.
  • #16 9076016
    Przemo1268
    Poziom 20  
    Te które masz (BD135) stosujesz jako główne a jako sterujące (to te, których bazy łączysz z uC) możesz zastosować inne NPN o mniejszym prądzie (np. BC547)
  • #17 9076285
    matii_speed
    Poziom 16  
    To chyba i tak będę musiał kupić nowe.. I może najlepiej bezie kupić typu Darlingtona np TIP112 ?
  • #18 9076330
    Przemo1268
    Poziom 20  
    może taniej wyjdzie ULN2003 jak radził Light-I jeżeli pobór prądu ma być ok 300mA. Tutaj masz 7 tranzystorów czyli potrzebujesz 3 takie układy. Cenowo wyjdzie taniej niż 20 tip112. Dodatkowo będziesz miał łatwiejszy montaż i mniejszą płytkę drukowaną.
  • #19 9106910
    matii_speed
    Poziom 16  
    Mam problem z tym układem.. przez jakiś czas działa dobrze a później zaczyna wariować. Dzieje się tak jak podłącze Tranzystory.. próbowałem na tip112 i bdx33c chyba że robię jakiś błąd? podłączam tak jak na moim schemacie wyżej.
    mam też jeszcze ULN2004 ale nie miałem pewności jak to podłączyć.

    Ma znaczenie że pod diody podłączam 12V a procesor 5?
    Jak to zrobić żebym nie miał z tym problemu? diody biorą dokładnie 380mA

    I czy dało by rade trochę zmienić kod i zamiast diody D1 był by trzeci włącznik po którym włączeniu świeciły by wszystkie diody tak długo jak długo zwierał bym go do masy? wtedy układ sterował by 19 diodami.
    pozdrawiam
  • #20 9122372
    Przemo1268
    Poziom 20  
    Witam

    W załączniku przesyłam poprawioną wersję firmware. Zmieniłem sposób sterowania diod (załączane od D1 do D19, gaszone od D1 do D19), dodałem także obsługę trzeciego przycisku, załączającego wszystkie diody. Filmik przedstawia działanie programu w układzie testowym. Odnośnie błędów w działaniu układu, przyczyna leży po stronie zakłóceń. Układ po załączeniu wszystkich diod pobiera ponad 7A prądu, dlatego należy zadbać o prawidłowy sposób łączenia elementów oraz doprowadzenie masy do poszczególnych elementów. Szczegóły wysłałem na PW.

    
    /*	Czestotliwosc taktowania procesora 1 MHz (korzystamy z wewn. RC 1MHz)
     *	Procesor ATmega 8
     */
    #define F_CPU 1000000UL
    
    #include <avrio.h>
    #include <utildelay.h>
    
    #define Czas_zalaczania 400	//Czas oczekiwania na zapalenie/wylaczenie kolejnej diody
    #define Czas_zalacz_wylacz 3000 //Czas oczekiwania od momentu zalaczenia wszystkich diod do rozpoczecia cyklu kolejnego wylaczania
    
    typedef enum
    {
    	WYLACZ = 0,
    	ZALACZ = 1
    } StanDiody;
    
    typedef enum
    {
    	ZADEN = 0,
    	PRAWO = 1,
    	LEWO = 2,
    	WSZYSTKIE = 3
    } Klawisz;
    
    /* Klawisze sterujace na PD0, PD1, PD2
     * Klawisz "Prawo" (D1->D20)  - PD0
     * Klawisz "Lewo" (D1<-D20) - PD1
     * Klawisz "Załącz wszystkie" PD2
     * 
     * Diody:
     * D1 	PortD.3
     * D2 	PortD.4
     * D4 	PortB.6
     * D4 	PortB.7
     * D5 	PortD.5
     * D6 	PortD.6
     * D7 	PortD.7
     * D8 	PortB.0
     * D9	PortB.1
     * D10	PortB.2
     * D11	PortB.3
     * D12	PortB.4
     * D13	PortB.5
     * D14	PortC.0
     * D15	PortC.1
     * D16	PortC.2
     * D17	PortC.3
     * D18	PortC.4
     * D19	PortC.5
     */
    
    void InicjalizacjaPortow()
    {
    	//Piny klawiatury jako wejscia (piny D0 do D2)
    	DDRD &= ~0x07;
    	//Pull-up
    	PORTD |= 0x07;
    
    	//Piny diod jako wyjscia, stan niski (diody wylaczone)
    	DDRB |= 0xFF;
    	PORTB &= ~0xFF;
    
    	DDRC |= 0x3F;
    	PORTC &= ~0x3F;
    
    	DDRD |= 0xF8;
    	PORTD &= ~0xF8;
    }
    
    void SterujLed(int dioda, StanDiody stan)
    {
    	int *Port;
    	int Pin;
    
    	switch(dioda)
    	{
    		case 1:
    			Port = &PORTD;
    			Pin = 3;
    			break;
    		case 2:
    			Port = &PORTD;
    			Pin = 4;
    			break;
    		case 3:
    			Port = &PORTB;
    			Pin = 6;
    			break;
    		case 4:
    			Port = &PORTB;
    			Pin = 7;
    			break;
    		case 5:
    			Port = &PORTD;
    			Pin = 5;
    			break;
    		case 6:
    			Port = &PORTD;
    			Pin = 6;
    			break;
    		case 7:
    			Port = &PORTD;
    			Pin = 7;
    			break;
    		case 8:
    			Port = &PORTB;
    			Pin = 0;
    			break;
    		case 9:
    			Port = &PORTB;
    			Pin = 1;
    			break;
    		case 10:
    			Port = &PORTB;
    			Pin = 2;
    			break;
    		case 11:
    			Port = &PORTB;
    			Pin = 3;
    			break;
    		case 12:
    			Port = &PORTB;
    			Pin = 4;
    			break;
    		case 13:
    			Port = &PORTB;
    			Pin = 5;
    			break;
    		case 14:
    			Port = &PORTC;
    			Pin = 0;
    			break;
    		case 15:
    			Port = &PORTC;
    			Pin = 1;
    			break;
    		case 16:
    			Port = &PORTC;
    			Pin = 2;
    			break;
    		case 17:
    			Port = &PORTC;
    			Pin = 3;
    			break;
    		case 18:
    			Port = &PORTC;
    			Pin = 4;
    			break;
    		case 19:
    			Port = &PORTC;
    			Pin = 5;
    			break;
    		default:
    			return;
    	}
    
    	if(stan == ZALACZ) *Port |= (1 << Pin);
    	else if(stan == WYLACZ) *Port &= ~(1 << Pin);
    }
    
    Klawisz SprawdzStanKlaw()
    {
    	int Licznik;
    
    	//sprawdzamy stan przycisku "Prawo"
    	if((PIND & 0x01) == 0)
    	{
    		//stan niski - przycisk wcisniety
    		//testujemy stan przycisku w czasie 100ms
    		//w celu eliminacji wplywu zaklocen
    		for(Licznik = 0;Licznik < 10;Licznik++)
    		{
    			_delay_ms(10);
    			if((PIND & 0x01) > 0) return ZADEN; //stan niestabilny wychodzimy z funkcji
    		}
    		return PRAWO; //stan przycisku stabilny, klawisz "prawo"
    	}
    
    	//sprawdzamy stan przycisku "Lewo"
    	if((PIND & 0x02) == 0)
    	{
    		//stan niski - przycisk wcisniety
    		//testujemy stan przycisku w czasie 100ms
    		//w celu eliminacji wplywu zaklocen
    		for(Licznik = 0;Licznik < 10;Licznik++)
    		{
    			_delay_ms(10);
    			if((PIND & 0x02) > 0) return ZADEN; //stan niestabilny wychodzimy z funkcji
    		}
    		return LEWO; //stan przycisku stabilny, klawisz "lewo"
    	}
    
    	//sprawdzamy stan przycisku "Zalacz wszystkie"
    	if((PIND & 0x04) == 0)
    	{
    		//stan niski - przycisk wcisniety
    		//testujemy stan przycisku w czasie 100ms
    		//w celu eliminacji wplywu zaklocen
    		for(Licznik = 0;Licznik < 10;Licznik++)
    		{
    			_delay_ms(10);
    			if((PIND & 0x04) > 0) return ZADEN; //stan niestabilny wychodzimy z funkcji
    		}
    		return WSZYSTKIE; //stan przycisku stabilny, klawisz "zalacz wszystkie"
    	}
    
    	return ZADEN; //zaden z przyciskow nie zostal wybrany
    }
    
    int main()
    {
    	int licznik;
    	Klawisz przycisk;
    
    	InicjalizacjaPortow();
    
    	while(1)
    	{
    		przycisk = SprawdzStanKlaw();
    		if(przycisk == PRAWO)
    		{
    			//wybrano przycisk PRAWO
    			//zapalamy kolejno diody od D1 do D19
    			for(licznik = 1;licznik < 20;licznik++)
    			{
    				if(licznik > 1) _delay_ms(Czas_zalaczania); //pierwsza dioda zalaczana bez opoznienia
    				SterujLed(licznik,ZALACZ);
    			}
    
    			//wszystkie diody zalaczone, czekamy czas opoznienia wylaczania
    			_delay_ms(Czas_zalacz_wylacz);
    
    			//wylaczamy kolejno diody
    			for(licznik = 1;licznik < 20;licznik++)
    			{
    				if(licznik > 1) _delay_ms(Czas_zalaczania);
    				SterujLed(licznik,WYLACZ);
    			}
    		}
    		else if(przycisk == LEWO)
    		{
    			//wybrano przycisk LEWO
    			//zapalamy kolejno diody od D19 do D1
    			for(licznik = 19;licznik > 0;licznik--)
    			{
    				if(licznik < 19) _delay_ms(Czas_zalaczania); //pierwsza dioda zalaczana bez opoznienia
    				SterujLed(licznik,ZALACZ);
    			}
    
    			//wszystkie diody zalaczone, czekamy czas opoznienia wylaczania
    			_delay_ms(Czas_zalacz_wylacz);
    
    			//wylaczamy kolejno diody
    			for(licznik = 19;licznik > 0;licznik--)
    			{
    				if(licznik < 19) _delay_ms(Czas_zalaczania);
    				SterujLed(licznik,WYLACZ);
    			}
    		}
    		else if(przycisk == WSZYSTKIE)
    		{
    			//zalaczamy wszystkie diody bez opoznienia
    			for(licznik = 1;licznik < 20;licznik++)
    			{
    				SterujLed(licznik,ZALACZ);
    			}
    		}
    		else
    		{
    			//wylaczamy wszystkie diody bez opoznienia
    			for(licznik = 1;licznik < 20;licznik++)
    			{
    				SterujLed(licznik,WYLACZ);
    			}
    		}
    	}
    }
    






    Pozdrawiam, Przemo
  • #21 9122663
    Mariojas
    Poziom 17  
    Nie rozumiem dlaczego nie polecacie podłaczanie diod bezpośrednio pod atmege. W datasheet jest zapis, iż wyjścia można bezpośrednio obciążyć wyswietlaczami LED. Sam nigdy nie stosowałem żadnych buforów dla diod LED podłączonych do atmegi i układy działają spokojnie i bez zakłóceń.

    Kolego, dlaczego podłaczasz diody pod 12V? Jaki to ma sens dla Ciebie? Bo jeśli możesz to podłącz po prostu pod 5V, mniej strat uzyskasz (mniej napiecia odloży się na rezystorach). Dla 5V (także podlaczonych pod atmege) polecam rezystor 300 - 330 Ohm. Daje to optimum zasilania standardowej diody (super jasnej czy innych wynalazków).
    Oczywiście dla wszystkich diod właczonych naraz jest to szczyt obciążenia, ale wg założeń nie będzie to trwać długo (albo nie doczytałem), a jesli chodzi o pojedyncze wejście to spokojnie wytrzyma z duzym zapasem (40mA maksymalny prad).
    Oczywiście lepiej byłoby to zrobić na buforach, ale to znacznie uprości układ.
  • #22 9122695
    Przemo1268
    Poziom 20  
    W urządzeniu docelowym prąd pobierany przez diody na jeden kanał wynosi 380mA czyli po załączeniu wszystkich diod będzie to ponad 7A. Z tego powodu napięcie zasilania wynosi 12V, jest ono pobierane z mostka Graetza (brak stabilizacji).
    Cytat:

    Chrobek:
    Oczywiście dla wszystkich diod właczonych naraz jest to szczyt obciążenia, ale wg założeń nie będzie to trwać długo (albo nie doczytałem), a jesli chodzi o pojedyncze wejście to spokojnie wytrzyma z duzym zapasem (40mA maksymalny prad).


    nie doczytałeś dokładnie noty katalogowej:
    Cytat:

    The sum of all IOH, for all ports, should not exceed 300 mA


    Wartość tę bardzo łatwo przekroczyć. Jeżeli chcemy podłączyć 20 diod LED, każdą pod oddzielny pin, to przy prądzie 15mA sumaryczny pobór prądu samych diod wynosi 300mA.
  • #23 9134507
    matii_speed
    Poziom 16  
    Witam. Wielkie dzięki za pomoc. A czy normalne jest że gdy wcisnę i trzymam przycisk s3 zapalają się wszystkie i do tego wcisnę przycisk (razem z s3) np s1 lub s2 diody zaczynają się wygaszać? czy wystarczy zmienić coś w kodzie żeby w czasie włączenie jednej z tych 3 funkcji reszta była nie aktywna?
  • #25 9345652
    matii_speed
    Poziom 16  
    A dało by się zrobić tak, żeby każdy LED rozjaśniał się powoli i tak samo gasł?
    Pozdrawiam
  • #26 9347148
    xamrex
    Poziom 28  
    matii_speed
    Poczytaj o PWM
  • #27 9347852
    SylwekK
    Poziom 32  
    Co do płynnego rozjaśniania to może ten temat coś rozjaśni... ;)

    Wracając do programu realizacji kolejnego zapalania się diod to czy w tym przypadku nie było by prościej, czytelniej i szybciej zrobić to za pomocą wybierania danych dla portów z linii data...?
  • #28 9349147
    matii_speed
    Poziom 16  
    SylwekK - ja się nie znam na programowaniu aż tak, a nie pomógł byś mi tego kodu "przerobić", czy w ogóle się da, czy lepiej się opłaci zrobić nowy projekt?
  • #29 9349416
    SylwekK
    Poziom 32  
    Te projekciki z linka to w zasadzie szkielet pod do o co Ci chodzi. Używając tylko jednego (tam mam 8) programowanego pwm przemieszczasz go kolejno między portami (coś na wzór drugiego kodu). Niestety, tak po prostu skleić się tego nie da. Nie jest to jakieś bardzo trudne ale chwilowo brak mi czasu. Właśnie dziś opracowałem impulsowe sterowanie silnika nad którym siedziałem kilka dni. Ani to pwm hardware ani software ale działa idealnie i dokładnie tak jak sobie to założyłem w związku z tym muszę na wczoraj kończyć dalszą część mojego sterownika do wysięgnika, bo za dużo czasu na testach zmarnowałem...
    Jak się wyrobię z czasem, to może coś pomogę w temacie. W każdym, razie przeanalizuj programy i pokombinuj trochę - to najlepsza nauka.
  • #30 9582172
    matii_speed
    Poziom 16  
    Wgrałem program z załącznika i nie działa prawidłowo tzn. zwłoka miedzy załączonymi diodami a wygaszaniem wynosi 0s.
REKLAMA