W tym artykule pokażemy, jak napisać swój pierwszy, klasyczny program obsługujący diody LED oraz przyciski tact-switch.

Co potrzebujemy aby zacząć zabawę:

Jeśli wszystkie powyższe warunki zostały spełnione możemy przejść do tworzenia kodu źródłowego. W tym celu uruchamiamy środowisko Eclipse i tworzymy nowy projekt oraz plik źródłowy.

Oczywiście, musimy jeszcze podłączyć programator do płytki za pomocą przewodu ISP, wybrać go w ustawieniach projektu, oraz podłączyć odpowedni pin danego portu do diody. W naszym przypadku wybrano pin 7 portu C i diodę nr 7.

Nasz program, mrugający diodą LED, musi najpierw zapalić diodę na odpowiednim pinie, odczekać określony czas, a następnie zgasić diodę. Kod programu przedstawia się następująco:

/*
 * migajaca_dioda.c
 *
 *  Created on: 20 lip 2015
 *      Author: Gotronik_1
 */

#include <avr/io.h>
#include <util/delay.h>

int main(void){

	DDRC |= (1<<PC7); //włączenie pinu PC7 jako wyjście
	while(1){
		PORTC &= ~(1<<PC7);
		_delay_ms(1000);
		PORTC |= (1<<PC7);
		_delay_ms(1000);

}

Jeśli wszystkie kroki przeszliśmy pomyślnie, naszym oczom powinna ukazać się mrugająca dioda nr 7.

Warto przeanalizować kod źródłowy krok po kroku.

Lekka modyfikacja linii odpowiedzialnych za uruchomienie portu, i wystawianie na nim stanu wysokiego, pozwala na uruchomienie np. wszystkich pinów na raz:

/*
 * migajaca_dioda.c
 *
 *  Created on: 20 lip 2015
 *      Author: Gotronik_1
 */

#include <avr/io.h>
#include <util/delay.h>

int main(void){

	DDRC = 0xff;
		while(1){
			PORTC = ~255;
			_delay_ms(1000);
			PORTC = ~0;
			_delay_ms(1000);
				}

}

 


Ciekawym pomysłem jest również stworzenie szlaczka, odbijającego się od skrajnych diód. W tym celu musimy zapoznać się z tym, jak wysterowywane są piny w procesorze Atmega. Podłączmy 8 diód LED, tak aby ich numery na płytce, odpowiadały numerom pinów portu C. Pinom w porcie C odpowiadają wagi, tak, jak w ciągu zerojedynkowym. Tabela wag przedstawia się następująco:

PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0
128 64 32 16 8 4 2 1

Załóżmy że chcemy zapalić diody podpięte do pinów PC2 i PC3. W tym celu wystarczy zsumować ich wagi, i wystawić stan wysoki odpowiednim poleceniem.

Kod naszego szlaczka przedstawia się następująco:

/*
 * LED.c
 *
 *  Created on: 20 lip 2015
 *      Author: Gotronik_1
 */

#include <avr/io.h>
#include <util/delay.h>

int main (void){

	DDRC = 0xff;
	uint8_t i, diody[]={3, 6, 12, 24, 48, 96, 192, 96, 48, 24, 12, 6} ;
	while (1) {
		for(i=0; i<12; i++){
			_delay_ms(500);
			PORTC = ~diody[i];

		}
	}
}

Filmik przedstawiający działanie:

Jak widać, utworzyliśmy sobie tablicę z wartościami wag dla odpowiednich diód. Następnie za pomocą pętli for wywoływaliśmy kolejno elementy tablicy, co skutkowało zapalaniem się diód. Zmieniając wartość opóźnienia możemy regulować szybkość przebiegania szlaczka.

Obsługa przycisków tact-switch

Pójdźmy dalej z rozbudową naszego układu, i dodajmy obsługę przycisku tact-switch. W tym celu podłączmy przycisk pod port B ( w naszym przypadku podłączono przycisk 7 pod port PB7).

Do kodu wystarczy dodać linię, ustawiającą stan wysoki na wejściach portu B, są to tak zwane rezystory podciągające pull-up. Ma to zapobiec hazardowi logicznemu, czyli pojawianiu się stanów nieustalonych na porcie mikrokontrolera. Następnie, musimy w jakiś sposób obsłużyć wciśnięcie przycisku. W tym przypadku, można posłużyć się instrukcją warunkową if, w której przewidzimy zarówno przypadek wciśniętego, jak i nie wciśniętego przycisku.

Nasz kod przedstawia się następująco:

/*
 * przycisk.c
 *
 *  Created on: 21 lip 2015
 *      Author: Gotronik_1
 */

#include <avr/io.h>

int main(void){

	DDRC = 0xff; // ustawienie wyjśc sterujących diodami
	PORTB = 255; //włączenie rezystorów podciągających

	while(1){

			if (!(PINB & 128)) // warunek, jeżeli na porcie B i pin 7
				{
					PORTC = ~128; //jeśli przycisk wciśnięty, zapal diodę nr 7
				}

				else PORTC = 255; //jeśli przycisk nie wciśnięty, zgaś wszystkie diody

		}
	}

Jeśli wszystko przepisaliśmy poprawnie, po wciśnięciu przycisku nr 7, powinna zapalić się dioda nr 7.

A co w sytuacji, gdy chcemy obsłużyć więcej diód i więcej przycisków? Są dwa rozwiązania. Jednym z nich jest dopisanie dodatkowych warunków dla każdego przycisku. Drugim rozwiązaniem może być użycie instrukcji switch-case. Ja jednak, skorzystałem z pierwszej opcji.

Stosując ciąg instrukcji if..else jak można zobaczyć poniżej, tworzy się nam ładny tasiemiec. Ale przynajmniej jest skuteczny, bo wszystko działa prawidłowo. Oto kod źródłowy:

/*
 * przyciski.c
 *
 *  Created on: 21 lip 2015
 *      Author: Gotronik_1
 */

#include <avr/io.h>

int main(void){

	DDRC = 0xff; // ustawienie wyjśc sterujących diodami
	PORTB = 255; //włączenie rezystorów podciągających

	while(1){

		if (!(PINB & 128)) PORTC = ~128;
			if(!(PINB & 64)) PORTC = ~64;
				if (!(PINB & 32)) PORTC = ~32;
					if (!(PINB & 16)) PORTC = ~16;
						if (!(PINB & 8)) PORTC = ~8;
							if (!(PINB & 4)) PORTC = ~4;
								if (!(PINB & 2)) PORTC = ~2;
									if (!(PINB & 1)) PORTC = ~1;

			else PORTC = 255; //jeśli przycisk wciśnięty, zapal diodę nr 7

	}
}

W tym artykule to już wszystko. Dzięki za uwagę 🙂

Dodaj komentarz