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.
Magistrala SPI Linie MOSI i MISO sąwspólne dla wszystkich urządzeńna magistrali, linia SS jest prowadzona do każdego Slave oddzielnie.
Magistrala SPI
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.
Tryby pracy interfejsu SPI Bity konfiguracyjne CPOL i CPHA decydują o tym, na którym zboczu impulsu dane na magistrali są stabilne (moment próbkowania danych sample), a na którym następuje ich zmiana setup. Możliwe są 4 kombinacje związane z fazą i polaryzacją impulsu zegarowego Przednie zbocze Impulsu leading edge Tylne zbocze Impulsu trailing edge 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. Master musi dostosowaćtryb pracy do wymagań Slave podanych w nocie katalogowej tego urządzenia.
Fazowanie magistrali SPI CPHA=0
Fazowanie magistrali SPI CPHA=1
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)
Prędkość transmisji na magistrali SPI
Rejestry interfejsu SPI Rejestr statusowy interfejsu SPI - SPSR Bit 7 6 5 4 3 2 1 0 Nazwa SPIF WCOL - - - - - - Odczyt/zapis R R R R R R R R Wartość początkowa 0 0 0 0 0 0 0 0 Bit 7 SPIF: flaga zakończenia transferu 1-go bajtu danych Bit 6 WCOL: flaga kolizji
Rejestry interfejsu SPI Rejestr danych interfejsu SPI - SPDR 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 X X X X X X X X Służy do bajtów danych między jednostką CPU a interfejsem SPI.
Interfejs mikrokontrolera Interfejs SPI mikrokontrolera leży na liniach: SS PORTB, 4 MOSI PORTB, 5 MISO PORTB, 6 SCK PORTB, 7
Transfer po magistrali zapis słowa Stanem bezczynnym linii wyboru (CE lub SS lub CS) jest logiczne 0 i taką wartością należy wysterować tę linie po resecie urządzenia. Master rozpoczyna transfer danych od wybrania urządzenia Slave (podniesienie linii wyboru (CE lub SS lub CS) w stan logicznej 1. Następnie Master generuje 16 impulsów zegarowych. W takt 1-szych 8-miu impulsów Master wysyła na magistrale adres rejestru zegara, dla którego są przeznaczone dane. W takt kolejnych 8-miu impulsów zegara Master wysyła na magistrale 8-mio bitowa daną dla rejestru zegara. Transfer kończy się wyzerowaniem linii wyboru.
Transfer po magistrali odczyt słowa Master rozpoczyna transfer danych od wybrania urządzenia Slave (podniesienie linii wyboru (CE lub SS lub CS) w stan logicznej 1. Następnie Master generuje 16 impulsów zegarowych. W takt 1-szych 8-miu impulsów Master wysyła na magistrale adres rejestru zegara, od którego będzie czytał dane. W takt kolejnych 8-miu impulsów zegara Slave nadaje, a Master odbiera 8-mio bitową daną z rejestru zegara. Transfer kończy się wyzerowaniem linii wyboru.
#include <SPI.h> SPI.begin(); SPI.setDataMode(SPI_MODE0); SPI.setClockDivider(SPI_CLOCK_DIV128); SPCR = (1<<SPE) (1<<MSTR); SPCR &= ~((1<<CPHA) (1<<CPOL)); SPCR = (1<<SPR1); SPI.begin(); SPI.setDataMode() SPI.setClockDivider 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 //static const uint8_t SS = 10; //static const uint8_t MOSI = 11; //static const uint8_t MISO = 12; //static const uint8_t SCK = 13; linia poza interfejsem linia interfejsu linia interfejsu linia interfejsu //konfiguracja programowa linii znajdującej się poza interfejsem pinmode (SS, OUTPUT); digitalwrite(ss,high);
uint8_t spi_transfer(uint8_t address, uint8_t data) { uint8_t o; digitalwrite(ss, HIGH); SPDR = address; while (!(SPSR && (1<<SPIF))); SPDR = data; while (!(SPSR && (1<<SPIF))); o = SPDR; digitalwrite(ss, LOW); return o; } int digitalspiwrite(int address, int value) { digitalwrite(slaveselectpin,high); SPI.transfer(address); int re = SPI.transfer(value); digitalwrite(slaveselectpin,low); return re; }
Transfer po magistrali procedura Ze względu na dookólną transmisję po magistrali jedna procedura obsługuje równocześnie nadawanie i odbiór. Procedura pobiera 1 bajt (typ char) oraz zwraca bajt odczytany. Jeśli celem jest zapis ważny jest bajt pobierany przez procedurę (można zaniechać odczytu). Jeśli celem jest odczyt ważny jest bajt zwracany przez procedurę (bajt pobierany może przenosić same zera). Rozróżnienie między zapisem a odczytem następuje na najstarszym bicie adresu. char transfer (char adres, char dana) { char odebrany; //ustaw linię wyboru urządzenia Slave //podaj do rejestru danych interfejsu adres rejestru zegara //poczekaj, aż interfejs skończy transfer adresu (sygnalizacja flagą SPIF) //podaj do rejestru danych interfejsu daną do zapisania w rejestrze zegara //poczekaj, aż interfejs skończy transfer danej (sygnalizacja flagą SPIF) //wyzeruj linię wyboru //odbierz daną z rejestru danych interfejsu return odebrany; }
Real-time clock DS1305 Zegar czasu rzeczywistego
Typowy schemat operacyjny układu DS1305
Schemat blokowy układu DS1305
Źródła zasilania Backup supply is a non-rechargeable lithium battery Backup supply is a rechargeable battery Battery operate mode
Tricle charger Trckle charger to układ podładowywania baterii podłączonej do punktu Vcc2 ze źródła Vcc1 przez diodę (lub dwie diody) i rezystor ograniczający prąd ładowania. W tym układzie bateria jest stale naładowana do optymalnej wartości energii
Zestawienie rejestrów układu DS1305
Rejestry zegara DS1305 Rejestr kontrolny adres odczytu $0F, adres zapisu $8F Bit 7 6 5 4 3 2 1 0 Nazwa EOSC WP 0 0 0 INTCN AIE1 AIE0 Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Bit 7 EOSC: włączenie/wyłączenie oscylatora Wyzerowanie bitu EOSC rozpoczyna pracę oscylatora. Ustawienie bitu EOSC zatrzymuje pracę oscylatora i DS1305 wchodzi w tryb pracy energooszczędnej. Bit 6 WP: zabezpieczenie przed nieuprawnionym zapisem Przed każdą operacją zapisu do rejestru zegara lub RAM-u bit WP musi zostać wyzerowany. Ustawiony w stan logicznej 1 bit WP zapobiega operacji zapisania do rejestrów, w tym również na pozycje 1, 2 i 7 rejestru kontrolnego. Po resecie stan bitu WP jest nieustalony, dlatego przed operacją zapisu bit WP musi zostać wyzerowany. Bit 2 INTCN: bit kontrolny przerwania alarmu Gdy INTCN=1 działa alarm 0 (sygnalizacja stanem niskim na linii INT0) oraz alarm 1 (sygnalizacja stanem niskim na linii INT1), gdy INTCN=0 działa tylko alarm 0 Bit 1 AIE1: maska alarmu 1 Bit 0 AIE0: maska alarmu 0
Rejestry zegara DS1305 Rejestr statusowy adres odczytu $10 Bit 7 6 5 4 3 2 1 0 Nazwa 0 0 0 0 0 0 IRQF1 IRQF0 Odczyt/zapis R R R R R R R R Wartość początkowa 0 0 0 0 0 0 0 0 Bit 1 IRQF1: flaga przerwania 1 Flaga IRQF1 sygnalizująca alarm 1 Bit 0 IRQF0: flaga przerwania 0 Flaga IRQF0 sygnalizująca alarm 0
Program main wersja podstawowa W programie głównym należy: skonfigurować linię wyboru (kierunek linii: output, stan linii: low), linie interfejsu (MOSI i SCK: output/high, MISO input/podwieszony) skonfigurować 8 diod na porcie D (kierunek linii: output stan linii: high), skonfigurować rejestr kontrolny interfejsu SPI SPCR, skonfigurować rejestr kontrolny zegara (zapisywany pod adresem $8F) w nieskończonej pętli odczytywać rejestr sekund i wyświetlać stan rejestru na diodach int main (void) {..//konfiguracje do { //odczyt rejestru sekund //wyświetlenie stanu rejestru na diodach } while (1); return 0; }
Konfiguracja interfejsu SPI Bity konfiguracji interfejsu znajdują się w rejestrze SPCR. Należy: Włączyć interfejs, Wybrać tryb MASTER, Wybrać prędkość po magistrali SPI. Kierunek przesyłu danych oraz fazowanie i polaryzacja musza być zgodne z wymaganiami urządzenia SLAVE na magistrali. Zegar DS1305 wymaga następujących ustawień: Kierunek przesyłu danych: od MSB do LSB, Tryb pracy magistrali SPI: 1. int main (void) { Konfiguracje linii portów Konfiguracja rejestru SPCR Konfiguracja rejestru kontrolnego zegara DS05 do {.} while (1); return 0; }
Rozwinięcie programu main -1 Wyświetlenie daty i czasu int main (void) {..//konfiguracje w tym inicjacja LCD do { //odczyt rejestru minut //przetworzenie danej BCD to ASCII //wyświetlenie na LCD //odczyt rejestru sekund //przetworzenie danej BCD to ASCII //wyświetlenie na LCD } while (1); return 0; }
Rozwinięcie programu main - 2 Wymuszenie wartości początkowych rejestrów daty i czasu Wstaw wartości początkowe do rejestrów zegara. Zegar powinien startować od aktualnej daty i czasu. int main (void) {..//konfiguracje //zapis wartości początkowej do rejestru lat (procedura pobiera daną w BCD) //zapis wartości początkowej do rejestru.. do { //odczyt rejestru. //przetworzenie danej BCD to ASCII //wyświetlenie na LCD } while (1); return 0; }
Rozwinięcie programu main - 3 Wartości początkowe w kodzie ASCII Napisz procedurę ASCIItobcd(), która dane pobiera liczby w kodzie ASCII, zamienia na BCD i zapisuje rejestrach zegara. char ASCIItobcd (char dzies, char jedn) { char danabcd;... return danabcd; } int main (void) {. danax = ASCIItobcd (.); transfer (adres, danax);. do {..} while (1); return 0; }
Zamiana kodu BCD na kod ASCII W rejestrach zegara dane są zapisywane w formacie BCD (tj. cyfra na każdym półbajcie). Jest to zapis identyczny z szesnastkowym, ale tylko w zakresie cyfr od 0 do 9. Etapy przetwarzania BCD to ASCII: Wydzielenie półbajtów liczby 8-bitowej Obrót starszego pół-bajtu o 4 pozycje binarne w prawo Dodanie wartości 48 do każdego pół-bajtu char st, ml, a; st = a & ; st = st >>4; st = st +48; ml = a &.... //wydzielenie 4-ch starszych bitów (cyfra BCD) //cyfra w postaci BIN //zamiana BIN to ASCII // wydzielenie 4-ch młodszych bitów (cyfra BCD) //zamiana BIN to ASCII