Zakres laboratorium:

  1. Zapoznanie z płytką EduTar
  2. Typy zmiennych dla mikrokontrolerów AVR
  3. Operacje bitowe
  4. Rejestry DDRx, PORTx, PINx – sterowanie portami
  5. Odczytywanie stanu pinu – obsługa przycisków, drgania styków

Przykładowy schemat z laboratorium wstępnego:

1. Zapoznanie z płytką EduTar

Strona płytki EduTar: link

Dane techniczne mikrokontrolera ATmega328P:

  • Rodzina: AVR
  • Organizacja pamięci Flash: 32kb
  • Pamięć EEPROM: 1024B
  • Pamięć SRAM: 2048B
  • Częstotliwość maksymalna: 20MHz
  • Napięcie pracy: 1,8 – 5,5V
  • Liczba wejść/wyjść: 23
  • Liczba kanałów PWM: 4
  • Obudowa: TQFP32

Moduł Arduino nano:

  • Atmega328P
  • programowanie/ komunikacja z komputerem: UART
  • częstotliwość taktowania przy wykorzystaniu zewnętrznego kwarcu: 16MHz
  • pinout zgodny z rysunkiem: link

 

2. Typy zmiennych dla mikrokontrolerów AVR

Mikrokontrolery AVR np. 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 lepiej jest korzystać z mniejszych zmiennych niż 32 bitowe, które zostały zdefiniowane w bibliotece (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 (4 bajty)
  • double (8 bajty, w Arduino 4 bajty)

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.

Zadanie 2.1

  • wyniki zapisywać na kartce w celu pokazania prowadzącemu
  • przygotować i skompilować poniższy program

  • 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 testy

Zadanie 2.2

  • skompilować poniższy program:

 

 

  • 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: <<

 

Bity, bajty itd. – o co w tym chodzi???

uint8_t liczba= 209;  uint8_t liczba= 0b11010001; uint8_t liczba= 0xD1;

bajt_01_small
Bajt interpretowany jako liczba bez znaku. Źródło*

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

bajt_02_small
Bajt o tej samej zawartości, teraz interpretowany jako liczba ze znakiem. Źródło*

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

dwa_bajty_01_small
Dwa bajty interpretowane jako liczba bez znaku. Źródło*

 

 

4. Rejestry DDRx, PORTx, PINx – sterowanie portami

Wyprowadzenia mikrokontrolera Atmega328P

Wyprowadzenia mikrokontrolera – sterowanie:

  • Port B – PB0-PB7 – DDRB, PORTB, PINB
  • Port C – PC0-PC6 – 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:

 

W celu ustawienia wyprowadzenie PD6 jako wyjście w stanie niskim należy:

 

Program realizujący miganie diodą:

Można też krócej:

 

 

Rejestry są zmiennymi do których można zapisywać wartość, więc są różne sposoby ich modyfikacji:

  1. DDRD=0xFF;
  2. DDRD |= (1<<PD0) | … | (1<<PD7)
  3. sbi(DDRD, PD0) … sbi(DDRD, PD7)

 

Sterowanie wyprowadzeniami mikrokontrolera jako wyjścia.

Zadanie 4.1

  • podłączyć diody:
    • LED1 do PD0, …………., LED8 do PD7
  • 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

Zadanie 4.2

  • podłączyć diody jak w poprzednim zadaniu
  • 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.
5. Odczytywanie stanu pinu – obsługa przycisków, drgania styków
Sterowanie wyprowadzeniami mikrokontrolera jako wejścia.

W pliku nagłówkowym <avr/sfr_defs.h> zdefiniowano makra “bit_is_set(reg,bit)” i “bit_is_clear(reg,bit)”

Zadanie 5.1

  • podłączyć diody jak w poprzednim zadaniu
  • podłączyć przewód do PB0
  • stworzyć funkcję: przyciśnięcie przycisku (przewód podłączony do GND) – wszystkie diody świecą się. Przycisk puszczony (przewód odłączone od GND) – wszystkie diody są wyłączone
  • jak działa program? czy jest jakiś problem? jak go rozwiązać?

Zadanie 5.2

  • podłączyć diody jak w poprzednim zadaniu
  • podłączyć przewód do PB1
  • napisać program przycisku bistabilnego – przyciśnięcie przycisku (przewód podłączony do GND i odłączony) – diody świecą. Drugi raz przyciśnięcie przycisku (przewód podłączony do GND i odłączony) – wszystkie diody są wyłączone
  • jak działa program? czy jest jakiś problem? jak go rozwiązać?

Zadanie 5.3

  • podłączyć diody jak w poprzednim zadaniu
  • podłączyć przycisk SW_1 do PB0
  • podłączyć przycisk SW_2 do PB1
  • zapoznać się jak elektronicznie są podłączone przyciski – narysować schemat podłączenia na kartce
  • napisać program przycisku monostabilnego – jeśli przycisk SW_1 wciśnięty to LED1 świeci. Jeśli przycisk SW_1 niewciśnięty to LED1 nie świeci
  • napisać program przycisku bistabilnego – jedno wciśnięcie przycisku SW_2 powoduje uruchomienie LED2-świeci, drugie wciśnięcie przycisku SW_2  powoduje wyłączenie LED2 – nie świeci
  • powyższe funkcje działają w jednym programie
  • jak działa program? czy jest jakiś problem? jak go rozwiązać?

Zadanie 6.1

  • podłączyć diody jak w poprzednim zadaniu
  • podłączyć przycisk SW_1 do PB0, …………, SW_4 do PB3
  • napisać program:
    • przyciskanie przycisku SW_2 powoduje zwiększania liczby świecących diod LED
    • przyciskanie przycisku SW_1 powoduje zmniejszanie liczby świecących diod LED
    • przyciśnięcie przycisku SW_3 powoduje wyłączenie wszystkich diod LED
    • przyciśnięcie przycisku SW_4 powoduje włączenie wszystkich diod LED
    • trzymanie wciśniętego przycisku nie powoduje zmiany