Zakres laboratorium:
- Zapoznanie z płytką EDU
- Typy zmiennych dla mikrokontrolerów AVR
- Operacje bitowe
- Rejestry DDRx, PORTx, PINx – sterowanie portami
Zadania do wykonania:
- Zadanie 1.1
- Zadanie 2.1
- Zadanie 2.2
- Zadanie 4.1
1. Zapoznanie z płytką EDU (płytka EDU)

Do czego mogą służyć poszczególne elementy?
Dane techniczne mikrokontrolera ATmega32A:
- Rodzina: AVR
- Organizacja pamięci Flash: 32kb
- Pamięć EEPROM: 1024B
- Pamięć SRAM: 2048B
- Częstotliwość maksymalna: 16MHz
- Napięcie pracy: 2,7 – 5,5V
- Liczba wejść/wyjść: 32
- Liczba kanałów PWM: 4
- Liczba timerów 8-bit: 2
- Liczba timerów 16-bit: 1
- Obudowa: DIP40
Przykładowy wynik kompilacji:

Program – pamięć Flash
Data – pamięć SRAM (20% – minimalna wartość jaka powinna być dostępna)
Zadanie 1.1
- Utworzyć nowy projekt z plikami “GLOBAL.h” i “main.cpp” (szablony plików na stronie Środowisko programistyczne AVR). Podłączyć programator, skompilować i wgrać program do mikrokontrolera.
- Ile pamięci zajmuje ten program?
2. Typy zmiennych dla mikrokontrolerów AVR
Mikrokontrolery ATmega32 i ATmega328P są mikrokontrolerami 8-biotowymi (wszystkie rejestry mają pojemność 8 bitów). Oznacza to, że potrafią wykonywać proste operacje tylko na liczbach 8-biotowych, w celu wykonania operacji na większych liczbach mikrokontroler musi wykonać kilka instrukcji, co wpływa na wydajność programu. Dlatego też w pakiecie WinAVR można znaleźć specjalne typy zmiennych z dokładnym sprecyzowaniem rozmiaru zmiennej (stdint.h).
Typy zmiennych dla liczb dodatnich (bez znaku) i całkowitoliczbowych:
- uint8_t – 0 – 255
- uint16_t – 0 – 65535
- uint32_t – 0 – 4294967295
- uint64_t – 0 – 18446744073709551615
Zmienne z znakiem i całkowitoliczbowe:
- int8_t – -128 – 127
- int16_t – -32768 – 32767
- int32_t – -2147483648 – 2147483647
- int64_t – -9223372036854775808 – 9223372036854775807
Zmienne dla liczb zmiennopozycyjnych (liczba z przecinkiem) – typy zajmujące dużo pamięci:
- float
- double
Zmienne inne:
- char – zmienna 8 bitowa do przechowywania znaków
- bool – true/false – przechowuje wartość na pierwszej pozycji bajtu (0b00000001/0b00000000) ale i tak zajmuje 8 bitów.
Bity, bajty itd. – o co w tym chodzi???
uint8_t liczba= 209; uint8_t liczba= 0b11010001; uint8_t liczba= 0xD1;

int8_t liczba= -47; int8_t liczba= -0b11010001; int8_t liczba= -0xD1;

uint16_t liczba= 37585; uint16_t liczba= 0b1001001011010001; uint8_t liczba= 0x92D1;

Zadanie 2.1
- wyniki zapisywać na kartce w celu pokazania prowadzącemu
- przygotować i skompilować poniższy program
1 2 3 4 5 6 |
#include "GLOBAL.h" uint8_t zmienna[10]; int main() { zmienna[5]=5; } |
- ile pamięci zajmuje program przy rozmiarze tablicy 10?
- zmienić rozmiary tablicy na 100,1000,2000
- zanotować informacje o wykorzystanej ilości pamięci
- zmienić typ uin8_t na int i przeprowadzić takie same badania
Zadanie 2.2
- skompilować poniższy program:
1 2 3 4 5 6 7 8 |
#include "GLOBAL.h" volatile float zmienna; int main() { zmienna=5; zmienna+=4; } |
- ile pamięci zajmuje program, którzy wykorzystuje liczby zmiennoprzecinkowe
- zmienić typ liczby “zmienna” z float na uint8_t
- ile pamięci teraz zajmuje program, ile pamięci dodatkowo musi wykorzystać kompilator aby móc obsługiwać liczby zmiennoprzecinkowe?
Jakie wnioski można wysunąć? Przemyśleć i zaprezentować prowadzącemu wyniki i przedstawić wnioski.
3. Operacje bitowe
- Zaprzeczenie NOT: ~
- Iloczyn AND: &
- Suma OR: |
- Suma wyłaczająca XOR: ^
- Przesunięcie w prawo: >>
- Przesunięcie w lewo: <<
Zapoznać się z działaniem operacji: link1
W pliku “GLOBAL.h” znajdują się funkcje do operacji bitowych:
- sbi(rejestr,bit) – ustawia w rejestrze bit(pozycje) jako 1 – SET
- cbi(rejestr,bit) – ustawia w rejestrze bit(pozycje) jako 0 – CLEAR
- tbi(rejestr,bit) – ustawia w rejestrze bit(pozycje) na przeciwną wartość – TOGGLE
4. Rejestry DDRx, PORTx,PINx – sterowanie portami

