Wojciech Koń – Mikrokontrolery – interfejsy szeregowe
Transkrypt
Wojciech Koń – Mikrokontrolery – interfejsy szeregowe
Wojciech KOŃ – IV rok Koło Naukowe Techniki Cyfrowej dr inŜ. Wojciech Mysiński – opiekun naukowy MICROCONTROLLERS – SERIAL INTERFACE MIKROKONTROLERY – INTERFEJSY SZEREGOWE Keywords: serial interface, serial transmission, USART, SPI, TWI, I2C, 1WIRE. Słowa kluczowe: interfejsy szeregowe, transmisja szeregowa, USART, SPI, TWI, I2C, 1WIRE. 1. WPROWADZENIE W 1969 roku japońska firma Busicom zleciła firmie Intel wykonanie zestawu 8 chipów, które miały wchodzić w skład programowalnego kalkulatora. Odpowiedzialnym za ten projekt był inŜynier Ted Hoff. Wymyślił idee centralnej jednostki obliczeniowej wspomaganej układami zewnętrznymi. Tak kalkulator zawierający 8 układów scalonych zamienił się w uniwersalny układ, który był na tyle uniwersalny, Ŝe mógł nie tylko wykonać wszystkie zadania kalkulatora, lecz równieŜ mógł znaleźć zastosowanie w innych konstrukcjach. Tak więc jesienią 1971 roku powstał i4004 – pierwszy mikroprocesor. Częstotliwość taktowania wynosiła 108kHz. Był w stanie wykonywać 60000 operacji na sekundę. W styczniu 1972 roku pojawił się następca – i8008. Posiadał juŜ 8 bitową magistralę. Taktowanie podniesiono do 200kHz. Powstawały coraz nowsze, coraz szybsze procesory. Jednak istniała grupa producentów, która chciała wykorzystać zalety mikroprocesorów w sprzęcie gospodarstwa domowego, RTV, AGD czy motoryzacji. Jednak sam mikroprocesor na niewiele się przydaje. Konieczne jest dodanie zegara, pamięci (RAM, ROM) układów we/wy. Jednak trudno sobie wyobrazić, aby w mikserze umieszczać osobno procesor pamięć układy we/wy. Powstał pomysł, aby umieścić wszystko w jednej kości. Tak powstał pierwszy mikrokontroler (mikrokomputer jednoukładowy). Niska cena spowodowała, Ŝe zaczął być stosowany w coraz większej liczbie urządzeń. Z czasem zaczęły powstawać mikrokontrolery mające zastosowanie w konkretnych dziedzinach, posiadające wyspecjalizowane właściwości. Dzisiaj trudno wyobrazić sobie mikroprocesor bez szeregu urządzeń umoŜliwiających komunikowanie się z otoczeniem. Liczba wyprowadzeń ciągle rosła, rosła równieŜ liczba urządzeń do obsłuŜenia. Dlatego bardzo waŜne stały się interfejsy szeregowe. Wykorzystywane są wtedy, gdy zachodzi konieczność przesłania danych do innych systemów. Nad transmisją równoległą mają niezaprzeczalną zaletę: przy wykorzystaniu tylko kilku linii umoŜliwiają sprawną komunikację. W transmisji równoległej pojawiają się problemy przy przesyłaniu na większe odległości. Zaczyna pojawiać się problem przesłuchów między liniami. Konieczne jest więc dodatkowe ekranowanie lub/i zmniejszenie prędkości transmisji. Istnieje wiele interfejsów szeregowych. W pracy omówię 4 najczęściej stosowane: USART, SPI, I2C oraz 1wire. Przedstawię krótką charakterystykę kaŜdego z tych interfejsów oraz omówię ich zalety i wady. Transmisja w kaŜdym z tych interfejsów moŜe być prowadzona przy obsłudze sprzętowej lub programowej. 2. INTERFEJS USART Interfejs USART (Universal Synchronous and Asynchronous serial Receiver and Transmitter) stanowi rozszerzenie interfejsu UART. W odróŜnieniu od poprzedniej wersji umoŜliwia prowadzenie transmisji synchronicznej. Interfejs UART/USART stosowany jest do prowadzenia prostych transmisji szeregowych pomiędzy dwoma lub więcej urządzeniami. Interfejs moŜe być wykorzystany do obsługi RS232 i RS485. Najczęściej stosowany jest do połączenia mikrokontrolera z komputerem PC (port com). RXD TXD XCK RXD TXD XCK Rys.2.1 Idea transmisji USART W zaleŜności od trybu transmisja moŜe być prowadzona z wykorzystaniem 1,2 lub 3 linii: • TXD • RXD • XCK Uniwersalny moduł do transmisji synchronicznej i asynchronicznej – USART moŜe być skonfigurowany do pracy w trybach: • tryb asynchroniczny • tryb synchroniczny Maksymalną prędkość, jaką moŜna osiągnąć dla trybu asynchronicznego to 625kbps. Tryb synchroniczny umoŜliwiają transmisję dochodzącą nawet do 5Mbps. Zdecydowanie najczęściej wykorzystywana jest transmisja asynchroniczna. MoŜna ją zrealizować przy uŜyciu nawet jednej linii. W transmisji synchronicznej moŜe okazać się konieczna dodatkowa linia synchronizacji. Jednak tu nie ma reguły. RóŜni producenci stosują róŜne rozwiązania. W procesorach AVR w trybie synchronicznym wymagana jest dodatkowa linia XCK, w procesorach PIC linia RX pełni rolę linii danych a linia TX linii zegarowej. W tym przypadku transmisja jest typu half duplex. Wysyłanie lub odbieranie bajtu jest realizowane sprzętowo przez układy wbudowane w mikrokontroler. Zakończenie nadawania lub odbierania moŜe generować przerwanie. Dzisiejsze mikrokontrolery posiadają do kilku sprzętowych układów wspomagających transmisję. Jednak w bardzo prosty sposób moŜe być zrealizowana w sposób programowy. 2.1 RAMKA TRANSMISYJNA Rejestry konfiguracyjne mikrokontrolerów umoŜliwiają dość swobodę ustalenie formatu przesyłanych danych. Przesyłane słowo moŜe składać się z 5,6,7,8 lub 9 bitów. Jednak przy projektowaniu systemu transmisji przy wykorzystaniu USART naleŜy uwzględnić specyfikację danego mikrokontrolera. Nie kaŜdy posiada moŜliwość wysyłania 5,6,7 bitowych słów. Niemniej jednak moŜna określić szablon ramki transmisyjnej zgodny dla wszystkich mikrokontrolerów. a (LSB) b b b b b b b b (MSB) c d d Rys.2.2 Format ramki transmisji UART a – bit startu b – bity przesyłanego bajtu c – bit parzystości d – 1 lub 2 bit stopu Transmisja rozpoczyna się od wysłania bitu startu, który zawsze jest równy 0. Następnie przesyłane są kolejne bity bajtu – najpierw najmłodsze bity potem najstarsze (przy czym bajt moŜe mieć 5,6,7,8 lub 9 bitów). W zaleŜności od ustawienia moŜe być nadawany bit parzystości (nie wszystkie mikrokontrolery posiadają sprzętową generację tego bitu) oraz 1 lub 2 bity stopu. Stan aktywny na linii to stan 0V. W stanie nieaktywnym utrzymywany jest stan wysoki. Aby transmisja była moŜliwa konieczne jest ustawienie tej samej prędkości w nadajniku i odbiorniku. Prędkość transmisji zaleŜy od rejestrów konfiguracyjnych mikrokontrolerów. Silnie zaleŜy ona od częstotliwości taktowania mikrokontrolera i jest zawsze jej podwielokrotnością. UBRR = f sys 16 ⋅ BAUD −1 (1) Wzór (1) określa wartość rejestru UBRR dla częstotliwości taktowania mikrokontrolera równej fsys i prędkości transmisji BAUD. Nie zawsze moŜliwe jest dobranie całkowitej wartości UBRR. Prędkość posiada odchyłkę, co dla skrajnych przypadków moŜe powodować do błędów transmisji. W praktyce bardzo często stosuje się częstotliwość 11,0592MHz lub 14,7456MHz. UmoŜliwia ona osiągnięcie typowych prędkości transmisji. Tabela 2.1 Wartości rejestru UBRR dla przykładowych częstotliwości (dla mikrokontrolera AVR Atmega8).UART w trybie asynchronicznym BAUD [bps] 2400 4800 9600 14,4k 19,2k 28,8k 38,4k 57,6k 76,8k 115,2k 230,4k 250k fsys = 2MHz UBRR 51 25 12 8 6 3 2 1 1 0 - Błąd [%] 0,2 0,2 0,2 -3,5 -7,0 8,5 8,5 8,5 -18,6 8,5 - UBRR 287 143 71 47 35 23 17 11 8 5 2 2 fsys = 11,0592MHz Błąd [%] 0 0 0 0 0 0 0 0 0 0 0 -7,8 Dla niektórych częstotliwości nie jest moŜliwe dobranie wartości rejestrów konfiguracyjnych tak, aby wartość była całkowita. Dla częstotliwości 2MHz i prędkości transmisji równej 78,6kbps błąd wynosi juŜ 18,6%. Jest to wartość niedopuszczalna. 3. INTERFEJS SPI Interfejs SPI (Serial Peripheral Interface) - szeregowy interfejs urządzeń peryferyjnych, umoŜliwia jednoczesną synchroniczną wymianę danych 8-bitowych. Najczęściej stosowany jest do komunikacji między mikroprocesorami. Prędkość transmisji dochodzi do 15Mbps. Standard SPI gwarantuje poprawną szybkość transmisji do 2,1 Mb/s. Komunikacja odbywa się synchronicznie za pomocą 4 linii: MOSI MISO SCK CS (SDO) (SDI) (CLK) (SS) - (Master Output Slave Input) – szeregowe wyjście danych - (Master Input Slave Output) – szeregowe wejście danych - (Serial Clock) – sygnał zegarowy (taktujący) - (Slave Select) – aktywacja wybranego układu peryferyjnego Rys.3.1 Idea transmisji SPI Konfiguracja SPI: - Aby transmisja była moŜliwa jedno urządzenie musi być skonfigurowane jako master, pozostałe jako slave. Sygnał zegarowy zawsze jest generowany przez master. Dlatego linia SCK powinna być ustawiona jako wyście dla master oraz jako wejście dla slave. - NaleŜy ustawić polaryzację linii SCK w stanie nieaktywności urządzeń - NaleŜy ustawić fazę zegara, w której odbywa się przepisywanie danych wejściowych (środek lub koniec waŜności danych). - NaleŜy ustawić aktywne zbocze zegara SCK. Dane wystawiane są na wyjście przy rosnącym lub malejącym zboczy SCK - Dla master naleŜy ustawić częstotliwość taktowania Gdy do magistrali dołączony jest tylko jeden układ slave, to wejście SS układu slave naleŜy podłączyć stale do masy, natomiast wyjście SS układu master naleŜy podłączyć do plusa zasilania. W przypadku, gdy jest kilka układów slave wejścia SS są sterowane przez dodatkowe wyprowadzenia portu układu master. MOSI MOSI MISO MISO SCK SCK SS1 Slave 1 SS MOSI MISO Master Slave 2 SCK SS2 SS MOSI MISO SCK SS3 SS Rys. 3.2 Tryb multislave Slave 3 Całością steruje układ master. To on generuje sygnał CLK i to on rozpoczyna wymianę danych. Takie rozwiązanie ma jednak wadę: nie moŜna skorzystać z przerwać. Jakakolwiek zmiana stanu urządzenia master moŜe być wykryta tylko poprzez programowe sprawdzenie zawartości rejestru slave. Wymiana danych z Slave1 następuje po ustawieniu linii SS1 w stanie niskim. Po tym dana 8 bitowa jest przesyłana z układu Master do Slave1. Po zakończeniu transmisji UWAGA: Niektóre mikrokontrolery nie mają moŜliwości zmiany, który bit (MSB czy LSB) ma być przesyłany jako pierwszy. W takim przypadku konieczna jest programowa zamiana bitów. Taka sytuacja występuje w mikrokontrolerach PIC. Mikrokontrolery AVR posiadają bity konfiguracyjne umoŜliwiające określenie porządku transmisji. Niekiedy uŜycie interfejsu SPI uniemoŜliwia korzystanie z innych funkcji mikrokontrolera. W mikrokontrolerach PIC interfejs SPI i I2C moŜe być uŜywany naprzemiennie. Tak więc włączenie trybu SPI uniemoŜliwia obsługi urządzeń SPI. Z kolei w niektórych mikrokontrolerach moŜliwe jest ustawienie interfejsu USART do pracy w trybie Master SPI. Jedną z odmian interfejsu SPI jest interfejs Microwire opracowany przez firmę National Semiconductor. 4. INTERFEJS I2C (TWI) Interfejs I2C (I2C,IIC Inter-Integrated Circuit Bus) został opracowany w firmie Phillips w 1981 roku. Jest to interfejs synchroniczny. UmoŜliwia połączenie wielu urządzeń do dwuprzewodowej magistrali. MoŜliwe jest podłączenie kilku urządzeń typu master w jednej linii. Vcc Rp Master1 Master SDA1SCL Slave1 Slave1 Slave 2 Slave2 Slave 3 Slave3 SDA SCL SDA SCL SDA SCL SDA SDA SDA Rp Master2 Master SDA2SCL SDA SCL Rys. 4.1. Magistrala I2C W mikrokontrolerach spotykany jest równieŜ interfejs TWI (Two Wire Interface), który jest zgodny z interfejsem I2C. Pozwala on na zaadresowanie do 128 urządzeń podłączonych do jednej magistrali. Nowsze specyfikacje I2C umoŜliwiają adresowanie 10 bitowe, co znacznie zwiększa liczbę obsługiwanych urządzeń. Transmisja odbywa się przy pomocy dwu linii dwukierunkowych: • SDA – linia danych • SCL – linia zegarowa Urządzenia są sterowane przez wyjścia OC tak więc konieczne są zewnętrzne rezystory podciągające. Niektóre mikrokontrolery posiadają porty z moŜliwością włączenia rezystorów podciągających. W takim przypadku zewnętrzne elementy nie są potrzebne. Wartość rezystancji zaleŜy od długości połączeń, liczby układów i częstotliwości pracy. Zawiera się w granicach od 1kΩ do 10 kΩ. 4.1. PRZEBIEG TRANSMISJI Transmisję rozpoczyna i kończy układ nadrzędny (master). Inicjalizacja transmisji następuje po nadaniu sygnału START. Następnie master wysyła na magistralę adres urządzenia, z którym chce się komunikować. Po wymianie danych układ master generuje sygnał STOP. W przypadku, gdy na wspólnej magistrali pracuje kilka układów nadrzędnych stosuję się R-START (Repeat Start Condition). Nadanie sygnału R-START powoduje ponowną inicjalizację transmisji bez kończenia poprzedniej. Dzięki temu inny układ master nie spowoduję przejęcia panowania nad magistralą. KaŜdorazowe wysłanie danych powoduje generowanie potwierdzenia ACK przez układ slave. Układ master po wysłaniu adresu urządzenia oczekuję na odpowiedź. Linia SDA ustawiana jest w stanie wysokim i generowany jest impuls na linii SCL. Pojawienie się stanu niskiego na linii SDA informuje układ master, Ŝe slave jest gotowy do transmisji. Przesyłanie bitów następuje przy pojawieniu się stanu wysokiego na linii SCL. PoniŜsze rysunki przedstawiają przebiegi czasowe na liniach SDA i SCL przy przesyłaniu danych: START STOP bit „1” SDA SCL Rys. 4.2. Zmiany na liniach SDA i SCL przy przesyłaniu danych bit „0” Specyfikacja I2C określa maksymalną długość połączeń równą 10cm. Jednak w wielu przypadkach zachodzi konieczność prowadzenia dłuŜszych przewodów. Porty wyjściowe posiadają duŜą rezystancję. Z tego powodu nawet małe prądy indukowane w przewodach będą powodować zmiany napięcia, które mogą zakłócać transmisję danych. Przy odległościach dłuŜszych niŜ 10cm naleŜy zastosować specjalne prowadzenie linii SCL i SDA i/lub zastosować ekranowanie. SDA GND SCL SDA GND SCL Rys. 4.3. Prowadzenie przewodów magistrali I2C 5. INTERFEJS 1WIRE Interfejs 1WIRE (One Wire) został opracowany przez firmę Dallas Semiconductor (obecnie Maxim). Transmisja danych dokonywana jest przy uŜyciu tylko jednej linii. Dane przesyłane są w obydwu kierunkach. DuŜym udogodnieniem interfejsu 1WIRE jest moŜliwość zasilania urządzeń wprost z linii danych. Przez co do komunikacji nawet z odległymi urządzeniami wystarczą dwa przewody (jeden to linia danych, drugi to masa). Wymianą danych steruje układ master. To on rozpoczyna transmisję, wybiera adres urządzenia, z którym się chce komunikować, i on ustala prędkość transmisji. Wymiana danych moŜe następować w dwóch trybach szybkości: • 16,3kbps – tryb standard • 115kbps – tryb overdrive W odróŜnieniu od pozostałych interfejsów szybkość transmisji nie musi być stała. Standard nie ogranicza od dołu prędkości transmisji. Jedyne ograniczenie dotyczy czasów trwania stanów „0” i „1”. Tak więc moŜna przeprowadzić część transmisji z jedną prędkością moŜe nastąpić przerwa w transmisji, a następnie dokończyć transmisję w dowolną prędkością. Vcc Rp Master Master 1 Slave1 Slave2 Slave3 SDA SDA SDA Slave1 Slave 2 1WIRE GND Rys. 4.1. Magistrala 1WIRE Slave 3 5.1. PRZEBIEG TRANSMISJI W stanie spoczynku linia danych jest w stanie wysokim. Jedynke logiczną utrzymuję rezystor podciągający. KaŜde pojawienie się stanu niskiego powoduje inicjację przesyłania bitu. Dane przesyłane są jako słowa 8bitowe. Najpierw transmitowany jest bit LSB. Brak linii synchronizacji oraz praktycznie dowolna prędkość transmisji (nie przekraczająca 115kbps) powoduje, Ŝe transmisja posiada pewne ograniczenia. Dotyczą one czasów trwania „0” oraz „1”. O tym czy przesyłane jest „0” czy „1” świadczy czas trwania stanu niskiego na linii 1WIRE. ZaleŜności czasowe przy transmisji danych przedstawia poniŜszy rysunek: RESET 480us 480us 60us 60us bit „1” bit „0” 60us 60..120us 11us Rys.5.2. ZaleŜności czasowe magistrali 1WIRE Resetowanie urządzeń podłączonych do magistrali 1WIRE jest rozpoczynane przez układ master. Układ master generuje impuls zerujący (niski stan na magistrali) przez okres ok. 480us. Po tym czasie następuje ustawienie stanu wysokiego. JeŜeli do magistrali podłączony jest slave to odpowiada on po czasie mniejszym niŜ 65us ustawiając stan niski na magistrali. Czas trwania tego stanu wynosi od 15 do 60 us. Wysyłanie „0” do slave polega na ustawieniu na magistrali stanu niskiego przez czas 60..120us. Po tym czasie na magistrali musi pojawić się stan wysoki. Gdy czas trwania „0” będzie dłuŜszy niŜ 480us, to zostanie on zinterpretowany jako reset magistrali. 7. PODSUMOWANIE Tabela 7.1 przedstawia porównanie opisanych wcześniej interfejsów. Niektóre parametry są osiągalne przy pewnych ograniczeniach, których nie ma wyszczególnionych w tabeli. Dotyczy to np. maksymalnej długości przewodów magistrali i maksymalnej prędkości przesyłu danych. Dlatego teŜ, porównując poszczególne interfejsy naleŜy zwrócić uwagę na ten fakt. Podane wartości są orientacyjne. ZaleŜą bowiem od konkretnej aplikacji (mikrokontrolera, częstotliwości zegara systemowego, technologii wykonania). Transmisja szeregowa ma wiele niepodwaŜalnych zalet takich jak mała liczba połączeń, mała liczba elementów zewnętrznych. Dzięki temu w tani sposób moŜna obsłuŜyć bardzo wiele urządzeń. Niestety prostota połączeń jest okupiona zdecydowanie większą złoŜonością programu obsługi transmisji. Niemniej wspieranie sprzętowe, jaką oferują współczesne mikrokontrolery powoduje, Ŝe stosowanie urządzeń komunikujących się przy pomocy magistrali szeregowej staje się łatwe w implementacji. Bogactwo interfejsów, róŜne rozwiązania stosowane przez producentów zmusza jednak do dokładnego zapoznania się z ograniczeniami, lub specjalnymi rozwiązaniami danego interfejsu. Tabela 7.1 Porównanie interfejsów szeregowych Nazwa Max prędkość interfejsu przesyłu danych Maksymalna długość połączeń Liczba linii Tryb masterslave Adresowanie urządzeń Rezystory pull up Firma I2C 3,4 Mb/s 10cm (1) 2 + + + Phillips USART 5Mb/s 1200m (2) 2 (3) - - (3) - Gordon Bell SPI 15Mb/s 30cm 4 (3) + - - Motorola 1wire 115,2kb/s 750m 1 + + + Dallas/ Maxim (1) – przy dłuŜszych połączeniach wymagane jest specjalne prowadzenie ścieŜek oraz ekranowanie. MoŜna osiągnąć długość do 2m – dla standardu RS485 (3) – istnieje moŜliwość pracy w trybie adresowania (2) LITERATURA [1] J.Bogusz: Lokalne interfejsy szeregowe w systemach cyfrowych. btc, Warszawa 2004 [2] W. Nawrocki: Rozproszone systemy pomiarowe. WKŁ, Warszawa 2006 [3] T. Jabłoński, K. Pławsiuk: Programowanie mikrokontrolerów PIC w języku C. btc, Warszawa 2005 [4] S. Pietraszek: Mikroprocesory jednoukładowe PIC. Helion, Gliwice 2002 [5] R. Baranowski: Mikrokontrolery AVR Atmega w praktyce. btc, Warszawa 2006-04-20 [6] M. Wiązania: Programowanie mikrokontrolerów AVR w języku Bascom. btc, Warszawa 2005 [7] Strona internetowa: http://www.embedded.com DODATEK A. PRZYKŁADOWE PROGRAMY OBSŁUGI INTERFEJSÓW INTERFEJS UART (PROCESOR ATMEGA8) void RS_init(void) { //ustawianie predkosci transmisji UBRRH = (unsigned char) (UBRR_BAUD>>8); UBRRL = (unsigned char) UBRR_BAUD; //wlaczenie toru nadawczego i odbiorczego, zezwolenie na //przerwania od odbiornika UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE); //8 bitowa transmisja z bitem startu, bez bitu parzystosci UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); } void RS_wyslij(unsigned char data) { while ( !( UCSRA & (1<<UDRE)) ); UDR = data; //czekaj az nadajnik // bedzie gotowy //wyslij wartosc na rs } SIGNAL (SIG_UART_RECV) { while ( !(UCSRA & (1<<RXC)) ); //odebrana wartosc w //rejestrze UDR } INTERFEJS 1WIRE (PROCESOR PIC18F4620) unsigned char reset_1w(void){ unsigned char presence; D_PIN = 0; D_TRIS = 0; delay_10us(50); D_TRIS = 1; delay_10us(6); presence = D_PIN; delay_10us(50); return(presence); } unsigned char read_1w(void) { unsigned char x,dana = 0; for (x=0;x<8;x++) { D_PIN = 0; D_TRIS = 0; delay_us(2); D_TRIS = 1; delay_us(2); if (D_PIN==1) dana|=0x01<<x; delay_10us(7); } return(dana); } void write_1w(unsigned char dana) { unsigned char x,temp; for (x=0;x<8;x++) { temp = dana>>x; temp &= 0x01; if(temp==1) { D_PIN = 0; D_TRIS = 0; delay_10us(1); D_TRIS = 1; delay_10us(6); } else { D_PIN = 0; D_TRIS = 0; delay_10us(7); D_TRIS = 1; } } } Przykładowy projekt miernika temperatury z wykorzystaniem interfejsu 1WIRE LCD1 R1 PULLUP DS1 Vdd DQ GND 3 U1 2 1 2 6 7 3 4 15 16 1 DS18B20 TEMP=12.0 RA0/AN0 RA1/AN1/LVDIN RA2/AN2/VREFRA3/AN3/VREF+ RA4/T0CKI RA5/MCLR/VPP RA6/OSC2/CLKO RA7/OSC1/CLKI RB0/AN4/INT 0 RB1/AN5/TX/CK/INT1 RB2/P1B/INT2 RB3/ECCP1/P1A RB4/AN6/RX/DT/KBI0 RB5/PGM/KBI1 RB6/PGC/T1OSO/T1CKI/P1C/KBI2 RB7/PGD/T1OSI/P1D/KBI3 8 9 17 18 10 11 12 13 PIC18F1220 Rys. A.1. Schemat ideowy miernika temperatury Kod programu: #include #include #include #include <pic18.h> "delay.h" "lcd.h" "1wire.h" unsigned unsigned unsigned unsigned unsigned char long char char long temp1; temp2; uklad; x,y,x; m; void main(void) { OSCTUNE=0b00011111; OSCCON=0b01111111; D0 D1 D2 D3 D4 D5 D6 D7 7 8 9 10 11 12 13 14 RS RW E 4 5 6 1 2 3 VSS VDD VEE LM032L PORTA=0b00000000; TRISA=0b00000000; ADCON1=0b11111111; //wylacz przetworniki A/C PORTB=0b00000000; TRISB=0b00000000; //wyjscia cyfrowe lcd_init(); delay_ms(1); lcd_clear(); delay_ms(1); cursor_off(); def_char(); gotoxy(0,1); delay_ms(1); gotoxy(0,1); lcd_text("Miernik temperatury"); gotoxy(0,2); lcd_text("xxxxx"); while(1) { uklad = reset_1w(); gotoxy(0,2); if (uklad==1) lcd_text("Brak uk│adu"); else { write_1w(0xCC); write_1w(0x44); delay(1); reset_1w(); write_1w(0xCC); write_1w(0xBE); temp1 = read_1w(); temp2 = read_1w(); x x y y = temp1 & 0b11110000; = x>>4; = temp2<<4; +=x; lcd_text("T1="); lcd_dec(y); x = temp1 & 0b00001111; m = 625*x; lcd_char('.'); lcd_char((m %10000)/1000+48); lcd_char(223); lcd_text("C"); } } } INTERFEJS SPI (PROCESOR PIC18F4620) void spi_slave(void) { TRISC = 0b00011000; //ustawienie portow SSPSTAT = 0b00000000; //konfiguracja SPI jako slave SSPCON1 = 0b00100100; SSPIE = 1; //wlaczenie przerwania } void spi_master(void) { PORTC=0b01000111; TRISC=0b00010000; SSPSTAT = 0b10000000; SSPCON1 = 0b00100001; } //konfiguracja SPI jako master unsigned char komunikacja(unsigned char dataout) { unsigned char datain; SSPIF = 0; SSPBUF = dataout; while (!SSPIF); datain = SSPBUF; return(datain); } INTERFEJS TWI (PROCESOR ATMEGA32) void twi_init(void) { //czestotliwosc 100kbps TWBR = 0x42; TWCR = (1<<TWEN); } void twi_start(void) { TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); while (!(TWCR & (1<<TWINT))); } char twi_odczytaj(void) { TWCR = (1<<TWEN)|(1<<TWINT); while (!(TWCR & (1<<TWINT)));//czekaj na odbior return TWDR; } void twi_zapisz(char dana) { TWDR = dana; TWCR = (1<<TWINT)|(1<<TWEN); //czekaj na potwierdzenie while (!(TWCR & (1<<TWINT))); } void twi_stop(void) { TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); }