on wwwl
listing l
h Fun<c}a sprarfdtająca, czy jest pocłaczona zewnętrzna panięć, // wynik w g_exisn, 1-nie, O-tak vcid spr_czy_jest|void)
(
ułntat dana;
// zapis próbnego bajta Clio;
i2c_atarto;
i2c_send(.60) ; i2c_3«n<J( .1); i2c_send(.00);
J2c__otopC i aoiO;
delaylODuaG•ICO) ; //niezbędne opóźnienie // odczyt próbnego bajta cli O ;
i2c_otart()t i2c_eoni(160); i2c_aeni(il); i2c_8tart()j i2c_aend <161) ; dana ■ 12c_get<I2C_N*CK)
#•i ();
//bajt acresowy pamięci, zapis
//adres w pamięci gdzie ma być zapisana dana //capia liczby 100 pod cdiea 11
//bajt acresowy pamięci zapis
//adres v pamięci, spod której ma być odczytana dana //ponowna rozpoczęcie transmisji //bajt adresowy pamięci, ©dozy:
//pobranie danej
1 i
1 f (dana»l 00) g ftxtsr.-0;
//wMt-ępn# załn*.*me, 4e klucz nie jest podłączony //jeśli jest podłączony, to wyzeru: zmienna
Listing 2 | |
// funkcja odczytu danych z zewn eeprom do tao | |
udcs_sew_eeprom<u.nl8_t *Cab' | |
dlO# | |
i2c_«c«rt{) i | |
i2:_»end<160),- |
//bajt acresowy pamięci sapią |
i2c_send <0); |
//adres v pamięci, spod któroj ma być odczytana dane |
i2e_atart <); |
//ponowne rozpoczęcie tranomioji |
i2c_30nd1161); |
//bajt adresowy pamięci, odczyt |
foc (uint£_t n-0f n<1ł n-t+) ( |
tab(n) - i2c_got (t2C_/.CK) ) / //pobranie danych do tafc |
tabP) - i2o_got U2C_NACK); |
//pobranie ostacn.e; oanaj baz potwierdzania |
i2o_«top O; | |
■•u:; i |
Listing J
// Zapis tablicy tabl do wewnętrznej pamięci EEPROM // paramatry funkcji: acres gdzie na być zapisana dana i zmienna for(uint8_t n-0; n<8; n++) eeprom_write_oyte (n, g_tabl|ni);
jest
(...:
// odczyt canych t wewnętrznej pamięci eeprom do tablicy tab2 // parametr funkcji, adres skąd na być odczytana dana for(uint8_t n“0; n<8; n++) g_zab2|n] * eepron_read_byte(n: ;
me można
wybranie SI zostanie zasygnalizowane dodatkowo pojedynczym dźwiękiem brzęczka i powoduje losowanie dwóch kolejnych bajtów kodu, dlatego trzeba go nacisnąć 4 razy. Po tej operacji. Dl zaświeci się na stałe, informując, że kontroler ma zapisany klucz. Natomiast dioda D3 zmieni kolor na zielony, wskazując, że podłączony klucz jest rozpoznany. Sposób losowania kodu może wydawać się pozornie trochę dziwny. Chodzi o to, żeby uzyskane liczby były zupełnie przypadkowe Mianowicie w mikroprocesorze cały czas pracuje szes-nastohitowy (dwubajtowy) Timerl. Po prostu po kolejnym naciskaniu SI odczytywany jest przypadkowy stan Timeral. Odczytane liczby są potem umieszczane w kluczu i w wewnętrznym EEPROM-ie mikroprocesora.
Zwykle jeden klucz to za mało. Ale jak na zamek przystało, można do niego ..dorobić” dowolną liczbę kluczy Aby to zrobić, należy podłączyć klucz do układu i nacisnąć S2. Kod zapisany w wewnętrznej pamięci EEPROM mikrokontrolera zostanie skopiowany do klucza. Na potwierdzenie tego brzęczek wyda z siebie podwójny dźwięk
Gdy w kontrolerze zapisany klucz, wylosować nowego kodu, dopóki nic usunie się poprzedniego. Do usuwania klucza z kontrolera służy S3. Po naciśnięciu przycisku czerwona dioda D4 na chwilę się zaświeci, brzęczek zapiszczy potrójnie a niebieska Dl zgaśnie. Jeśli kontroler nic ma zapisanego klucza, nie reaguje na naciskanie S3.
Program procesora napisałem w języku C. Do podstawowej obsługi interfejsu I2C wykorzystałem procedury zamieszczone w kursie C autorstwa Radosława Koppla, więc nie będę ich omawiał. Powiem
0 kilku prostych fragmentach programu zawierającego już gotowe funkcje.
Rozpoznawanie podłączonego klucza sprowadza się do odczytu kodu klucza
1 kodu umieszczonego w EEPROM-ie mikroprocesora
i weryfikacji zgodności tych kodów. Jednak przed odczytem (zapisem) zewnętrznej pamięci najpierw mikroprocesor sprawdza, czy pamięć jest podłączona do układu. Odby wa się to automatycznie w pętli głównej. Realizuje to procedura spr_czyjcst() pokaza na na listingu 1. Do pamięci jest zapisywany a zaraz potem odczytywany próbny bajt liczba 100 pod adres II. Jeśli wartość bajtu zapisanego pokrywa się z odczylanym, to zerowana jest zmienna globalna g exisl. Zmienna ta jest informacj ą o obecności klucza dla innych fragmentów programu. Komendy cliQ oraz seiQ odpowiednio zerują i ustawiają globalną flagę przerwań. W programie jest wykorzystane przerwanie od timcrO do miga ma dioda Dl. Podczas obsługi I2C jest blokowane, żeby transmisja przebiegła poprawnie.
Funkcja odczytująca kod z klucza jest pokazana na listingu 2. Odczyt danych do tablicy odbywa się za pośrednictwem zmiennej wskaźnikowej *tab. Wskazuje ona na tablicę, w której mają być umieszczone odczytane dane. Ostatni odebrany bajt nic jest potwierdzany.
Warto wspomnieć, jak jest obsługiwana wewnętrzna pamięć EEPROM procesora. Przede wszystkim musi być dołączony plik nagłów kowy <avr\eeprom.h>. Są w mm definicje odpowiednich funkcji. Zapis i odczyt kodu jest pokazany na listingu 3 Jak widać, jest to bardzo proste i sprowadza się do wykorzystania dwóch gotowych funkcji: eeprom write byle() oraz eeprom _read_byte().
Procedurę weryfikującą poprawność podłączonego klucza pokazuje listing 4. Najpierw odczytywane są obie pamięci, a następnie porównywane. Wynik przechowuje zmienna g_\vyn_por. W tej części programu musi być jeszcze zabezpieczenie przed rozpoznawaniem kluczy fabrycznych. Problem w tym, że nowe pamięci, zarówno wewnętrzna pamięć procesora, jak i klucza są wypełnione liczbami 255. Gdyby nie było lo uwzględnione, klucz byłby rozpoznawany, bo w tym momencie mają zgodny kod.
Elektronika dla Wszystkich Grudzień 2006 51