Wyprowadzenia mikrokontrolera – sterowanie:
- Port A – PA0-PA7 – DDRA, PORTA, PINA
- Port B – PB0-PB7 – DDRB, PORTB, PINB
- Port C – PC0-PC7 – DDRC, PORTC, PINC
- Port D – PD0-PD7 – DDRD, PORTD, PIND
Rejestry – a o co chodzi?
Rejestr DDRx – rejestr kierunku:
- 0 – ustawia wyprowadzenie jako wejście
- 1 – ustawia wyprowadzenie jako wyjście
Rejestr PORTx – rejestr wyjściowy – gdy DDRx ==1:
- 0 – ustawia wyprowadzenie w stan niski
- 1 – ustawia wyprowadzenie w stan wysoki
Rejestr PORTx – rejestr wyjściowy – gdy DDRx ==0:
- 0 – nic nie robi (stan wysokiej impedancji)
- 1 – pull-UP – podciągnięcie wyprowadzenia do VCC przez rezystor 10k (zapobiega pojawianiu się nieokreślonych stanów na wyprowadzeniu)
Rejestr PINx – rejestr wejściowy – tylko do odczytu:
- 0 – oznacza stan niski na wyprowadzeniu
- 1 – oznacza stan wysoki na wyprowadzeniu
Podsumowując:
DDRx | PORTx | PINx* | |
Wyjście stan niski | 1 | 0 | |
Wyjście stan wysoki | 1 | 1 | |
Wejście wysoka impedancja | 0 | 0 | |
Wejście PULL-UP | 0 | 1 | |
Odczyt wejścia – stan wysoki | 0 | x | 1 |
Odczyt wejścia – stan niski | 0 | x | 0 |
*-tylko do odczytu
W celu ustawienia wyprowadzenie PD6 jako wyjście w stanie wysokim należy:
1 2 |
sbi(DDRD,PD6); //Ustawia wyprowadzenie PD6 do pracy jako wyjście sbi(PORTD,PD6); //Ustawia stan wysoki na wyprowadzeniu PD6 |
W celu ustawienia wyprowadzenie PD6 jako wyjście w stanie niskim należy:
1 2 |
sbi(DDRD,PD6); //Ustawia wyprowadzenie PD6 do pracy jako wyjście cbi(PORTD,PD6); //Ustawia stan niski na wyprowadzeniu PD6 |
Program realizujący miganie diodą:
1 2 3 4 5 6 7 8 9 10 11 |
int main() { sbi(DDRD, PD6); while (1) { sbi(PORTD, PD6); _delay_ms(500); cbi(PORTD, PD6); _delay_ms(500); } } |
Można też krócej:
1 2 3 4 5 6 7 8 |
int main() { sbi(DDRD, PD6); while (1) { tbi(PORTD, PD6); _delay_ms(500); } } |
Pierwsze kroki:
- podłączyć port D do linijki diodowej według schematu (jeśli zworki są w innym położeniu to należy je przepiąć):

- ustawić cały port D jak wyjścia – będzie służył do sterowania diodami. W celu uruchomienia diody należy ustawić stan niski na wyprowadzeniu mikrokontrolera.
Kilka sposobów:
- DDRD=0xFF;
- DDRD |= (1<<PD0) | … | (1<<PD7)
- sbi(DDRD, PD0) … sbi(DDRD, PD7)
Zadanie 4.1 – sterowanie wyprowadzeniami mikrokontrolera:
- włączyć wszystkie diody LED – jak można to zrobić, przetestować 3 sposoby
- napisać funkcję, która będzie mrugała wszystkimi diodami z częstotliwością 1s
- przygotować funkcje, która będzie realizowała zadanie “biegający punkt”. Jedna dioda na linijce diodowej jest włączona i porusza się w lewo lub w prawo – w zależności gdzie świecący punkt był wcześniej.
Zadanie domowe (wykonuje każda osoba samodzielnie):
- zapoznać się z tworzeniem schematów elektronicznych (Link2)
- narysować schemat elektroniczny na podstawie układu z zadania 4.1 (biegający punkt)
- schemat musi zawierać: mikrokontroler, podłączenie programatora, układ stabilizacji napięcia, diody LED z rezystorami
- schematy mogą być wykonane w programie komputerowym lub narysowane odręcznie,
- kompletne/prawidłowe schematy należy przynieść na kolejne zajęcia na kartce A4
Zadania na przyszłe laboratorium:
- Utrwalić wiadomości dotyczące obsługi portów (rejestr DDRx, PORTx, PINx – do czego służy, jak czytać?)
- Co to jest klawiatura matrycowa, jak obsługiwać? (klawiatura 4×4)
- Wyświetlacz LCD oparty o sterownik HD44780 – jak obsługiwać?
- Algorytm kalkulatora liczb całkowitych opartego o klawiaturę 4×4 (problem wczytywania liczb), wyświetlacz LCD (dodawanie, odejmowanie, mnożenie, wynik, anuluj)
* – http://apollo.astro.amu.edu.pl/PAD/index.php?n=Dybol.DydaktykaBinaria1