Zakres materiału:
- Typy zmiennych dla mikrokontrolerów AVR
- Operacje bitowe
- Rejestry DDRx, PORTx, PINx – sterowanie portami
- Sterowanie diodami LED – wyjścia
- Schematy elektroniczne
Zadania do wykonania:
- Zadanie 1.1
- Zadanie 1.2
- Zadanie 1.3
- Zadanie 1.4
1. Typy zmiennych dla mikrokontrolerów AVR
Mikrokontrolery rodziny AVR jak ATmega328P są mikrokontrolerami 8-bitowymi (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ż zaleca się tworzenie zmiennym ze szczególnym uwzględnieniem ich typów. Jawnie deklarować typy zmiennych z dokładnie sprecyzowaniem rozmiarem zmiennej, zakresem danych.
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 miejsca w pamięci:
- float
- double
Zmienne pozostałe:
- 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;
2. 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
3. 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 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?
Zadanie 2.1
- wyniki zapisywać na kartce w celu pokazania prowadzącemu
- przygotować i skompilować poniższy program
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <avr/io.h> #include <stdlib.h> #include <string.h> #include <util/delay.h> #ifndef _BV #define _BV(bit) (1<<(bit)) #endif #ifndef sbi #define sbi(reg,bit) reg |= (_BV(bit)) #endif #ifndef cbi #define cbi(reg,bit) reg &= ~(_BV(bit)) #endif int main() { while (1) { } } |
- 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.
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
Program migający diodą LED na całym porcie D
Czynności do wykonania:
-podłączyć diody LED:
LED1 do D0 (PD0)
LED2 do D1 (PD1)
LED3 do D2 (PD2)
LED4 do D3 (PD3)
LED5 do D4 (PD4)
LED6 do D5 (PD5)
LED7 do D6 (PD6)
LED8 do D7 (PD7)
przygotować funkcje, która za pomocą przesunięć bitowych 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