Technika mikroprocesorowa materiały do laboratorium. Autor: Dorota Rabczuk

Podobne dokumenty
Bootloader programming

ATMega328. Memories: Flash memory 32kB SRAM 2kB EEPROM 1kB

Poradnik programowania procesorów AVR na przykładzie ATMEGA8

Bootloader programming

SYSTEM PRZERWAŃ ATmega 32

Server setup. #include <SPI.h> #include <Ethernet.h> boolean incoming = 0;

Technika mikroprocesorowa materiały do laboratorium. Autor: Dorota Rabczuk

Podstawowe urządzenia peryferyjne mikrokontrolera ATmega8 Spis treści

Podstawowe urządzenia peryferyjne mikrokontrolera ATmega8 Spis treści

Mikroprocesory i Mikrosterowniki Liczniki Timer Counter T/C0, T/C1, T/C2

Programowanie mikrokontrolerów. 8 listopada 2007

Uwaga: dioda na wyjściu 13 świeci gdy na wyjście podamy 0.

Schemat blokowy architektury AVR

Wyświetlacz alfanumeryczny LCD zbudowany na sterowniku HD44780

Wbudowane układy peryferyjne cz. 3 Wykład 9

Niektóre piny mogą pełnić różne role, zależnie od aktualnej wartości sygnałów sterujących.

Mikrokontrolery AVR Wprowadzenie

Podstawowe urządzenia peryferyjne mikrokontrolera ATmega8 Spis treści

Uproszczony schemat blokowy zespołu 8-bitowego timera przedstawiono na rys.1

Programowanie Mikrokontrolerów

start Program mikroprocesorowego miernika mocy generowanej $crystal = deklaracja

PRZETWORNIK ADC w mikrokontrolerach Atmega16-32

Wbudowane układy peryferyjne cz. 2 Wykład 8

Instytut Teleinformatyki

Komunikacja w mikrokontrolerach Laboratorium

Uproszczony schemat blokowy konwertera analogowo-cyfrowego przedstawiony został na rys.1.

Przetworniki analogowo-cyfrowe (A/C)

Programowanie mikrokontrolerów AVR z rodziny ATmega.

2. Architektura mikrokontrolerów PIC16F8x... 13

LABORATORIUM. TIMERY w mikrokontrolerach Atmega16-32

Magistrala SPI. Linie MOSI i MISO sąwspólne dla wszystkich urządzeńna magistrali, linia SS jest prowadzona do każdego Slave oddzielnie.

Szkolenia specjalistyczne

Listing_ $crystal = deklaracja

Programowanie mikrokontrolerów AVR

LABORATORIUM. TIMERY w mikrokontrolerach Atmega16-32

Instytut Teleinformatyki

Programowanie mikrokontrolerów. 5 grudnia 2007

Programowanie mikrokontrolerów AVR z rodziny ATmega.

Systemy wbudowane. Uniwersytet Łódzki Wydział Fizyki i Informatyki Stosowanej. Witold Kozłowski

GND(VSS) i VCC - masa i zasilanie. V0 - regulacja kontrastu

Politechnika Poznańska Wydział Budowy Maszyn i Zarządzania. Sterowniki Urządzeń Mechatronicznych laboratorium. Ćw. 3: Timer v1.0

Instytut Teleinformatyki

Opis procedur asemblera AVR

KOMUNIKACJA Z OTOCZENIEM MIKROKONTROLERA

Instytut Teleinformatyki

Układy czasowo-licznikowe w systemach mikroprocesorowych

Komunikacja w mikrokontrolerach Laboratorium

4 Transmisja szeregowa na przykładzie komunikacji dwukierunkowej z komputerem PC, obsługa wyświetlacza LCD.

o Instalacja środowiska programistycznego (18) o Blink (18) o Zasilanie (21) o Złącza zasilania (22) o Wejścia analogowe (22) o Złącza cyfrowe (22)

Arduino dla początkujących. Kolejny krok Autor: Simon Monk. Spis treści

Przetwornik analogowo-cyfrowy

LOW ENERGY TIMER, BURTC

Mikrokontroler ATmega32. System przerwań Porty wejścia-wyjścia Układy czasowo-licznikowe

Systemy Wbudowane. Arduino C. Arduino C - stałe. Arduino C - Stałe. Arduino C - Stałe. Funkcje matematyczne. Arduino C - Stałe

Technika Mikroprocesorowa

Wprowadzenie do podstaw programowania AVR (na przykładzie mikrokontrolera ATmega 16 / 32)

3.2. Zegar/kalendarz z pamięcią statyczną RAM 256 x 8

Komunikacja w mikrokontrolerach. Wydział Elektroniki Mikrosystemów i Fotoniki Piotr Markowski

Język C. Wykład 9: Mikrokontrolery cz.2. Łukasz Gaweł Chemia C pokój 307

1.2 Schemat blokowy oraz opis sygnałów wejściowych i wyjściowych

Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR

4 Transmisja szeregowa, obsługa wyświetlacza LCD.

Expandery wejść MCP23S17 oraz MCP23017

Technika mikroprocesorowa laboratorium. dr inż. Dorota Rabczuk

Struktura i działanie jednostki centralnej

Przerwanie. Źródła przerwań

Zespół Szkół Technicznych. Badanie wyświetlaczy LCD

Inż. Kamil Kujawski Inż. Krzysztof Krefta. Wykład w ramach zajęć Akademia ETI

PROGRAMOWALNE SYSTEMY MECHATRONIKI

1. Tworzenie nowego projektu.

Programowanie w językach asemblera i C

Systemy wbudowane. Uniwersytet Łódzki Wydział Fizyki i Informatyki Stosowanej. Witold Kozłowski

Instrukcja do ćwiczeń

Mikrokontroler AVR ATmega32 - wykład 9

Laboratorium Systemów wbudowanych Wyższa Szkoła Zarządzania i Bankowości, Informatyka studia inżynierskie

Systemy Wbudowane. Arduino, AVR. Arduino. Arduino. Arduino. Oprogramowanie. Mikrokontroler. Mikrokontroler Platforma Arduino. Arduino IDE: Arduino C:

Server setup. #include <SPI.h> #include <Ethernet.h> boolean incoming = 0;

Obsługa przetwornika ADC na mikrokontrolerze ATmega8 CEZARY KLIMASZ OBSŁUGA PRZETWORNIKA ADC NA MIKROKONTROLERZE ATMEGA8

Mikroprocesory i Mikrosterowniki Laboratorium

Wstęp Architektura... 13

Systemy wbudowane. Uniwersytet Łódzki Wydział Fizyki i Informatyki Stosowanej. Witold Kozłowski

Mikroprocesory i Mikrosterowniki

Wbudowane układy peryferyjne cz. 1 Wykład 7

Metody obsługi zdarzeń

XMEGA. Warsztaty CHIP Rok akademicki 2014/2015

Kurs Zaawansowany S7. Spis treści. Dzień 1

Uczeń/Uczennica po zestawieniu połączeń zgłasza nauczycielowi gotowość do sprawdzenia układu i wszystkich połączeń.

/* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include <aduc834.h>

Technika Mikroprocesorowa Laboratorium 5 Obsługa klawiatury

Charakterystyka mikrokontrolerów. Przygotowali: Łukasz Glapiński, Mateusz Kocur, Adam Kokot,

1. Wprowadzenie Programowanie mikrokontrolerów Sprzęt i oprogramowanie... 33

Organizacja pamięci VRAM monitora znakowego. 1. Tryb pracy automatycznej

Uniwersalny asynchroniczny. UART Universal Asynchronous Receier- Transmiter

Ćwiczenie 7 Matryca RGB

Spis treœci. Co to jest mikrokontroler? Kody i liczby stosowane w systemach komputerowych. Podstawowe elementy logiczne

Układy czasowo-licznikowe w systemach mikroprocesorowych

Mikroprocesory i Mikrosterowniki Analog-Digital Converter Konwerter Analogowo-Cyfrowy

Akademia Górniczo-Hutnicza w Krakowie Katedra Elektroniki

2.1 Porównanie procesorów

Gdzie przyjęto, że: IR7...IR4 to starsze bity przesyłanej danej lub rozkazu, IR3...IR0 to młodsze bity przesyłanej danej lub rozkazu.

Transkrypt:

Technika mikroprocesorowa materiały do laboratorium Autor: Dorota Rabczuk

Architektura mikrokontrolera AT90S8515 1. Jednostka arytmetyczno-logiczna ALU posiada dostęp do 32-ch rejestrów 8-bitowych, na których wykonuje obliczenia. 2. Pamięć programu Flash 8 kbajtów, licznik instrukcji, dekoder instrukcji. 3. Pamięć ulotna danych RAM 512 bajtów. 4. Pamięć nieulotna danych EEPROM 512 bajtów. 5. Urządzenia peryferyjne: liczniki/timery 8-bitowe i 16-bitowe, Timer z trybem PWM, Timer watchdog, moduł przerwań zewnętrznych, interfejsy: SPI i UART, komparator analogowy

Architektura mikrokontrolera AT90S8515

Wyprowadzenia mikrokontrolera AT90S8515

Pamięci wewnętrzne mikrokontrolera 1. Pamięć programu Flash programowalna elektrycznie równolegle lub szeregowo. Programowanie szeregowe może się odbywać w układzie przez interfejsy: SPI lub JTAG lub UART (RS-232) ten ostatni sposób wymaga wcześniejszego wgrania programu ładującego tzn. bootloader a 2. Pamięć danych RAM (SRAM) o dostępie nanosekundowym, ulotna, tryby adresowania: bezpośredni i wskaźnikowy. 3. Pamięć danych EEPROM o dostępie milisekundowym, nieulotna.

Zapis liczb Zapis liczb: 0b11011100 zapis binarny 0xdc lub $dc zapis szesnastkowy 220 zapis dziesiętny 0b11011100 = 0xdc = $dc = 220 Makro _BV(x) jest liczbą, która ma jedną binarną 1 na pozycji x _BV(6) = 0b01000000 = 0x40 = 64

Suma i iloczyn binarny Suma binarna Suma binarna jest wykonywana bit z bitem. Operacja ta służy do ustawienia w wyjściowym rejestrze wybranych bitów pozostawiając pozostałe bez zmian. 0b???????? 0b10101010 = 0b1?1?1?1? Bity nieparzyste tj. 1,3,5 i 7 zostają ustawione, natomiast bity parzyste tj. 6,4,2,0 nie ulegną zmianie. Iloczyn binarny & Iloczyn binarny jest wykonywany bit z bitem. Operacja ta służy do wyzerowania w wyjściowym rejestrze wybranych bitów pozostawiając pozostałe bez zmian. 0b???????? & 0b10101010 = 0b?0?0?0?0 Bity nieparzyste tj. 1,3,5 i 7pozostaja bez zmian, natomiast bity parzyste tj. 6,4,2,0ulegają wyzerowaniu.

Przesunięcie binarne Przesunięcie binarne w lewo << Operacja (1<<0) powoduje utworzenie liczby 0b00000001 (1<<0) = 0x01 Operacja (1<<4) powoduje przesunięcie binarnej 1 o 4 pozycje w lewo i utworzenie liczby (1<<4) = 0b00010000 Liczba (1<<4) (1<<0) = 0b00010001 ma 2-ie jedynki binarne Przesunięcie binarne w prawo >> Operacja (a>>8) powoduje przesunięcie wszystkich bitów liczby o 8 pozycji w prawo i jest przydatna do wykonywania operacji na młodszym i starszym bajcie liczby 16-sto bitowej w 8-mio bitowych mikrokontrolerach char b, c; //liczby 8-mio bitowe int a=0x3456; //liczba 16-sto bitowa b = a; //młodszy bajt liczby a tj. b=0x56; c = (a>>8); //starszy bajt liczby a tj. b=0x34;

Przesunięcie binarne Przesunięcie binarne w lewo << jest równoznaczne z pomnożeniem przez 2 B =A << 1; //B=A*2 C =A << 2; //C=A*4 Przesunięcie binarne w prawo >> jest równoznaczne z podzieleniem przez 2 B =A >> 1; //B = A/2 C= A >> 3; //C = A/8

Negacja binarna Operacja ~(1<<0) powoduje zanegowanie wszystkich bitów w liczbie 0b00000001 i tym samym utworzenie liczby 0b11111110 ~(1<<0) = 0xFE Operacja ~(1<<4) powoduje zanegowanie wszystkich bitów liczby (1<<4) ~(1<<4) = 0b11101111 Liczba (1<<4) (1<<0) = 0b00010001 ma 2-ie jedynki binarne Liczba ~((1<<4) (1<<0) ) = 0b11101110 ma 2 binarne zera ~(_BV(6)) = ~(0b01000000) = 0b10111111 = 0xBF = 191

Operacje binarne - przykłady Po zdefiniowaniu # define bit5 5 Operacja A = (1<<bit5) spowoduje ustawienie bitu 5 w zmiennej A Operacja A & = ~(1<<bit5) spowoduje wyzerowanie bitu 5 zmiennej A Operacja A &= (1<<bit5) spowoduje wyzerowanie wszystkich bitów za wyjątkiem bitu 5 i ma sens selekcji bitu 5 zmiennej A. Aby się dowiedzieć, czy bit 5 jest wyzerowany dokonuję selekcji i porównania. if (A & (1<<bit5) ) = = 0) ; //jest wyzerowany else ; //nie jest wyzerowany

Operacje logiczne Suma logiczna Jeśli którakolwiek z liczb jest różna od zera, to wynik jest prawdą Iloczyn logiczny && Jeśli obie liczby są niezerowe, to wynik iloczynu jest prawdą Negacja logiczna! Zaprzeczeniem 1 jest 0

Pętle for for ( i=1; i<11; i++) { Rozkaz; } switch (zmienna) { case 1: //gdy zmienna = 1 rozkaz; break; case 2: //gdy zmienna = 2 rozkaz; break; } Wykorzystywana np. do rozróżniania naciśniętych klawiszy

Pętla while while Pętla while jest często wykorzystywana w programie głównym, jeśli potrzebne jest ciągłe wykonywanie procedur wątku głównego do { ;rozkazy } while (1); //wykonuj zawsze Pętla while jest też wykorzystywana do oczekiwania na ustawienie lub wyzerowanie bitu. Np. dopóki nie ustawi się bit 5 w rejestrze A czekaj while(! (A & (1<<bit5))); W pętli tej nie umieszczono żadnych rozkazów, co oznacza, że program stoi oczekując na spełnienie warunku

Projekt w środowisku AVR Studio Każdy projekt należy założyć w oddzielnym katalogu. Projekt zawiera następujące pliki:.c pliki z kodem źródłowym napisanym w języku C.h opcjonalnie pliki nagłówkowe z deklaracjami, definicjami i wybranymi procedurami kodu źródłowego.aps zawiera informacje o tym, które pliki należą do projektu i będą podlegały kompilacji.aws przechowuje informacje bieżące o ostatnio używanej przestrzeni roboczej (nieistotny dla projektu) Makefile Plik Makefile w katalogu default zawiera reguły kompilacji czyli przekształcania wyrażeń z języka wysokiego poziomu (tu: C) na wyrażenia niskopoziomowe.eep,.elf.,.hex,.o pliki wyjściowe w katalogu default powstałe podczas kompilacji. Plik.hex w formacie Intel Hex należy wgrać do pamięci Flash mikrokontrolera AVR

Podstawowe opcje kompilacji Podstawowe opcje kompilacji należy ustawić na zakładce Project Configuration Options: Typ procesora, dla którego jest wykonywana kompilacja Częstotliwość zegara procesora (tu: kwarcu) Poziom optymalizacji Należy zaznaczyć pole Create Hex File Uwaga!! Jeśli pętla programu nie obiega prawidłowo (może się to zdarzyć zarówno w czasie symulacji środowiskowych, jak i po uruchomieniu programu w mikrokontrolerze), wówczas należy zmniejszyć poziom optymalizacji do O0.

Struktura programu Na początku programu należy wczytać potrzebne pliki nagłówkowe z funkcjami bibiotecznymi. #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> //biblioteka procesora //biblioteka przerwań //procedury z opóźnieniem czasowym Następnie umieszcza się definicje potrzebnych procedur/funkcji dodatkowych (w tym procedur przerwań), a na samym dole procedurę główna (main) Nazwy procedur dodatkowych mogą być dowolne, natomiast nazwy procedur przerwań są zarejestrowane i można je znaleźć w pliku procesora. Przykładowy program main wywołuje procedurę funkcja i odbiera wynik na zmienną t. Procedur przerwań nie wywołuje się programowo, procedury te są wykonywane samoczynnie, jeśli zajdą określone warunki sprzętowe lub programowe pod warunkiem wcześniejszego zdjęcia maski danego przerwania. Biblioteka delay.h zawiera funkcje: _delay_us (x);_delay_ms (x);

Kolejność procedur Jeśli w programie umieścimy (oprócz definicji) również deklaracje procedur, to kolejność procedur jest nieistotna i wszystkie procedury widzą się wzajemnie. Deklaracja przykładowej procedury (funkcji): char funkcja (int); W prostym programie można pominąć deklaracje procedur, jednak należy wówczas zadbać o takie uporządkowanie procedur, aby procedura (funkcja) umieszczona niżej odwoływała się wyłącznie do procedur umieszczonych nad nią. W takim układzie procedura main musi być ostatnia.

Struktura prostego programu bez deklaracji funkcji char funkcja (int m) { char k; k=m+1; return k; } ISR (INT0_vect ) { _delay_us (50); _delay_ms (10); } //definicja funkcji //definicja procedury przerwania int main (void) { char t; t= funkcja (20); //wywołanie funkcji return 0: }

Struktura programu z deklaracjami funkcji char funkcja (int); ISR (INT0_vect ) { _delay_us (50); _delay_ms (10); } //deklaracja funkcji //definicja procedury przerwania int main (void) { char t; t= funkcja (20); //wywołanie funkcji return 0: } char funkcja (int m) { char k; k=m+1; return k; } //definicja funkcji

Plik nagłówkowy Deklaracje procedur, deklaracje zmiennych oraz definicje wybranych procedur można przenieść do samodzielnie utworzonego pliku nagłówkowego z rozszerzeniem.h. Pliki nagłówkowe przeważnie tworzy się tematycznie np. dla umieszczenia wszystkich procedur związanych z wyświetlaczem LCD. Przykład wczytania pliku nagłówkowego #include <pliklcd.h>

Porty input/output Mikrokontroler AT90S8515 posiada 4 uniwersalne porty dwukierunkowe (Input/Output): A, B, C, D, z których każdy ma 8 linii z możliwością podwieszenia każdej linii przez rezystor do zasilania. Każdy z portów jest obsługiwany przez 3 rejestry: Rejestr kierunkowy DDR (A, B, C lub D) Rejestr wyjściowy PORT (A, B, C lub D) Rejestr wejściowy PIN (A, B, C lub D) Mikrokontroler ATMega128 posiada 6 uniwersalnych portów (Input/Output): A, B, C, D, E i F.

Linie portów (na przykładzie portu D) Rejestr kierunkowy portu D - DDRD Bit 7 6 5 4 3 2 1 0 Nazwa DDD7 DDD6 DDD5 DDD4 DDD3 DDD2 DDD1 DDD0 Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 Rejestr danych portu D - PORTD Bit 7 6 5 4 3 2 1 0 Nazwa PORTD7 PORTD6 PORTD5 PORTD4 PORTD3 PORTD2 PORTD1 PORTD0 Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 Rejestr wejściowy portu D - PIND Bit 7 6 5 4 3 2 1 0 Nazwa PIND7 PIND6 PIND5 PIND4 PIND3 PIND2 PIND1 PIND0 Odczyt/zapis R R R R R R R R Wartość początkowa N/A N/A N/A N/A N/A N/A N/A N/A N/A wartość nieustalona

Konfiguracja linii portów Konfiguracja rejestru kierunkowego DDR (A, B, C lub D): 1 linia staje się wyjściem 0 linia staje się wejściem Gdy linia jest wyjściem, to rejestr PORT (A, B, C lub D) ustawia: 1 wyjście w stanie wysokim 0 wyjście w stanie niskim Gdy linia jest wejściem, to rejestr PORT (A, B, C lub D) ustawia: 1 podwieszenie wejścia pod zasilanie 0 wejście w stanie wysokiej impedancji Gdy linia jest wejściem, to rejestr PIN (A, B, C lub D) służy do odczytu stanu linii (czy zwarta od zewnątrz).

Konfiguracja linii portów -wyjście Linia 2 portu B jako wyjście (przykładowe sposoby zapisu): DDRB = DDRB 0b00000100; lub DDRB = DDRB 0x04; lub DDRB = DDRB _BV(2); lub DDRB = _BV(2); gdzie makro _BV(x) jest liczbą, która ma jedną 1 binarną jedynkę na pozycji x np. _BV(2) = 0b00000100

Konfiguracja linii portów -wejście Linia 2 portu B jako wejście (przykładowe sposoby zapisu): DDRB = DDRB & 0b11111011; lub DDRB = DDRB & 0xFB; lub DDRB = DDRB & ~_BV(2); lub DDRB & = ~_BV(2); gdzie makro ~_BV(x) jest liczbą, która ma jedną 1 binarne zero na pozycji x np. ~_BV(2) = 0b11111011

Konfiguracja linii portów przykład 1 (założenia) Na linii 0 portu D umieszczono przycisk. Na linii 0 portu B umieszczono diodę. Należy sprawdzać w sposób ciągły stan przycisku i odzwierciedlać zapalaniem/gaszeniem diody. Elementy programu: - pętla wykonywana zawsze do {;} while(1); - selekcja linii 0 za pomocą iloczynu binarnego: PIND & 0x01 jest warunkiem wykonania rozkazu

Konfiguracja linii portów przykład 1 int main(void) { DDRD &= ~_BV(0); PORTD = _BV(0); DDRB = _BV(0); PORTB =_BV(0); //linia 0 portu D jako wejście //podwieszenie wejścia // linia 0 portu B jako wyjście //wyjście w stanie high do { } while(1); return 0; } if (PIND & 0x01) PORTB &= ~_BV(0); else PORTB =_BV(0); //sprawdź stan na linii 0 portu D //wyjście w stanie low //wyjście w stanie high

Konfiguracja linii portów przykład 2 Na linii 0 portu D umieszczono przycisk. Na linii 0 portu B umieszczono diodę. Należy sprawdzać w sposób ciągły stan przycisku i jego zwarcie zasygnalizować trwałym świeceniem diody. Elementy programu: - selekcja linii 0 za pomocą iloczynu binarnego: PIND & 0x01 - wyliczenie iloczynu logicznego (PIND & 0x01), który jest warunkiem wykonania rozkazu - wykorzystanie pętli while o logice: dopóki nie zwarto przycisku czekaj while (! (PIND & 0x01) );

Konfiguracja linii portów przykład 2 (założenia) int main(void) { DDRD &= ~_BV(0); PORTD = _BV(0); DDRB = _BV(0); PORTB =_BV(0); //linia 0 portu D jako wejście //podwieszenie wejścia // linia 0 portu B jako wyjście //wyjście w stanie high while (PIND & 0x01); PORTB &= ~_BV(0); return 0; } //dopóki nie zwarto przycisku stój //wyjście w stanie low

Porty przykład 3 Założenia: Wykorzystując pętlę do{;} while(1); mrugaj diodą 4 na porcie B Szkic programu: int main(void) { //konfiguracja linii diody do { //zapal diodę //czekaj 500ms //zgaś diodę //czekaj 500ms } while(1); }

Porty przykład 4 Założenia: Wykorzystując pętlę for (i=0;.) o 8 obejściach i operację obrotu zmiennej (char a) w lewo zrób linijkę, w której (po każdym obejściu pętli for) przybywa 1 światełko. Po 8-mym obejściu pętli palą się wszystkie diody, ponieważ zmienna obracana w lewo jest z prawej uzupełniana zerami. Szkic programu: Int main(void) { char i, A=0xff;; //konfiguracja linii 8-miu diod PORTB = A; for (i=0; ) { } return 0; } //zgaszenie wszystkich diod //czekaj 500ms //obróć zmienną A o 1 pozycję w lewo //wystaw liczbę A na PORTB

Porty przykład 5 Założenia: Wykorzystując pętlę for (i=0;.) o 8 obejściach zrób linijkę z jednym zapalonym, przemieszczającym sięświatełkiem. W tym celu wykorzystaj zmienną i oraz makro _BV(x). Szkic programu: Int main(void) { char i; //konfiguracja linii 8-miu diod for (i=0; ) { //czekaj 500ms PORTB =.. } return 0; } Zmodyfikuj działający program tak, aby zapalone światełko chodziło bez końca.

Wektory przerwań W najniższej części pamięci Flash są lokowane wektory przerwań (wątków bocznych). Są to adresy procedur wykonywanych pod warunkiem zaistnienia określonego zdarzenia (wewnętrznego lub zewnętrznego). Zaistnienie zdarzenia jest sygnalizowane ustawieniem binarnej flagi przerwania. Warunkiem wykonania procedury przerwania jest zdjęcie (w wątku głównym) maski przerwania. Wektory są ustawione w hierarchii pierwszeństwa im niższy adres, tym wyższa hierarchia. Najwyżej w hierarchii stoi wektor Reset, który ma adres 0.

Wektory przerwań procesora AT90S8515 Adres przerwania symbol przerwania Źródło przerwania $000 RESET Spadek napięcia zasilania, impuls ujemny na linii RESET, układ watchdog $001 INT0 Przerwanie zewnętrzne 0 $002 INT1 Przerwanie zewnętrzne 1 $003 Timer1 CAPT Timer 1 w trybie przechwytu $004 Timer1 COMPA Timer 1 w trybie porównawczym z rejestrem A $005 Timer1 COMPB Timer 1 w trybie porównawczym z rejestrem B $006 Timer1 OVF Timer 1 w trybie przepełnienia $007 Timer0 OVF Timer 0 w trybie przepełnienia $008 SPI, STC ukończenie transmisji szeregowej SPI $009 UART, RX zakończenie odbioru UART $00A UART, UDRE pusty rejestr danych UART $00B UART, TX zakończenie nadawania UART $00C ANA_KOMP komparator analogowy

Przerwania zewnętrzne INT0, INT1 AT90S8515 Przerwania zewnętrzne INT0 i INT1 są wywoływane przez stan niski, zbocze narastające lub zbocze opadające na określonych liniach zewnętrznych mikrokontrolera. W mikrokontrolerze AT90S8515 przerwanie INT0 reaguje na stany na linii 2 portu D, a przerwanie INT1 na linii 3 portu D. Przerwania zewnętrzne INT0 i INT1 wywoływane poziomem niskim nie posiadają flag. W związku z tym, przerwania te są wywoływane tylko w czasie rzeczywistym. Bity konfigurujące źródło przerwania INT0 oraz INT1 znajdują się w rejestrze kontrolnym MCUCR.

Przerwania zewnętrzne wybór źródła przerwania Rejestr kontrolny - MCUCR Bit 7 6 5 4 3 2 1 0 Nazwa SRE SRW SE SM ISC11 ISC10 ISC01 ISC00 Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 ISC01 ISC00 Źródło przerwania 0 0 Poziom niski na linii INT0 0 1 Zarezerwowane 1 0 Zbocze opadające na linii INT0 1 1 Zbocze narastające na linii INT0 ISC11 ISC10 Źródło przerwania 0 0 Poziom niski na linii INT1 0 1 Zarezerwowane 1 0 Zbocze opadające na linii INT1 1 1 Zbocze narastające na linii INT1

Maska i flaga przerwania zewnętrznego Rejestr masek przerwań - GIMSK Bit 7 6 5 4 3 2 1 0 Nazwa INT1 INT0 - - - - - - Odczyt/zapis R/W R/W R R R R R R Wartość początkowa 0 0 0 0 0 0 0 0 Rejestr flag przerwań - GIFR Bit 7 6 5 4 3 2 1 0 Nazwa INTF1 INTF0 - - - - - - Odczyt/zapis R/W R/W R R R R R R Wartość początkowa 0 0 0 0 0 0 0 0

Przerwania zewnętrzne założenia przykładu W programie głównym skonfigurowano linię 2 portu D, na której umieszczono przycisk oraz linię 2 portu B, an której umieszczono diodę. W rejestrze MCUCR wybrano źródło przerwania: poziom niski na linii przycisku. Zdjęto maskę przerwania i włączono przerwania, tym samym moduł przerwań podjął ciągłą obserwację linii INT0 (2-ga linia portu D). Gdy linia jest rozwarta wykonywana jest pętla główna programu, w której dioda jest gaszona. Gdy linia zostanie zwarta program wykonuje procedurę przerwania ISR (INT0_vect), w której umieszczono rozkaz zapalenia diody. Nazwa procedury przerwania jest zarejestrowania i można ją znaleźć w pliku z danymi procesora.

Przerwania zewnętrzne przykład ISR (INT0_vect) //procedura przerwania INT0 { PORTB &= ~_BV(2); //zapalenie diody 2 } int main(void) //procedura główna { DDRD &= ~_BV(2); //linia 2 portu D jako wejście PORTD = _BV(2); //podwieszenie wejścia DDRB = _BV(2); // linia 2 portu B jako wyjście PORTB =_BV(2); //wyjście high MCUCR = 0x00; //przerwanie poziomem niskim GIMSK = 0x40; //zdjęcie maski INT0 sei(); // Odblokowanie przerwań do {PORTB = _BV(2); } //zgaszenie diody 2 while (1); }

Przerwania zewnętrzne polecenia 1. Wzorując się na przykładzie przygotuj projekt, w którym aktywne będą 2 przerwania zewnętrzne INT0 oraz INT1 (sprawdzające 2-gą i 3-cią linię portu D). W odpowiedzi na naciśnięcie przycisków należy zapalać odpowiednio 2-gą i 3-cią diodę na porcie B. 2. Zwróć uwagę, że w przykładzie na poprzedniej stronie na wszystkie 8 bitów rejestru MCUCR wpisywane są stany 0 rozkazem MCUCR = 0x00. Zmień rozkaz tak, zerowane były tylko 4 młodsze bity odpowiedzialne za konfigurację przerwań zewnętrznych, natomiast 4 starsze odpowiedzialne za aktywację zewnętrznej przestrzeni adresowej (w tym za prace LCD) pozostały bez zmian. 3. Podobnie w rejestrze masek ustaw tylko 2 najstarsze bity pozostawiając pozostałe bez zmian.

Liczniki/Timery Moduły liczników/timerów są przeznaczone do zliczania impulsów zegarowych mikrokontrolera lub impulsów na liniach zewnętrznych mikrokontrolera. Przy zliczaniu impulsów zegarowych można wykorzystać dzielnik wstępny impulsów przez N (prescaler) tym samym wydłużając N-krotnie zliczony czas. W najprostszym trybie zliczanie następuje od 0 do 2 8 w przypadku Timera 8-bitowego, oraz od 0 do 2 16 w przypadku Timera 16-bitowego. Po przepełnieniu rejestr liczący zapełnia się zerami, a Timer zlicza nadal.

Timer 8-bitowy prescaler Rejestr kontrolny TIMER a 0 TCCR0 Bit 7 6 5 4 3 2 1 0 Nazwa - - - - - CS02 CS01 CS00 Odczyt/zapis R R R R R R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 Prescaler TIMER a 0 [1] CS02 CS01 CS00 Impulsy zliczane 0 0 0 Zatrzymanie TIMER a 0 0 0 1 CK 0 1 0 CK/8 0 1 1 CK/64 1 0 0 CK/256 1 0 1 CK/1024 1 1 0 Zbocza opadające na linii 0 portu B 1 1 1 Zbocza narastające na linii 0 portu B

Timer 8-bitowy wybór prescalera Rejestr kontrolny TIMER a 0 TCCR0 Bit 7 6 5 4 3 2 1 0 Nazwa - - - - - CS02 CS01 CS00 Odczyt/zapis R R R R R R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 Przykład: wybór prescalera 1024 TCCR0 = 0b00000101; TCCR0 = 0x05; TCCR0 = (1<<CS02) (1<<CS00); TCCR0 = _BV(CS02) _BV(CS00); Wyrażenia (1<<x) oraz _BV(x) są identycznymi liczbami, które mają jedną binarną jedynkę na pozycji x.

Timer 8-bitowy rejestry Rejestr zliczania TIMER a 0 TCNT0 Bit 7 6 5 4 3 2 1 0 Nazwa MSB - - - - - - LSB Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 Rejestr flagowy timerów TIFR Bit 7 6 5 4 3 2 1 0 Nazwa TOV1 OCF1A OCF1B - ICF1 - TOV0 - Odczyt/zapis R/W R/W R/W R R/W R R/W R Wartość początkowa 0 0 0 0 0 0 0 0 W rejestrze TCNT0 następuje zliczanie kroków od 0 do 256. Ustawienie flagi TOV0 (bit 2) sygnalizuje przepełnienie. Po przepełnieniu rejestr TCNT0 zapełnia się zerami, a Timer kontynuuje zliczanie.

Timer 8-bitowy maska przerwania Zdjęcie maski TOIE0 (ustawienie bitu 2) włącza przerwanie wywołane przepełnieniem Timera 0. Po każdym przepełnieniu program główny pobiera adres procedury przerwania z wektora przerwań i wykonuje procedurę przerwania (watek boczny), po czym wraca do wątku głównego i kontynuuje jego wykonywanie. Rejestr masek timerów TIMSK Bit 7 6 5 4 3 2 1 0 Nazwa TOIE1 OCIE1A OCIE1 - TICIE1 - TOIE0 - Odczyt/zapis R/W R/W R/W R R/W R R/W R Wartość początkowa 0 0 0 0 0 0 0 0

Timer 8-bitowy obsługa programowa Obsługa programowa polega na sprawdzaniu w pętli, czy ustawiła się flaga sygnalizująca przepełnienie. int main(void) { TCCR0 = (1<<CS00); //włącz Timer, prescaler = 1 while (! (TIFR & (1<<TOV0))); //dopóki nie ustawi się //flaga TOV0 stój TIFR =(1<<TOV0); //wyzeruj flagę TCCR0 = 0x00; //wyłącz Timer return 0; }

Timer 8-bitowy obsługa sprzętowa Obsługa sprzętowa polega na zdjęciu maski i zleceniu modułowi Timerów sprawdzanie, czy doszło do przepełnienia oraz wykonanie procedury przerwania. ISR (Timer0_OVF_vect) { asm( nop ); } //procedura przerwania //asemblerowy rozkaz pusty int main(void) { TCCR0 = (1<<CS00); //włącz Timer, prescaler = 1 TIMSK = (1<<TOIE0); //zdejmij maskę TOIE0 sei(); //włączenie przerwań do { asm( nop ); //asemblerowy rozkaz pusty while(1); //nic nie rób czekaj na przerwania return 0; }

Timer 8-bitowy polecenia 1. Napisz program, który zlicza przerwania Timera 0 (czyli zlicza, ile razy licznik się przekręcił ) i wartość tą pokazuje na 8-miu diodach. 2. Napisz program, który po kolejnych przerwaniach Timera na przemian zapala i gasi wybraną diodę.

Magistrala równoległa Mikrokontroler może zaadresować 64 kbajty komórek w zewnętrznej przestrzeni adresowej. Adresowanie odbywa się równolegle na 16-stu liniach portów A (8 linii) oraz C (8 linii). Dane są przesyłane na 8 liniach portu A. Podwójne wykorzystanie linii portu A (do adresowania i przesyłu danych) jest możliwe dzięki zastosowaniu zatrzasku adresowego. W układzie EVB-503 na magistrali równoległej podłączono pamięć zewnętrzną RAM o pojemności 32kbajty. Dwa z pozostałych wolnych adresów zostały wykorzystane do podłączenia wyświetlacza LCD.

Tryb PWM timera1 (Procesor AT90S8515) Założenia: PWM 10-bitowy timer1 zlicza w górę od 0 do 1023 (0x03ff) i w dół do 0 Zatem okres przebiegu wynosi 2046 cykli okresu timera 1 (prescler =8), wartość porównawcza ustawiana jest w rejestrze OCR1A i powinna zmieniać się w zakresie od 0 do 1023, aby uzyskać płynną zmianę współczynnika wypełnienia Przebiegu PWM. Przebieg PWM podawany jest na diodę, która jest sterowana wartościąśrednia przebiegu.

Tryb PWM timera1 (Procesor AT90S8515) Założenie x=a (wyjście A OC1A przebiegu PWM)

Tryb PWM timera1 (Procesor AT90S8515) Założenie x=a (wyjście A OC1A przebiegu PWM) lub

Tryb PWM timera1 Założenie: współczynnik wypełnienia zmienia się płynnie po każdym przepełnieniu timera1 ISR (TIMER1_OVF_vect) { OCR1A = if (OCR1A == 0x03ff) } //tryb timera 1 przepełnienie (overflow) int main (void) { TCCR1A = // tryb PWM 10-bitowy TCCR1B = // preskaler = 8 OCR1A = 0; // wartość początkowa DDRD = // wyjście A układu PWM TIMSK = //maska timera 1 tryb timera 1 przepełnienie (overflow) sei (); // odblokowanie przerwań while(1); return (0); }

Tryb PWM timera1 Założenie: współczynnik przepełnienia zmienia każdorazowo po naciśnięciu przycisku na wejściach INT0 (rośnie) lub INT1 (maleje) ISR (INT0_vect) { OCR1A = if (OCR1A == 0x03ff) } ISR (INT1_vect) { OCR1A = if (OCR1A == 0) } int main (void) { TCCR1A = // tryb PWM 10-bitowy TCCR1B = // preskaler = 8 OCR1A = 0; // wartość początkowa DDRD = // wyjście A układu PWM MCUCR = // przerwanie INT0 i INT1 aktywne zboczem sei (); // odblokowanie przerwań while(1); return (0); }

Podłączenie wyświetlacza LCD W układzie EVB-503 wyświetlacz LCD został umieszczony w zewnętrznej przestrzeni adresowej pod adresem ustalonym przez konfigurację wyprowadzeń dekodera adresowego. Dostęp do danych w tym układzie znajduje się pod adresem $1F91, a dostęp do instrukcji sterujących wyświetlaczem pod adresem $1F90. W programie adresy te należy zdefiniować jako stałe typu wskaźnikowego: #define LCD_rozkaz (*(unsigned char *) (0x1F90)) #define LCD_dane (*(unsigned char *) (0x1F91))

Procedury wyświetlacza LCD Do sterowania wyświetlaczem należy zdefiniować 3 procedury (funkcje): void LCD_sterowanie (int rozkaz) przesyła rozkaz pod adres 0x1F90, gdzie jest on interpretowany przez sterownik LCD jako rozkaz sterujący (przestaw kursor, przesuń napis itd..) void wyswietl_znak (int zn) przesyła rozkaz pod adres 0x1F91, gdzie jest on interpretowany przez sterownik LCD jako dana dla DDRAM-u (DATA RAM) i zostanie wyświetlony na LCD od pozycji bieżącej kursora. Sterownik LCD zapewnia automatyczną post-inkrementację pozycji na LCD, dlatego przy wyświetlaniu ciągu znaków ustala się pozycję tylko 1- szego znaku w ciągu void LCD_ini (void) zestaw komend aktywujących wyświetlacz wg wymagań sterownika HD44780

Zestaw procedur wyświetlacza LCD void LCD_steruj (int rozkaz) { LCD_rozkaz = rozkaz; _delay_ms(5); } void wyswietl_znak (char zn) { LCD_dane = zn; _delay_ms(1); } //rozkaz sterujący //wyświetlenie danej void LCD_ini (void) { // wpisz rozkazy ze slajdu Konfiguracja wyświetlacza LCD } int main(void) { return 0; }

Konfiguracja wyświetlacza LCD Procedura konfiguracji/aktywacji wyświetlacza LCD składa się z następujących rozkazów: Włączenie interfejsu przestrzeni adresowej zewnętrznej bit SRE Opóźnienie strobu (impulsu) zapisu np. o 1 cykl bit SRW Komenda trybu sterowania (8-mio bitowy - 0x38) wydana 3x Komenda przesuwania napisu i kursora (bez zmiany zawartości DDRAM) Komenda włączenia wyświetlacza Komenda przesuwania napisu i kursora (ze zmianą zawartości DDRAM) Komenda czyszczenia wyświetlacza Komenda początkowego ustawienia kursora (adres DDRAM)

Aktywacja wyświetlacza LCD Przykładowa procedura aktywacji wyświetlacza LCD: void LCD_ini (void) { MCUCR = (1<<SRE) (1<<SRW); LCD_steruj(0b00111000); LCD_steruj(0b00111000); LCD_steruj(0b00111000); LCD_steruj(0b00011000); LCD_steruj(0b00001100); LCD_steruj(0b00000110); LCD_steruj(0b00000001); LCD_steruj(0b10000000); }

Dostęp do zewnętrznej przestrzeni adresowej Rejestr kontrolny MCUCR (mikrokontroler AT90S8515) Bit 7 6 5 4 3 2 1 0 Nazwa SRE SRW SE SM ISC11 ISC10 ISC01 ISC00 Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 Aktywacja zewnętrznej przestrzeni adresowej odbywa się przez ustawienie bitu 7 (SRE) rejestru MCUCR. Wymagane opóźnienie impulsu zapisu/odczytu o 1 cykl maszynowy uzyskuje się przez ustawienie bitu 7 (SRW) rejestru MCUCR.

Komenda trybu sterowania Bit 7 6 5 4 3 2 1 0 Nazwa/Wartość 0 0 1 D/L N F * * D/L liczba bitów danych interfejsu sterującego: D/L=1 interfejs 8- bitowy, D/L=0 interfejs 4-bitowy, N F liczba wyświetlanych linii: N=1 dwie linie, N=0 jedna linia format znaku: F=1 znak 5 10 punktów, F=0 znak 5 7 punktów * Wartość nieistotna (czas wykonania komendy 5ms)

Komenda przesuwania napisu/kursora bez zmiany zawartości DDRAM-u Bit 7 6 5 4 3 2 1 0 Nazwa/Wartość 0 0 0 1 S/C R/L * * S/C R/L S/C=1 przesuwanie napisu bez zmiany zawartości pamięci danych DDRAM sterownika LCD, S/C=0 przesuwanie kursora bez zmiany zawartości pamięci danych DDRAM sterownika LCD (pamięć DDRAM przechowuje znaki wyświetlone na matrycy LCD), R/L=1 przesuwanie w prawo, R/L=0 przesuwanie w lewo * Wartość nieistotna (czas wykonania komendy 120 us)

Komenda włączania wyświetlacza Bit 7 6 5 4 3 2 1 0 Nazwa/Wartość 0 0 0 0 1 D C B D włącza/wyłącza wyświetlacz) C włącza/wyłącza kursor B włącza/wyłącza funkcję mrugania kursora (czas wykonania komendy 120 us)

Komenda przesuwania napisu/kursora ze zmianą zawartości DDRAM-u Bit 7 6 5 4 3 2 1 0 Nazwa/Wartość 0 0 0 0 0 1 I/D S I/D S ustala kierunek przesuwu kursora: I/D = 1 w prawo, I/D = 0 w lewo włącza (S = 1) i wyłącza (S = 0) funkcję przesuwu napisu z równoczesnym przesuwaniem znaków w pamięci danych DDRAM sterownika (czas wykonania komendy 120 us)

Komenda powrotu kursora Bit 7 6 5 4 3 2 1 0 Nazwa/Wartość 0 0 0 0 0 0 1 * Ustawia kursor na pozycji początkowej (adres=0). Jeśli napis był przesunięty, ustawia go w pozycji oryginalnej. Pamięć danych DRRAM nie ulega zmianie. (czas wykonania komendy 5ms)

Komenda czyszczenia wyświetlacza Bit 7 6 5 4 3 2 1 0 Nazwa/Wartość 0 0 0 0 0 0 0 1 Czyści wyświetlacz i ustawia kursor na adresie 0 pamięci danych DRAM. Komenda ta jest używana tylko podczas konfiguracji wyświetlacza. W trakcie pracy wyświetlacza znaki na LCD należy nadpisywać bez czyszczenia. (czas wykonania komendy 5ms)

Komenda ustawiania adresu DDRAM-u Bit 7 6 5 4 3 2 1 0 Nazwa/Wartość 1 DD DD DD DD DD DD DD Ustawia adres pamięci danych DDRAM odpowiadający pozycji znaku na wyświetlaczu. Adres należy ustawić na 7-miu bitach oznaczonych DD pozostawiając 1 na najstarszym bicie. Adresy 1-szej linii leżą w zakresie od 0 do 63, a 2-giej linii od 64 do 127. Na matrycach LCD o liczbie znaków mniejszej niż 64 dalsze znaki każdej linii pozostaną niewidoczne. (czas wykonania komendy 120 us)

Przykłady wyświetlania znaków LCD_ini( ); //inicjuj wyświetlacz LCD_steruj (128); //ustawia kursor w górnej linii na lewym skraju wyswietl_znak (66); //wyświetla literę B LCD_steruj (???); // kursor w górnej linii na prawym skraju wyswietl_znak (???); //wyświetla cyfrę 2 LCD_steruj (???); //ustawia kursor w dolnej linii na lewym skraju wyswietl_znak ( A ); // wyświetla literę A LCD_steruj (???); // kursor w dolnej linii na prawym skraju wyswietl_znak (0x33); // wyświetla cyfrę 3

Wyświetlanie znaków - polecenia 1. Wyświetl litery A, B, C w dolnej linii rozpoczynając od 3-ciej pozycji. 2. Wyświetl w jednej linii tekst składający się z 30-ciu znaków (większość z nich będzie niewidoczna). Następnie obracaj powoli napis w lewo, aby można było zobaczyć ukryte znaki. Uwaga! Nie zmieniaj rozkazów w funkcji LCD_ini. Obrót rozpocznij po wyświetleniu napisu. 1. Napisz program, który zlicza przerwania Timera 0 i wyświetla na LCD liczbę przepełnień Timera (liczba przepełnień jest zapisana w rejestrze Timera w postaci binarnej i przed wyświetleniem wymaga zamiany na ASCII).

Tablica kodów ASCII Znak Kod Znak Kod Znak Kod Znak Kod Znak Kod 32! 33 " 34 # 35 $ 36 % 37 & 38 ' 39 ( 40 ) 41 * 42 + 43, 44-45. 46 / 47 0 48 1 49 2 50 3 51 4 52 5 53 6 54 7 55 8 56 9 57 : 58 ; 59 < 60 = 61 > 62? 63 @ 64 A 65 B 66 C 67 D 68 E 69 F 70 G 71 H 72 I 73 J 74 K 75 L 76 M 77 N 78 O 79 P 80 Q 81 R 82 S 83 T 84 U 85 V 86 W 87 X 88 Y 89 Z 90 [ 91 \ 92 ] 93 ^ 94 _ 95 ` 96 a 97 b 98 c 99 d 100 e 101 f 102 g 103 h 104 i 105 j 106 k 107 l 108 m 109 n 110 o 111 p 112 q 113 r 114 s 115 t 116 u 117 v 118 w 119 x 120 y 121 z 122 { 123 124 } 125 ~ 126

Wskaźniki do pamięci RAM i FLASH Do zapisu i odczytu pamięci RAM wykorzystujemy typowe zmienne wskaźnikowe języka C char* str; char zn; zn = * (str); //deklaracja wskaźnika typu char w pamięci RAM //deklaracja zmiennej typu char w pamięci RAM //pobranie znaku spod wskaźnika str i przepisanie //na zmienną zn Do zapisu i odczytu pamięci FLASH środowisko ma zdefiniowany własny zestaw wskaźników i procedur zdefiniowanych w pliku nagłówkowym #include <avr/pgmspace.h> PGM_P str_p; char zn; zn = pgm_read_byte(str_p); //deklaracja wskaźnika typu char w pamięci FLASH //deklaracja zmiennej typu char w pamięci RAM // pobranie znaku z pamięci FLASH spod wskaźnika str_p // i przepisanie go na zmienną zn w pamięci RAM

Procedury wyświetlania tekstów z pamięci RAM i FLASH Procedura pisz_string pobiera kolejne znaki spod wskaźnika str do tablicy i wyświetla je na LCD dopóki nie napotka na NULL void pisz_string (char* str) { char zn; while(0!= (zn = * (str++))) wyswietl_znak(zn); } Procedura pisz_string_p pobiera kolejne znaki spod wskaźnika str_p do pamięci FLASH i wyświetla je na LCD dopóki nie napotka na NULL void pisz_string_p (PGM_P str_p) { char zn; while(0!= (zn = pgm_read_byte(str_p ++))) wyswietl_znak(zn); }

Deklaracje tablic w pamięciach RAM i FLASH //dane w pamięci RAM char napis[ ] = "witaj!"; char tablica[ ] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9}; char *str; Dane przechowywane w pamięci FLASH muszą mieć charakter globalny //dane w pamięci FLASH const char napis_p[ ] PROGMEM= hello!"; char tablica_p[ ] PROGMEM= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3}; PGM_P str_p;

Przykłady wyświetlania tekstów z pamięci RAM i FLASH RAM wyswietl_znak(tablica[5]); pisz_string(napis); pisz_string("haha! "); FLASH str_p= & tablica_p[5]; char zn; zn = pgm_read_byte (str_p); wyswietl_znak(zn); pisz_string_p(napis_p); pisz_string_p(pstr( Hurra! ));

Pamięć EEPROM rejestr adresowy Elektrycznie programowalna, nieulotna pamięć EEPROM mikrokontrolera AT90S8515 ma 512 bajtów adresowanych od 0 do 511. Adres zapisu/odczytu danej należy umieścić w 16-sto bitowym rejestrze EEAR (EEARH+EEARL). Rejestr adresowy pamięci EEPROM - EEAR (część starsza EEARH, część młodsza EEARL) Bit 15 14 13 12 11 10 9 8 Nazwa MSB Nazwa LSB Odczyt/zapis 7 R 6 R 5 R 4 R 3 R 2 R 1 R 0 R/W Wartość początkowa R/W 0 R/W 0 R/W 0 R/W 0 R/W 0 R/W 0 R/W 0 R/W 0 0 0 0 0 0 0 0 0

Pamięć EEPROM rejestr danych Daną przeznaczoną dla pamięci EEPROM należy wstawić do rejestru EEDR. Zapisanie jednego bajtu w pamięci EEPROM trwa od 2.5 4ms. W procesie odczytu dana spod adresu umieszczonego w rejestrze EEAR jest przepisywana do rejestru EEDR. Odczyt jednego bajtu trwa 4 cykle zegarowe. Rejestr danych pamięci EEPROM EEDR Bit 7 6 5 4 3 2 1 0 Nazwa MSB LSB Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0

Pamięć EEPROM - procedury Dla zapisania i odczytania pamięci EEPROM najlepiej posłużyć się gotowymi procedurami zawartymi w pliku nagłówkowym eeprom.h. W pliku eeprom.h można zapoznać się z deklaracjami procedur dla EEPROM-u: void eeprom_write_word (unsigned int *adres, unsigned int *dana); unsigned int eeprom_read_word (unsigned int *adres); Przykład wykorzystania w programie: #include <avr/eeprom.h> unsignad int *l; eeprom_write_word (l+8, 'b'); eeprom_busy_wait(); char c; c= eeprom_read_word (l+8); wyswietl_znak(c); Samodzielne tworzenie procedur dla EEPROM-u jest nieskuteczne ze względu na wymagania czasowe (kolejność impulsów musi następować z dokładnością do 4 cykli zegarowych) język C nie daje możliwości takiego panowania nad czasem.

Przetwornik analogowo-cyfrowy Ćwiczenie jest wykonywane na mikrokontrolerze ATMega8, który jest wyposażony w 8-mio kanałowy przetwornik analogowo-cyfrowy o rozdzielczości 10-cio bitowej wyprowadzony na 8 linii portu C. Kanały można skonfigurować jako niesymetryczne lub symetryczne (różnicowe). Kanałom różnicowym można przyporządkować określone wartości wzmocnienia. Typowa częstotliwość przetwarzania mieści się między 50 a 200kHz.

Rejestr konfiguracji przetwornika Rejestr konfiguracji przetwornika ADC ADMUX Bit 7 6 5 4 3 2 1 0 Nazwa REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0 Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 REFS1, REFS0 wybór zakresu przetwarzania ADLAR bit decydujący o sposobie wyrównania wyniku konwersji w rejestrze ADC (ADCH+ADCL), gdy ADLAR = 0 wyrównanie do prawej, gdy ADLAR = 1 wyrównanie do lewej MUX4 MUX0 wybór kombinacji wejść analogowych podłączonych do przetwornika oraz wzmocnień dla tych wejść. Dla MUX4 MUX0 = 0 wybrane jest wejście niesymetryczne 0 na porcie F ze wzmocnieniem równym 1

Zakres przetwarzania Napięcie odniesienia dla przetwornika REFS1 REFS0 Napięcie odniesienia 0 0 Zewnętrzne źródło podłączone do pinu AREF 0 1 Wewnętrzne 5V z kondensatorem podłączonym na pinie AREF 1 0 zarezerwowane 1 1 Wewnętrzne 2.56V z kondensatorem podłączonym do pinu AREF Zakres napięcia przetwarzanego może być podawany wewnętrznie lub zewnętrznie na pin AREF. Przy wyborze źródła wewnętrznego minimalne napięcie przetwarzania wynosi 0V, a maksymalne 5V-1LSB lub 2.56V-1LSB. Rozdzielczość przetwarzania jest 10-bitowa.

Wyrównanie wyniku konwersji w rejestrze danych Rejestr danych ADCH i ADCL (dla bitu ADLAR = 0) Bit 15 14 13 12 11 10 9 8 ADCH - - - - - - ADC9 ADC8 ADCL ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADC0 Bit 7 6 5 4 3 2 1 0 Odczyt/zapis R R R R R R R R Wartość początkowa 0 0 0 0 0 0 0 0 Rejestr danych ADCH i ADCL (dla bitu ADLAR = 1) Bit 15 14 13 12 11 10 9 8 ADCH ADC9 ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADCL ADC1 ADC0 - - - - - - Bit 7 6 5 4 3 2 1 0 Odczyt/zapis R R R R R R R R Wartość początkowa 0 0 0 0 0 0 0 0

Rejestr statusowy przetwornika Rejestr statusowy przetwornika ADC ADCSR Bit 7 6 5 4 3 2 1 0 Nazwa ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0 Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 ADEN włączenie przetwornika ADSC rozpoczęcie przetwarzania ADC. Konwersja trwa 14 cykli zegara przetwornika, przy czym 1-sza konwersja po włączeniu przetwornika trwa 25 cykli zegara przetwornika. ADFR - włączenie ciągłego przetwarzania, rejestr wyniku przetwarzania jest aktualizowany w sposób ciągły ADIF flaga sygnalizująca zakończenie pojedynczego przetwarzania ADIE maska przerwania przetwornika ADPS2, ADPS1, ADPS0 preskaler zegara przetwornika, im większy współczynnik preskalera tym powolniejszy zegar przetwornika i dokładniejszy wynik konwersji

Czas konwersji Czas konwersji jest wyrażony w cyklach zegara przetwornika Warunki Czas uśredniania (w cyklach zegara przetwornika) Czas konwersji (w cyklach zegara przetwornika) 1-sza konwersja 14.5 25 Konwersja na wejściu niesymetrycznym Konwersja na wejściu różnicowym 1.5 13 1.5/2.5 13/14

Prescaler zegara przetwornika ADPS2 ADPS1 ADPS0 Współczynnik podziału 0 0 0 2 0 0 1 2 0 1 0 4 0 1 1 8 1 0 0 16 1 0 1 32 1 1 0 64 1 1 1 128

Założenia programu przetwarzania A/C wejście niesymetryczne 0-we przetwornika (linia 0 portu C) - wybór wejścia 0 wymaga wyzerowania bitów MUX4-MUX0 w rejestrze ADMUX, zakres przetwarzania 5V-owy ze źródłem wewnętrznym, przetwarzanie ciągłe - ustawiony bit ADFR w rejestrze ADCSR, ograniczenie rozdzielczości do 8-mio bitowej (wyrównanie do lewej na bicie ADLAR i odczyt wyłącznie starszej części rejestru ADC), uśrednianie wyniku przetwarzania co 5 pomiarów, Wyrażenie wyniku pomiaru w mv (wynik pomiaru wyrażony w mv leży w zakresie 0 5000mV i musi być przechowany na zmiennej int Wyrażenie wyniku pomiaru w kodzie ASCII Wysłanie w UART poszczególnych cyfr wyniku pomiaru w ASCII

Szkic programu przetwarzania A/C int main (void) { int wynik; Skonfiguruj rejestry ADMUX i ADCSR wg założeń Skonfiguruj interfejs UART (9600, 8n1) do { for (wykonaj 5 razy) { Poczekaj na zakończenie przetwarzania (sygnalizacja flagą ADIF), Odczytaj wynik przetwarzania } Uśrednij wynik przetwarzania z 5-ciu pomiarów, Uśredniony wynik przetwarzania wyraź w mv (pomnoż przez krok przetwornika), Uśredniony wynik przetwarzania w mv przekształć na kod ASCII Wyślij w UART kolejne cyfry ASCII wyniku pomiaru } while (1); return 0; }

Zamiana zapisu binarnego na ASCII Założenie: liczba jest typu int MAX 2 16 = 65536 (wynik pomiaru wyrażony w mv leży w zakresie 0 5000mV). Przekształcenie liczby binarnej na kod ASCII należy wykonać w następującego wzoru: Oblicz kolumnę dziesiątek tysięcy: dz_tys = liczba/10000; Oblicz kolumnę tysięcy (procent oznacza resztę z dzielenia): tys = (liczba%10000)/1000; Oblicz resztę z dzielenia przez tysiąc: reszta = (liczba%10000)%1000;..kontunuuj

ATMega328 Memories: Flash memory 32kB SRAM 2kB EEPROM 1kB

ISP programming

Bootloader programming The bootloader is basically a.hex file that runs when you turn on the board. It is very similar to the BIOS that runs on your PC. It does two things. First, it looks around to see if the computer is trying to program it. If it is, it grabs the program from the computer and uploads it into the ICs memory (in a specific location so as not to overwrite the bootloader). That is why when you try to upload code, the Arduino IDE resets the chip. This basically turns the IC off and back on again so the bootloader can start running again. If the computer isn t trying to upload code, it tells the chip to run the code that s already stored in memory. Once it locates and runs your program, the Arduino continuously loops through the program and does so as long as the board has power.

Arduino Uno board

USART Interface and USART connection to PC COM MAX 232 converts signals from an RS-232 serial port to signals suitable for use in TTL Asynchronous transmission

USART to USB adapter

The Uno differs from all preceding boards in that it does not use the FTDI USB-to-serial driver chip. Instead, it features the Atmega16U2 (Atmega8U2 up to version R2) programmed as a USB-to-serial converter.

Default Clock Source The device is shipped with internal RC oscillator at 8.0MHz and with the fuse CKDIV8 programmed, resulting in 1.0MHz system clock. The startup time is set to maximum and time-out period enabled. (CKSEL = "0010", SUT = "10", CKDIV8 = "0"). The default setting ensures that all users can make their desired clock source setting using any available programming interface. Other clock sources Low power crystal oscillator crystal External oscillator Low frequency crystal oscillator Used for real time clock

Clock systems

Linia DTR umożliwia resetowanie mikrokontrolera z komputera PC konieczne przed ładowaniem programu przez bootloader

General purpose input/output schematic

Tryby uśpienia i sposób wybudzania

Controlling sleep modes register description

Interrupt vectors

Przerwania zewnętrzne Przerwania zewnętrzne dostępne są na pinach INT0, INT1 oraz PCINT23 - PCINT0. Maski przerwań INT0 oraz INT1 leżą w rejestrze EIMSK. W rejestrze PCICR leżą bity aktywacji przerwań PCINT0-7 (bit PCIE0), PCINT8-14 (bit PCIE1), PCINT15-23 (bit PCIE2). W rejestrach PCMSK0, 1, 2 leżą maski indywidualne przerwań PCINT23-0. W rejestrze EICRA leżą bity konfiguracji przerwań INT0 oraz INT1 (zboczem opadającym, narastającym, poziomem niskim). Przerwania PCINT23-0 sa aktywowane każda zmianą na odpowiadających pinach wejściowych.

Bitwise operators: & AND OR ~ NOT << SHIFT LEFT >> SHIFT RIGHT Example: Bitwise AND PORTD = 0b???????? Number= 0b11111011???????? unknown bits & 11111011 =?????0?? result: one bit cleared Binary and hex numbers are best suited to address ports Examples: 0b00000001 = 0x01 0b00000010 = 0x02 0b00000100 = 0x04 0b00001000 = 0x08 0b00001100 = 0x0C 0b11110001 = 0xF1 0b10001000 = 0x88

Example: Bitwise OR PORTD = 0b???????? Number= 0b00000100???????? unknown bits 00000100 =?????1?? result: one bit set Example: Bitwise NOT PORTD = 0b10101010 ~PORTD = 0b01010101 Example: Bitwise SHIFT PORTD = 0b10101010 PORTD<<1 = 0b01010100

Types of variables

Using Arduino library Using PORT names Pin 2 as input internally pulled up pin 2 = PORTD, 2 DDRD = DDRD & 0xFB; (input) pinmode(2, INPUT_PULLUP); PORTD = PORTD 0x04; (pullup) Pin 2 as input floating (high Z) pin 2 = PORTD, 2 DDRD = DDRD & 0xFB; (input) pinmode(2, INPUT); PORTD = PORTD & 0xFB;(floating) Pin 13 as output pin 13 = PORTB, 5 DDRB = DDRB 0x20; PORTB = PORTB 0x20; PORTB = PORTB & 0xDF; pinmode(13, OUTPUT); digitalwrite(13, HIGH); digitalwrite(13, LOW);

Cod in AtmelStudio: int main(void) { setup(); while (1) loop(); return 0; } Cod in Arduino setup(); loop(); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setup (void) { // the setup function runs once when you press reset or power the board //funkcja setup jest wykonywana 1x po resecie lub podaniu zasilania } void loop(void) { // the loop function runs over and over again forever //funkcja loop() jest wykonywana w kółko w nieskończonej pętli }

Example: blinking LED Using Arduino library void setup() { pinmode(13, OUTPUT); } void loop() { digitalwrite(13, HIGH); delay(1000); // wait for a second digitalwrite(13, LOW); delay(1000); } Using PORT names void setup() { DDRB = DDRB 0x20; } void loop() { PORTB = PORTB 0x20; delay(1000); // wait for a second PORTB = PORTB & 0xDF; delay(1000); }

Example: button const int buttonpin = 2; // the number of the pushbutton pin const int ledpin = 13; // the number of the LED pin int buttonstate = 0; // variable for reading the pushbutton status void setup() { pinmode(ledpin, OUTPUT); pinmode(buttonpin, INPUT); } // initialize the LED pin as an output: // initialize the pushbutton pin as an input: void loop() { buttonstate = digitalread(buttonpin); // read the state of the pushbutton value: if (buttonstate == HIGH) // check if the pushbutton is pressed. { // turn LED on: digitalwrite(ledpin, HIGH); } else { // turn LED off: digitalwrite(ledpin, LOW); } }

Example: serial monitor Serial monitor is an application on PC connected to USART via USB int incomingbyte = 0; // for incoming serial data void setup() { Serial.begin(9600); } // opens serial port, sets data rate to 9600 bps void loop() { // send data only when you receive data: if (Serial.available() > 0) { // read the incoming byte: incomingbyte = Serial.read(); } } // say what you got: Serial.print("I received: "); Serial.println(incomingByte, DEC);

Serial.write(33); Serial.write(33) gives 33" Writes binary data to the serial port Serial.print(45); Prints data to the serial port as human-readable ASCII text Serial.print(33) gives 33" Serial.print(1.23456) gives "1.23" Serial.print('N') gives "N" Serial.print("Hello world.") gives "Hello world." Serial.print(78, BIN) gives "1001110" Serial.print(78, OCT) gives "116" Serial.print(78, DEC) gives "78" Serial.print(78, HEX) gives "4E" Serial.println(1.23456, 0) gives "1" Serial.println(1.23456, 2) gives "1.23" Serial.println(1.23456, 4) gives "1.2346"

void setup() { //Initialize serial and wait for port to open: Serial.begin(9600); Serial.println("ASCII Table Character Map"); } int thisbyte = 33; // first visible ASCIIcharacter '!' is number 33: void loop() { Serial.write(thisByte); Serial.print(", dec: "); Serial.print(thisByte); // Serial.print(thisByte, DEC); Serial.print(", hex: "); Serial.print(thisByte, HEX); Serial.print(", oct: "); Serial.print(thisByte, OCT); Serial.print(", bin: "); Serial.println(thisByte, BIN); if (thisbyte == 126) { { while (true) { continue; } } // go on to the next character thisbyte++; }

#include <util/delay.h> includes _delay_us(80); _delay_ms(80); delaymicroseconds(480); Example: delay functions

Example: analog input void setup() { Serial.begin(9600); } void loop() { int sensorvalue = analogread(a0); Serial.println(sensorValue); delay(1);}

Example: Timer1 overflow vector #define ledpin 13 void setup() { pinmode(ledpin, OUTPUT); nointerrupts(); // disable all interrupts TCCR1A = 0; TCCR1B = 0; TCCR1B = (1 << CS12); // 256 prescaler TIMSK1 = (1 << TOIE1); // enable timer compare interrupt interrupts(); // enable all interrupts } ISR(TIMER1_OVF_vect) // timer compare interrupt service routine { digitalwrite(ledpin, digitalread(ledpin) ^ 1); // toggle LED pin } void loop() { }

#define ledpin 13 void setup() { pinmode(ledpin, OUTPUT); nointerrupts(); // disable all interrupts TCCR1A = 0; TCCR1B = 0; OCR1A = 31250; // compare match register 16MHz/256/2Hz TCCR1B = (1 << WGM12); // CTC mode TCCR1B = (1 << CS12); // 256 prescaler TIMSK1 = (1 << OCIE1A); // enable timer compare interrupt interrupts(); // enable all interrupts } ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine { digitalwrite(ledpin, digitalread(ledpin) ^ 1); } void loop() { } Example: Timer1 compare vector CTC mode

Funkcja biblioteczna attachinterrupt attachinterrupt(digitalpintointerrupt(pin), procedura przerwania, atrybut); Funkcja attachinterrupt dotyczy wektorów przerwań zewnętrznych INT0 oraz INT1 powiązanych z liniami 2 i 3 na porcie D (pin 2 i 3 w numeracji Arduino). Stan wysoki na linii zewnętrznej jest wyjściowym stanem bezczynnym IDLE. Atrybutem funkcji jest zdarzenie na linii zewnętrznej wywołujące przerwanie: LOW (poziom niski), FALLING (zbocze opadające, RISING (zbocze narastające), CHANGE (każda zmiana). Procedura przerwania jest funkcją powiązaną z wektorem przerwania, wykonywaną pod warunkiem zajścia zdarzenia na linii zewnętrznej. #define ledpin 13 void setup() { pinmode(ledpin, OUTPUT); attachinterrupt(digitalpintointerrupt(0), blink, FALLING); void loop() {} void blink () { digitalwrite (ledpin, digitalread(ledpin)^1); } Example: INT0, INT1 vectors

Example: PCINT vectors void setup() { DDRB = 0x20; //output digitalwrite(13, LOW); //Pin Change Interrupt enable on PCINTx (Port x) PCICR = _BV(PCIEx); PCMSKx = _BV(PCINTx); sei(); } ISR(PCINTx_vect) { if (..) digitalwrite(13, HIGH); } void loop() {}

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x13, 0x3A }; //physical mac address byte ip[] = { 192, 168, 0, 230 }; // ip in lan byte gateway[] = { 192, 168, 0, 1 }; // the IP of the router byte subnet[] = { 255, 255, 255, 0 }; //subnet mask EthernetServer server(80); // server port (change int ledpin = 4; // LED pin void setup() { Serial.begin(9600); ////enable serial data print Ethernet.begin(mac, ip, gateway, subnet); //start Ethernet pinmode(ledpin, OUTPUT); //Set pin 4 to output }

void loop() { EthernetClient client = server.available(); // Create a client connection if (client) { buttonpress = digitalread(3); while (client.connected()) { if (client.available()) { char c = client.read(); if (dstring.length() < 30) { dstring += c; if (c == '\n') { client.println("http/1.1 200 OK"); //send new page client.println("content-type: text/html"); client.println(); client.println("refresh: 1"); // refresh every sec client.println("</html></body>"); client.println("<font color='red'><h1>arduino Remote control</font></h1>");//send first heading client.println("<br />"); client.println("<hr />"); client.println("</body></html>"); dstring = ""; //clearing string for next read delay(10); client.stop(); //stopping client }}}}}}

if (dstring.indexof("l=1") > 0) { digitalwrite(ledpin, HIGH); // set the LED on LEDON = true; } if (dstring.indexof("l=0") > 0) { digitalwrite(ledpin, LOW); // set the LED on LEDON = false; }.. Komponenty w html u Tworzone są: dwa radiobuttony o działaniu alternatywnym komponent submit przekazujący rozkaz dla diod przez dopisanie łańcucha do żądania HTTP client.println("<form method=get name=med><br>"); if (LEDON == false) { client.println("<input type='radio' name='l' value='1'>led ON<br>"); client.println("<input type='radio' name='l' value='0' checked>led OFF<br>"); } else if (LEDON == true) { client.println("<input type='radio' name='l' value='1' checked>led ON<br>"); client.println("<input type='radio' name='l' value='0'>led OFF<br>"); } client.println("<input type=submit value=submit></form>");

client.println("<hr />"); client.println("<br />"); client.println("<font color='blue'>analog input: "); sensorvalue = analogread(sensorpin); client.print(sensorvalue);//analog input. client.println("<hr />"); client.println("<br />");

if (buttonpress == 1) { //client.println("<cke:html><cke:body bgcolor=#ffffff>light!</cke:body></cke:html>"); client.print("rozwarcie"); } if (buttonpress == 0) { //client.println("<cke:html><cke:body bgcolor=#000000 text=#ffffff>dark!</cke:body></cke:html>"); client.print("zwarcie"); }

Atrybut href w html u Atrybut href zawiera adres internetowy powiązanej strony The href attribute specifies the URL of the page the link goes to. a /a ograniczają fragment interpretowany jako adres URL w html u nie wszystkie znaki są znakami ascii i niektóre wymagają zamiany na ascii przez poprzedzenie ich backslashem - przykładem jest kombinacja \ client.println("<a href=\"/?lighton\"\">turn On Light</a>"); client.println("<a href=\"/?lightoff\"\">turn Off Light</a><br />");. if(readstring.indexof("?lighton") >0) digitalwrite(2, HIGH); // set pin 6 high else if(readstring.indexof("?lightoff") >0) digitalwrite(2, LOW); // set pin 6 low readstring=""; //clearing string for next read

Transmisja szeregowa UART Moduł UART (Universal Asynchronous Receiver and Transmiter) obsługuje dupleksową, asynchroniczna transmisję danych między procesorem a urządzeniem zewnętrznym. Dane są nadawane (i odbierane) w formacie start-stopowym tzn., każdy znak składa się z: 1 bitu startu: logiczne 0 8 lub 9 bitów danych 1 bitu stopu: logiczna 1. 9-ty bit danych może zostać wykorzystany jako bit parzystości lub jako dodatkowy bit stopu.

Transmisja szeregowa UART rejestr danych Rejestr danych transmisji UART UDR Bit 7 6 5 4 3 2 1 0 Nazwa MSB LSB Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 Rejestr danych jest wykorzystywany do nadawania i odbioru danych. Fizycznie istnieją 2 rejestry danych (transmisja jest dupleksowa), ale występują pod ta samą nazwą.

Transmisja szeregowa UART rejestr statusowy Rejestr statusowy UART USR Bit 7 6 5 4 3 2 1 0 Nazwa RXC TXC UDRE FE OR - - - Odczyt/zapis R R/W R R R R R R Wartość początkowa 0 0 0 0 0 0 0 0 RXC flaga zakończenia odbioru znaku TXC flaga zakończenia nadawania znaku UDRE flaga pustego bufora nadawczego (bufor mieści 2 znaki) FE flaga błędu synchronizacji ramki OR flaga nadpisania znaku

Transmisja szeregowa UART rejestr kontrolny Rejestr kontrolny UART UCR Bit 7 6 5 4 3 2 1 0 Nazwa RXCIE TXCIE UDRIE RXEN TXEN CHR9 RXB8 TXB8 Odczyt/zapis R/W R/W R/W R/W R/W R/W R W Wartość początkowa 0 0 0 0 0 0 1 0 RXCIE maska przerwania odbiorczego TXCIE maska przerwania nadawczego UDRIE maska przerwania pustego bufora nadawczego RXEN włączenie odbiornika TXEN włączenie nadajnika CHR9 włączenie transmisji 9-tego bitu RXB8 9-ty bit odebrany TXB8 9-ty bit gotowy do nadania

Transmisja szeregowa UART prędkość transmisji Rejestr prędkości transmisji UART UBRR Bit 7 6 5 4 3 2 1 0 Nazwa MSB - - - - - - LSB Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 BAUD = f CK 16 ( UBRR + 1) BAUD prędkość w bitach/sek typowe wartości: 1200, 2400, 4800, 9600, 19200 fck częstotliwość zegara mikrokontrolera UBRR wartość obliczona, którą po zaokrągleniu należy wstawić do rejestru UBRR

Transmisja szeregowa UART połączenia Asynchroniczny interfejs UART mikrokontrolera ma dwie linie: nadawczą TXD i odbiorczą RXD. W mikrokontrolerze AT90S8515 linie te znajdują się na porcie D: RXD = PORTD0, TXD = PORTD1. Na liniach mikrokontrolera występują poziomy TTL (5V/0V). Podłączenie interfejsu UART do portu COM komputera PC, gdzie występują poziomy standardu RS-232 (-15V/0V) wymaga zastosowania konwertera zmiany poziomów. Z tego względu na płytce EVB-503 konwerter poziomów napięć został włączony przed wyjściami DB9, na których występują już napięcia standardu RS-232. Połącz wyprowadzenie RXD1 złącza AUX2 z linia PORTD0, a wyprowadzenie TXD1 złącza AUX2 z linia PORTD1.

Transmisja szeregowa UART nadawanie z obserwacją flagi Program główny: //konfiguracja interfejsu UART UBRR =38; UCR = (1<<TXEN); //wysłanie liczby ASCII a UDR = a ; while(! (USR & (1<<TXC))); USR = (1<<TXC); //wysłanie b UDR = b ; while(! (USR & (1<<TXC))); USR = (1<<TXC); //ustalenie prędkości transmisji //włączenie nadajnika //oczekiwanie na ustawienie bitu TXC //wyzerowanie flagi TXC //oczekiwanie na ustawienie bitu TXC //wyzerowanie flagi TXC

Transmisja szeregowa UART nadawanie z przerwaniem W programie głównym dokonuje się konfiguracji parametrów transmisji, odblokowania przerwań i wysłania 1-szego znaku. Kolejne znaki są wysyłane, gdy moduł przerwań zgłosi zakończenie wysyłania poprzedniego znaku. //zmienna globalna char a; procedura przerwania: ISR (UART_TX_vect) {UDR = a++; } program główny: UBRR =38; UCR = (1<<TXCIE) (1<<TXEN); a = a ; UDR = a; sei(); while (1) ; //wysłanie kolejnej liczby //ustalenie prędkości transmisji //włączenie nadajnika, zdjęcie maski nadawczej //wysłanie liczby ASCII a //włączenie przerwań //nic więcej nie rób

Transmisja szeregowa UART odbiór z obserwacją flagi Program główny: //konfiguracja interfejsu UART UBRR =.; UCR = (..); do { while(! (USR & (..)));.. } while(1); //ustalenie prędkości transmisji //włączenie odbiornika //oczekiwanie na ustawienie flagi //odbiór z rejestru UDR //wyświetlenie znaku na LCD

Transmisja szeregowa UART odbiór z przerwaniem W programie głównym dokonuje się konfiguracji parametrów transmisji i odblokowania przerwań Kolejne znaki są odbierane i wyświetlane na LCD, gdy moduł przerwań zgłosi zakończenie odbioru znaku. procedura przerwania: ISR (..) {//odbiór znaku //wyświetlenie znaku} program główny: //inicjacja LCD UBRR =38; UCR = (..) (..); sei(); while (1) ; //ustalenie prędkości transmisji //włączenie odbiornika, zdjęcie maski odbiorczej //włączenie przerwań //nic więcej nie rób

Magistrala 1-wire Magistrala 1-wire składa się z pojedynczej linii. Na magistrali 1-wire jedno urządzenie MASTER nadzoruje pracę jednego lub wielu urządzeń SLAVE. Urządzenie MASTER oraz wszystkie SLAVE są podłączone do magistrali wyjściem tranzystora otwarty dren lub bramką trójstanową. Takie podłączenie umożliwia zwolnienie linii przez każde z urządzeń po zakończeniu transmisji. Magistrala 1-wire wymaga zewnętrznego rezystora podciągającego do zasilania o wartości około 5kΩ. Stanem bezczynnym magistrali jest stan wysoki.

Impuls Resetu i obecności Każdy transfer po magistrali rozpoczyna się od impulsu Resetu nadawanego przez urządzenie MASTER i impulsu obecności, który jest odpowiedzią urządzenia SLAVE. W czasie impulsu Resetu MASTER zwiera magistralę do masy na czas co najmniej 480 µs. Po tym czasie MASTER zwalnia magistralę, która wskutek podciągnięcia rezystorem 5k przechodzi w stan wysoki. SLAVE dokonuje detekcji zbocza narastającego, czeka 15 60 µs, po czym nadaje impuls obecności zwierając magistralę do masy na czas 60 240 µs.

Impuls Resetu i obecności procedura uproszczona Mikrokontrolery nie posiadają interfejsu do magistrali 1-wire. W związku z tym magistralę 1-wire można umieścić na dowolnej linii mikrokontrolera np. 5 linia portu B. Wówczas na liniach portu D można umieścić 8 diod pomocniczych w uruchamianiu programu. Definicja impulsu resetu zawiera opis kształtu impulsu przedstawiony na rysunku (w przykładzie pomijamy odczyt impulsu obecności) void reset (void) { //magistrala 1-wire jako output //magistrala 1-wire w stan wysoki //odczekaj 5us //magistrala w stan niski //odczekaj 500us //magistrala w stan wysoki //odczekaj 500us pomijamy odczyt impulsu obecności }

Impuls Resetu i obecności W tym rozwiniętym przykładzie MASTER nadaje impuls reset i odczytuje impuls obecności void reset (void) { //magistrala 1-wire jako output //magistrala 1-wire w stan wysoki //odczekaj 5us czas nie restrykcyjny //magistrala w stan niski //odczekaj 500us //magistrala w stan wysoki //odczekaj 60us //magistrala jako wejście //podwieszenie wejścia (magistrali) pod zasilanie (wewnetrzne) //odczyt stanu magistrali //if( stan magistrali == HIGH) //SLAVE nieobecny (wyświetl tekst) //else // SLAVE obecny (wyświetl tekst) //odczekaj 500us //magistrala 1-wire jako output //magistrala 1-wire w stan wysoki }

Ramka nadawcza Stany logiczne: 0 i 1 są nadawane w ramkach czasowych. Każda ramka czasowa trwa co najmniej 60 µs, z odstępem między ramkami co najmniej 1µs. Rysunek przedstawia ramki obu stanów logicznych obie ramki rozpoczynają się od zbocza opadającego.

Impulsy stanów logicznych Definicja impulsu stanu logicznego 0 (lewa połowa rysunku z poprzedniego slajdu) void impuls0 (void) { //magistrala 1-wire jako output //magistrala 1-wire w stan wysoki //odczekaj 5us //magistrala w stan niski //odczekaj 80us //magistrala w stan wysoki //odczekaj 10us } Definicja impulsu stanu logicznego 1 (prawa połowa rysunku z poprzedniego slajdu) void impuls1 (void) {//do samodzielnego wypełnienia wg. rysunku }

Procedura nadania bajtu (8 bitów) Bajt nadajemy bit po bicie rozpoczynając od najmłodszego bitu, czyli przez obrót bajtu w prawo void nadaj (char A) { //magistrala 1-wire jako output //magistrala 1-wire w stan wysoki for (..) //8 obrotów pętli dla 8-miu bitów { if (selekcja najmłodszego bitu zmiennej A) ) impuls1(); //impuls logicznej else impuls0(); //impuls logicznego 0. //obrót bajtu w prawo } //sprawdzenie wartości najmłodszego bitu }

Ramka odbiorcza MASTER generuje zbocze opadające i podtrzymuje stan niski co najmniej przez 1 µs, po czym zwalnia magistralę, która wskutek powieszenia przechodzi w stan wysoki. Teraz SLAVE może zewrzeć magistralę do masy (gdy nadaje logiczne 0 ) lub pozostawić ją w stanie wysokim (gdy nadaje logiczną 1). MASTER odczytuje stan magistrali przed upływem 15 µs od rozpoczęcia ramki.

Procedura odbioru bajtu (8 bitów) Bajt odbieramy bit po bicie wsuwając bity przychodzące po magistrali na najstarszą (7-mą) pozycję zmiennej B i obracając zmienną B w prawo char odbierz (void) { for (.) //8 obrotów pętli dla 8-miu bitów { B=B>>1; //obrót bajtu w prawo //magistrala 1-wire jako output //magistrala 1-wire w stan wysoki //5us //magistrala 1-wire w stan niski //5us //magistrala 1-wire jako input //magistrala 1-wire podwieszona do zasilania (wewnętrznie) //10us if (.) //odczyt stanu magistrali B = 0b10000000; //odebrano stan 1 else. //odebrano stan 0 //delay. us } //magistrala 1-wire jako output //magistrala 1-wire w stan wysoki return..; }

Termometr cyfrowy DS18B20 Układ DS18B20 zawiera czujnik temperatury i przetwornik A/C o rozdzielczości 12-sto bitowej, co odpowiada pomiarowi temperatury z krokiem 0.0625 C. Pamięć układu DS18B20 składa się z 8-miu rejestrów, temperatura jest zapisywana na dwóch pierwszych rejestrach: 0-wy rejestr zawiera młodszy bajt pomiaru temperatury, 1-szy rejestr zawiera starszy bajt pomiaru temperatury. Podczas transmisji na magistrali dane są nadawane począwszy od najmłodszego bitu. Rejestr 0-wy jest wysyłany przez DS18B20 jako pierwszy.

Sesja komunikacyjna po magistrali 1-wire z termometrem DS18B20 TRYB URZĄDZENIA MASTER DANE (NAMŁODSZY BIT JAKO 1-SZY) KOMENTARZ TX Impuls resetu Master generuje impuls resetu RX Impuls obecności DS18B20 odpowiada impulsem obecności TX $CC Master wydaje rozkaz pominięcia odczytu pamięci ROM TX $44 Master wydaje rozkaz pomiaru temperatury TX Podciągnięcie linii Master utrzymuje magistralę w stanie wysokim czas pomiaru = 1000ms TX Impuls resetu Master generuje impuls resetu RX Impuls obecności DS18B20 odpowiada impulsem obecności TX $CC Master wydaje rozkaz pominięcia odczytu pamięci ROM TX $BE Master wydaje rozkaz odczytu pamięci RAM urządzenia RX Odczyt 2-ch słów Master odczytuje wynik pomiaru temperatury

Uzupełnienie programu main W programie głównym należy: skonfigurować linię magistrali 1-wire (kierunek linii: output, stan linii: high), skonfigurować 8 diod na porcie D (kierunek linii: output stan linii: high), w nieskończonej pętli wywoływać procedury 1-wire wg. kolejności pokazanej w tabeli na poprzednim slajdzie int main (void) {..//konfiguracje do {.//procedury z tabeli //odbierz bajt LS //odbierz bajt MS //wyświetl bajt LS na diodach } while (1); return 0; }

Rejestr temperatury Rejestr temperatury (LS byte) Bit 7 6 5 4 3 2 1 0 Nazwa 2 3 2 2 2 1 2 0 2-1 2-2 2-3 2-4 Rejestr temperatury (MS byte) Bit 15 14 13 12 11 10 9 8 Nazwa S S S S S 2 6 2 5 2 4 S bity znaku

Odczyt temperatury w rozdzielczości 8-bitowej Wynik pomiaru temperatury jest przekazywany przez termometr w rozdzielczości 12- bitowej na bajtach LS i MS. Ograniczenie rozdzielczości do 8-bitowej ( =1 ) polega na usunięciu bitów: 2-1, 2-2, 2-3, 2-4. W tym celu bajty LS i MS należy odpowiednio obrócić, po czym zsumować je binarnie i uzyskać na bajcie wynikowym następujący układ bitów: 0 2 6 2 5 2 4 2 3 2 2 2 1 2 0 Bajt wynikowy zawiera temperaturę w zapisie binarnym o rozdzielczości 8-bitowej. Przed wyświetleniem na LCD liczbę binarną należy rozłożyć na kolumny (setki, dziesiątki, jedności) i zapisać każdą kolumnę w kodzie ASCII.

Odczyt temperatury w rozdzielczości 12-bitowej Usunięte poprzednio bity części ułamkowych temperatury 2-1, 2-2, 2-3, 2-4 należy zapisać na oddzielnej zmiennej. Rozdzielczość 12-bitowa jest równa 1/16 = 0,0625. Z porównania kolumn liczb w zapisie dwójkowym i dziesiętnym a 16 a 8 4 2 b4 b3 b2 1 = + + + 10000 1000 100 10 4 3 a2 a1 b + 625 10000 + + 1 ( a 4 + 2a3 + 4a2 + 8a1) = (1000b 1 + 100b2 + 10b3 + b 10000 wynika, że kolumnę części dziesiętnych b 1 można obliczyć mnożąc liczbę przez 625, a następnie wyznaczając część całkowitą z podziału przez 1000. Wyznacz kolumny części dziesiętnych, setnych, tysiącznych i dziesięciotysięcznych, każdą z nich przedstaw w kodzie ASCII i wyświetl na LCD. 4 )

Zadania do wykonania 1. Stwórz procedury 1. Resetu i obecności 2. Impulsu logicznej 1 3. Impulsu logicznego 0 4. Zapisu bajtu (8-miu bitów) 5. Odczytu bajtu (8-miu bitów) 2. Przy wykorzystaniu procedur napisz program główny do pomiaru temperatury w nieskończonej pętli Dla uproszczenia można pominąć: Impuls obecności, Bit znaku, zakładając że temperatura jest dodatnia Bity wyniku o rozdzielczości większej niż 8 (wynik można wówczas zapisać na 1 bajcie)

1-wire IButton

Termometr cyfrowy DS18B20 - cechy

DS18B20 obudowy i wyprowadzenia

DS18B20 zasilanie pasożytnicze

DS18B20 zasilanie pasożytnicze

DS18B20 zasilanie zewnętrzne

DS18B20 port 3-stanowy

DS18B20 zasilanie In digital circuits, a high impedance (also known as hi-z, tri-stated, or floating) output is not being driven to any defined logic level by the output circuit. The signal is neither driven to a logical high nor low level; this third condition leads to the description "tri-stated". Such a signal can be seen as an open circuit (or "floating" wire) because connecting it to a low impedance circuit will not affect that circuit; it will instead itself be pulled to the same voltage as the actively driven output.

DS18B20 - schemat

DS18B20 pamięć ROM Transmisja następuje od LSB do MSB ( od prawej do lewej)

DS18B20 pamięci RAM i EEPROM

DS18B20 rejestr konfiguracyjny

DS2430 256-bit 1wire EEPROM Główne sekcje pamięci: - 64-bitowa pamięć ROM (laserowo wypalona) - 256-bitowa pamięć danych EEPROM - 256-bitowy pamięć tymczasowa (pośredniczy przy zapisie i odczycie z EEPROM) - 64-bitowy rejestr aplikacji jednokrotnie programowalny - 64-bitowa pamięć tymczasowa (pośredniczy przy zapisie rejestru aplikacji) - 8-bitowy rejestr statusowy (status rejestru aplikacji: zapisany/nie zapisany) Main memory sections: - 64-bit lasered ROM - 256-bit data memory - 256-bit scratchpad - 64-bit OTP application register (OTP- One Time Programmable) - 64-bit scratchpad - 8-bit status memory

Schemat blokowy

Mapa pamięci

Master musi najpierw wysłać jedną z komend adresowanych do pamięci ROM (Read ROM, Match ROM, Search ROM lub Skip ROM). Po wykonaniu komendy ROM Master może wydawać komendy adresowane do innych pamięci

Pamięć ROM

Komendy adresowane do pamięci ROM

Search ROM Command (F0H) Odczyt numerów identyfikacyjnych urządzeń na magistrali (przy założeniu, że na magistrali jest więcej niż jedno urządzenie) Wszystkie urządzenia ma magistrali mają wyjścia typu otwarty kolektor. Po podłączeniu tych urządzeń do jednej linii (1-wire) stan magistrali jest wynikiem hardwarowej operacji logicznej AND (koniunkcja hardwarowa). Proces rozpoczyna się następująco: - master odczytuje wynik koniunkcji bitów LSB wszystkich urządzeń - master odczytuje negację wyniku koniunkcji bitów LSB wszystkich urządzeń - master zapisuje na magistrali pożądaną wartość bitu LSB tym samym wydaje rozkaz przejścia w stan high-z urządzeniom o niezgodnym bicie LSB itd. do bitu 63 (MSB). W takim procesie master odczytuje numer jednego urządzenia. Następnie urządzenie już odczytane przechodzi w stan high-z, a proces zaczyna się ponownie dla urządzeń o numerach jeszcze nie odczytanych. All devices are open drain and connected to one wire produce a wired AND result. Master issues a 0FH command. Then master: read a bit, reads the complement to the bit, writes the desired value of the bit. All devices that do not match turn to state high-z.

Algorytm zapisu i odczytu pamięci EEPROM

Zapis i odczyt pamięci

CRC Cyclic Redundancy Code - reszta z dzielenia wielomianów Dzielnik i dzielna są traktowane jako ciągi (liczby) binarne, dzielenia następuje wg. zasad arytmetyki binarnej modulo 2, wynik dzielenia jest nieistotny (pomijany), reszta z dzielenia (CRC) jest dopisywana do ciągu przesyłanych danych Odbiornik dzieli otrzymany ciąg z dołączonym CRC przez ten sam wielomian, jeśli wynik dzielenia jest różny od zera, to w transmisji wystąpił błąd. Obliczenia CRC mogą być: stablicowane lub wykonywane na bazie procedur.

Dodawanie i odejmowanie w arytmetyce binarnej modulo dwa (bez przeniesienia) suma różnica 10011011 10011011 +11001010 11001010 01010001 01010001 0 0 = 0 0 1 = 1 1 0 = 1 1 1 = 0 W arytmetyce binarnej modulo 2 suma i różnica są dają identyczny rezultat. Z tego powodu nie można tradycyjnie porównywać liczb pod względem relacji większa/mniejsza. Liczba X jest większa lub równa liczbie Y jeżeli pozycja najstarszego bitu liczby X jest taka sama lub większa niż pozycja najstarszego bitu Y. np. 101 jest mniejsze niż 1010

Dzielenie w arytmetyce binarnej modulo dwa (bez przeniesienia)

DS18B20 wielomian CRC Ciąg danych: 1010101010101010101010 Dzielimy przez wielomian 100110001 W tym celu ciąg danych uzupełniamy o 8 zer 101010101010101010101000000000 100110001 liczymy sumę modulo 2 001100100010101010101000000000 100110001 liczymy sumę modulo 2 11111100110101010101000000000 100110001 liczymy sumę modulo 2 itd. aż do uzyskania 8-bitowej reszty z dzielenia

Nadajnik transmituje bity danych uzupełnione o bity reszty z dzielenia wielomianów CRC8 lub CRC16 CRC 8 =x 8 +x 5 +x 4 +1 100110001 = 0x31 CRC 16 =x 16 +x 15 +x 2 +1 11000000000000101=0x8005 Wybiera się takie wielomiany, dla których rozkład 0 i 1 wielomianu oraz wielokrotności wielomianu nie przypomina rozkładu szumu (równomiernego) Odbiornik dzieli otrzymany ciąg łącznie z bitami reszty CRC przez ten sam wielomian CRC 8 (lub CRC 16 ). Jeżeli reszta z dzielenia =0, ciąg nie został przekłamany.

Generator hardwarowy CRC16 i CRC8

unsigned int crc16(unsigned char c) { unsigned int crc, j; for (j=0; j<8; j++) { if ((crc^(unsigned int) c) & 0x0001) { crc = (crc ^ 0x8005); } else; crc = crc >>1; c = c >> 1; } return crc; } //////////////////////////////////////////////////////////////////////////////////////////////// int main(void) { unsigned char ciag[15]; unsigned int i, oblcrc; ciag[0] = 'H'; ciag[1] = '1';. crc=0; for (i=0; i<12; i++) { oblcrc = crc16(ciag[i]); } return 0; }

Podział pamięci półprzewodnikowych Pamięci półprzewodnikowe sekwencyjne rejestry przesuwające CCD - ze sprzężeniem ładunkowym ulotne zwykłe statyczne dynamiczne (SRAM) (DRAM) równoległe klasyczne (bipol.,unipol.) (unipol.) szeregowe pseudostatyczne (unipol.) (unipol.) nieulotne ROM PROM EPROM (szereg. i równol.) EEPROM (E 2 PROM) (szereg. i równol.) NVRAM (SRAM+EEPROM) FLASH (3 rodzaje) FRAM bipolarne unipolarne u n i p o l a r n e

Charakterystyka pamięci nieulotnych - ROM i EPROM

Charakterystyka pamięci nieulotnych EEPROM i FLASH

Pamięć NV-RAM

Charakterystyka pamięci nieulotnych FRAM

Charakterystyka pamięci ulotnych SRAM

Charakterystyka pamięci ulotnych DRAM

rodzaj rozmiar nieulot- zapis odczyt pobór komórki ność czas [ns] ilość czas [ns] ilość mocy SRAM duży - 25-100 nieogr. 25-100 nieogr. niski DRAM średni - 50-100 nieogr. 30-70 nieogr. wysoki EEPROM średni + 10ms 10 5 60-150 nieogr. średni NVRAM duży + 25-45 nieogr. 25-45 nieogr. średni Flash mały + 5-10µs 10 6 70-150 nieogr. średni FRAM średni + 55-200 10 10-10 14 55-200 10 10-10 14 niski

Zalety pamięci FRAM w stosunku do EEPROM (E 2 PROM) - dostęp 30 razy szybszy - liczba zapisów (przeprogramowań) 1milion razy większa - zużycie energii 200 razy mniejsze - wysoka odporność na pola elektromagnetyczne i promieniowanie gamma - przechowywanie danych 10 lat bez baterii - prostsza konstrukcja jedynie mały kondensator podtrzymujący w razie spadku napięcia zasilającego podczas procesu zapisu

Porównanie pamięci SRAM, FRAM

Zastosowanie pamięci FRAM w systemach wbudowanych: - Authentication chip z szyfrowaniem np.. AES do identyfikacji uprawnionego użytkownika - Custom LSI układ LSI wg. zamówienia - RFID identyfikator drogą radiową

RFID Radio Frequency Identification Układ składa się z czytnika i etykiety (transpondera) Czytnik: nadajnik, odbiornik, dekoder, antena nadawcza i odbiorcza Etykieta: układ scalony bez obudowy z anteną, bez zasilania. Czytnik nadając wytwarza falę elektromagnetyczną. Etykieta po znalezieniu się w polu czytnika gromadzi energię w kondensatorze, po czym wysyła odpowiedź do czytnika. Po wysłaniu odpowiedzi etykieta pozostaje nieczynna przez pewien czas, co umożliwia odczyt wielu transponderów znajdujących się jednocześnie w polu odczytu. częstotliwości pracy: 13,5MHz zasięg około metra 800 900 MHz zasięg kilka metrów

FRAM embedded RFID LSI

Dziękuję za uwagę

Magistrala SPI Magistrala SPI składa się z linii: MOSI Master output Slave input MISO Master input Slave Output SCK Clock SS Slave select (CS Chip Select lub CE Chip Enable) Sygnał taktujący transmisję SCK oraz sygnał wyboru urządzenia Slave jest zawsze wystawiany przez urządzenie Master. Linie MOSI i MISO są wspólne dla wszystkich urządzeń na magistrali, linia SS jest prowadzona do każdego Slave oddzielnie.

Magistrala SPI Transmisja po magistrali jest dookólna każdemu nadawaniu po linii MOSI towarzyszy odbiór po linii MISO. Nie wszystkie transfery niosą informacje, niekiedy mogą być nadawanie dane puste np. same zera.

Fazowanie magistrali SPI Faza sygnału taktującego definiuje zależność pomiędzy zboczami sygnału taktującego, a momentami odbioru (próbkowania) danych wejściowych i nadawania (przesuwania w rejestrze) danych wyjściowych. CPHA=0 pierwsze zbocze sygnału taktującego próbkuje dane wejściowe, drugie zbocze przesuwa dane w rejestrze (dane są próbkowane, a następnie przesuwane i wysyłane) CPHA=1 pierwsze zbocze sygnału taktującego przesuwa dane w rejestrze wyprowadza je z rejestru, drugie zbocze próbkuje dane wejściowe (dane są przesuwane i wysyłane, a następnie próbkowane i wpisywane do rejestru) Polaryzacja i fazowanie przebiegów na magistrali dla bitu CPHA =0 i różnych wartości bitu CPOL.

Fazowanie magistrali SPI Polaryzacja i fazowanie przebiegów na magistrali dla bitu CPHA =1 i różnych wartości bitu CPOL.

Tryby pracy interfejsu SPI Wartości bitów CPOL i CPHA decydują o wyborze jednego z 4-ch trybów pracy interfejsu SPI, oznaczonych jako 0, 1, 2 lub 3. W zakresie polaryzacji i fazowania urządzenie Master musi się dostosować do wymagań Slave podanych w nocie katalogowej tego urządzenia. Zegar czasu rzeczywistego DS1305 pracuje w trybie 1. Tryby pracy interfejsu SPI [1] Zbocze narastające Zbocze opadające Tryb pracy SPI CPOL = 0, CPHA = 0 Próbkowanie Zmiana danych 0 CPOL = 0, CPHA = 1 Zmiana danych Próbkowanie 1 CPOL = 1, CPHA = 0 Zmiana danych Próbkowanie 2 CPOL = 1, CPHA = 1 Próbkowanie Zmiana danych 3

Rejestry interfejsu SPI Rejestr kontrolny interfejsu SPI - SPCR Bit 7 6 5 4 3 2 1 0 Nazwa SPIE SPE DODR MSTR CPOL CPHA SPR1 SPR0 Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 Bit 7 SPIE: maska przerwania interfejsu SPI Bit 6 SPE: włączenie interfejsu Bit 5 DODR: kolejność przesyłu danych: 0 MSB pierwszy, 1 LSB pierwszy Bit 4 MSTR: wybór trybu master/slave Bit 3 CPOL: wybór polaryzacji sygnału taktującego Bit 2 CPHA: wybór fazy próbkowania Bit 1 SPR1, bit 0 SPR0: wybór częstotliwości taktującej (patrz tabela)

Wybór częstotliwości taktującej Należy wybrać dzielnik między częstotliwością interfejsu SPI, a zegarem systemowym.