Sistem de Acces Ibutton
CUPRINS
Introducere
Descrierea sistemului de acces cu buton Dallas
Prezentare generală
Componentele sistemului
Calculatorul si software-ul de administrare pontaj
Funcționarea unui sistem de acces iButton
Microcontrolerul ATTINY2313
Interfața serială RS232
. Prezentare generală
Comunicația sincronă și asincronă
Formatul datelor
Rata de transfer
Standardul RS232
Pinii interfeței seriale RS232
Semnalele de control handshaking
Conectarea microcontrolerului
ATTINY2313 la interfața serială RS232
Descrierea driver-ului/receiver-ului MAX232
Suportul software al sistemului de control acces cu button Dallas – SAM
. Generalități
Funcționarea sistemului de acces cu buton Dallas – SAM
Generalități
Aplicații
Concluzii
Bibliografie
Anexe
Introducere
Chei inteligente
Primele chei inteligente au fost cele legate de codurile de acces. Primele coduri de acces erau introduse cu ajutorul unei tastaturi. Același cod de acces putea fi folosit de mai multe persoane fără a se cunoaște identitatea persoanei care l-a folosit. Pentru o codare optimă era nevoie de un cod cu mai multe cifre ceea ce făcea ca utilizatorul să piardă timp la introducerea codului.
O următoare etapă în evoluția cheilor inteligente au fost cartelele magnetice sau cu coduri de bare. Cartela asigura accesul doar unei singure persoane (deținătorului). Citirea era aproape instantanee fără intervenția operatorului uman.
Totuși și acest tip de chei avea limitări:
– Nu putea stoca informații importante despre posesor având capacitate redusă de codare;
– Informația nu putea fi modificată fără schimbarea cartelei;
– Nu permitea stocarea temporară de date pe cartelă;
– Necesitau sisteme relativ complicate pentru citirea magnetică sau optică.
Mai târziu, au apărut cardurile “cip electronic” (similare cu cele telefonice de astăzi) cu aceleași caracteristici fizice, numai că nu erau afectate de câmpurile electro-magnetice. Posibilitatea folosirii incorecte s-a redus substanțial. Totuși, suspiciunea asupra securității lor s-a păstrat în rândul utilizatorilor.
Touch memory
Pe la jumătatea anilor ’90 Dallas a prezentat “touch memory” – memoria de contact. A fost făcută o paletă completă de cipuri din această serie cu caracteristici și funcții diferite (NVRAM, ROM, EPROM, respective termometru, “real time clock” – ceas de timp real, etc.). Comparându-le cu tastaturile și diferite tipuri de carduri, se disting următoarele caracteristici:
memoriile “touch” sunt mai mici;
nu sunt afectate de câmpuri magnetice;
carcasele de oțel inoxidabil elimină eventualele influențe electrostatice din atmosferă;
nu sunt două de același fel – au un număr propriu de identificare;
realizare ușoară a produselor cu cititoare multiple (spot).
Ultima caracteristică este foarte importantă pentru crearea unui sistem de spoturi (cu citiri) multiple. Un contact este plasat la fiecare spot de citire și o memorie touch (cu atingere) este plasat pe el. LED-ul (Light-Emitting Diode) montat deasupra sa este un indicator de acces și de avertizare în același timp. Spoturile multiple sunt conectate simplu cu două perechi de fire. Dacă nu este necesar a avea o indicație optică (LED), o singură pereche este de ajuns. Se pot face economii mari de material. Cipurile tip card sunt elegante, practice și arată bine într-un buzunar al unei uniforme albe. Dar totusi nu toți lucrează în laboratoare. Aici este cazul muncitorilor din construcții, sudorilor și minerilor, ca exemplu, unde cardurile trebuie să reziste în condiții extreme.
Scopul principal al lucrării este realizarea unui sistem electronic de securizare ce permite accesul într-un obiectiv anume (birouri, case, hotel, etc) cu ajutorul unei chei inteligente tip iButton. Având în vedere că securitatea lucrurilor personale și a locuințelor este o problemă majoră în ziua de azi și tot mai mulți oameni sunt preocupați de acest aspect, firma Dallas Semiconductors a propus un concept nou, sigur și relativ simplu, cel al cheilor Dallas de tip Touch Memory.
Ideea de bază de la care pleacă elaborarea proiectului constă în restricționarea, identificarea și monitorizarea accesului persoanelor în obiectivele amintite mai sus. Acest lucru se poate face cu ajutorul unui calculator conectat la încuietoarea electronică printr-un cablu serial si un soft specializat în acest sens. S-a folosit o cheie Touch Memory tip DS1990A#F5, un receptor, o placă de comandă și o interfață pentru comnicarea cu PC-ul acestuia din urmă fiindu-i instalat un soft ce permite vizionarea datelor citite de circuit si monitorizarea lor sub forma unei baze de date. Receptorul este un cititor IButton standard de tip CZ-0-S, placa de comandă folosește un microcontroler din familia Atmel cu un cuarț la valoarea de 8 MHz ce comandă un releu, interfața pentru comunicarea cu calculatorul este de tip RS232 ce conține un convertor de semnal MAX232 și un port serial DB9.
Rezultate obținute
În cadrul realizării proiectului se poate constata finalizarea în mare parte a obiectului propus. S-a efectuat comnicația dintre calculator si circuit cu ajutorul unui cablu serial având la un capăt un conector DB9 de tip tată ce se conectează la circuit și la celalălalt un conector DB9 de tip mamă ce se conectează la calculator, circuitul funcționând ca emițător și calculatorul ca receptor. Se pot stoca în memoria microcontrolerului pâna la douăzeci de chei slave plus cheia master care poate fi folosită ca și cheie “jeton” . Accesul cu cheia slave se poate face în acest caz numai cu ajutorul cheii master ambele fiind în memorie. Am folosit în cadrul proiectului meu o singură cheie ce va fi pusă ca și master. În loc de încuietoarea propriu-zisă cu yală am folosit un mecanism de anclanșare cu un releu în acest fel fiind simulată descuierea și încuierea ușii. Suportul software folosit este un soft de pontaj ce a fost proiectat în hyper terminal.
Descrierea sistemului de acces cu buton Dallas
2.1. Prezentare generală
Importanța asigurării securității instituțiilor a crescut exponențial, în aces sens controlul accesului joacă un rol deosebit de important în planul organizatoric general de securitate.
Sistemele de control acces au rolul de a limita și controla accesul personalului în zone de interes și securitate, putând ușor prelua și funcția de evidență a prezenței personalului în program.
Ca sistem de securitate, sistemul de control acces este flexibil și modular, ceea ce permite extinderea pe etape a acestuia la cererea și resurselor clientului.
Sistemele de control acces au la bază aceleași caracteristici generale de realizare și operare, elementele ce le diversifică sunt facilitățile suplimentare și modalitatea de stocare și citire a informației codificate pe suportul de identificare. În prezent soluția cea mai des adoptată pe plan mondial este utilizarea cartelelor de proximitate, cartelelor magnetice sau chiar a tastaturilor cu cod de acces și implementarea unui software adecvat pentru controlul fluxului de personal și/sau valori. Deși sistemele bazate pe butoane Dallas sunt apărute încă de la mijlocul anilor ’90 nu sunt la fel de folosite ca cele enumerate mai devreme, cel puțin la noi, dar încetul cu încetul acest sistem relativ nou va fi din ce în ce mai folosit.
Tendința de integrare prin software a sistemelor de control acces, detecție a începutului de incendiu, protecție la efracție și supraveghere video transferă aplicațiile complexe din domeniul abstract în cel concret.
Un astfel de sistem poate rezolva următoarele probleme:
Controlul accesului în sediul instituțiilor;
Prevenirea accesului neautorizat în zonele speciale;
Pontajul electronic al timpului și a prezenței angajaților.
Avantaje:
Protecție față de tendința de falsificare;
Obținerea operativă a datelor privind prezența prin intermediul software-ului de pontaj;
Timp minim consumat în prelucrarea datelor;
Sistemul are interfață prietenoasă cu utilizatorul fiind ușor de utilizat;
Fiecare cheie are un cod unic de identificare de 64 biți care cu ajutorul softului de pontaj utilizatorul poate fi recunoscut imediat ce a atins cheia de cititor;
Fiabilitate ridicată.
2.2. Componentele sistemului
Sistemul de control acces prezentat în această lucrare are următoarele componente:
– Cheile inteligente de identificare IButton;
– Cititorul de chei;
– Elementele de execuție;
– Calculatorul și software-ul de administrare și pontaj;
– Rețeaua de comunicație și conectare.
Menționăm ca în cadrul unei instituții unde se folosesc astfel de sisteme de pontaj topologia rețelei și numărul echipamentelor sunt diferite în funcție de cerințele respectivei instituții.
Cheile inteligente de identificare IButton
Aceste chei prezintă următoarele avantaje:
Carcasa cheii este din oțel inoxidabil fiind foarte rezistent la zgârieturi, scăpări pe jos sau în apă;
Adresă unică de 64 biți ce nu poate fi afectată de câmpuri magnetice, detectoare de metal, etc;
Este ușor de purtat și se poate atașa la un inel de cheie sau chiar folosi sub formă de inel în anumite variante;
Simplu de folosit prin simpla atingere de cititor.
Standardul mecanic
Tipuri
Sunt sub forma unor microcipuri de silicon de 16 milimetri diametru protejate de o armură de oțel inoxidabil [1]. Există două standarde după grosime: de trei milimetri si de cinci milimetri. Dispozitivele care sunt alimentate de master prin liniile de date (alimentare parazită) sunt valabile în ambele standarde. Toate celelalte dispozitive le găsim numai în standardul de cinci milimetri. În figura 2.1 ne sunt prezentate cele două tipuri de chei. Menționăm că dimensiunile din figură sunt trecute în milimetri.
Figura 2.1. Standardul de trei și de cinci milimetri al cheii iButton (F3, F5)
Având în vedere ca ambele chei au capac cu aceeași dimensiune folosesc același tip de cititor. Flanșa de dedesubt a butonului ajută la montarea anumitor suporturi de purtat a cheii.
Stabilitate
Sunt proiectate din oțel inoxidabil solid cu o grosime de 0.254 mm. Materialul izolant dintre partea superioară și cea inferioară a butonului este din polipropilenă neagră opacă care inhibă razele ultraviolete. Acest lucru conferă o stabilitate mecanică excelentă fiind și rezistent la coroziune. Toate aceste minicarcase de metal suportă șocuri mecanice de 500 g (1 g = 9.81 m/s2) în orice direție. O scăpare de la 1.5 m nu afectează carcasa de metal sau conținutul acesteia. De asemenea contactele repetate cu cititoarele nu ii afectează structura. Este conceput să reziste pe puțin un milion de cicli de folosire.
Regim de temperatură
Infobutoanele (DS1990A precum și altele) au fost poiectate să reziste la regimuri de temperatură extreme de la -40° C la +70° C.
Gravarea în vederea citirii
Toate carcasele de metal ale cheilor sunt gravate cu laser pentru a oferi informații despre cheie ca în figura 2.2. Modelul cheii este gravat în partea de jos (ex. DSZZZZ – XXX). Extensia XXX a modelului va indica tipul pachetului (F3 sau F5) ori versiunea specifică a utilizatorului. Dispozitivul specific utilizatorului poate fi marcat 001 – FFF (hexazecimal) în combinație cu un cod de familie specific. Independent de asta, numele utilizatorului poate fi de asemenea plasat în locul numelui „DALLAS”.
Figura 2.2. Gravarea datelor pe capac și specificația lor
Standardul electric
Tehnologia
Pentru a realiza un sistem economic, interfața electrică este redusă la minim absolut, fiind necesare numai două fire (linia de date și masa). Energia necesară transmisiei este luată din linia de date. În figura 2.3 ne este prezentată o privire de ansamblu a infobutonului.
Figura 2.3. Diagrama bloc a infobutonului
Cipul din interior este produs folosind tehnologia CMOS și consumă numai curentul disersat când este în stare inactivă. Pentru a menține energia consumată la o valoare cât mai joasă posibil în timpul activ și pentru a fi compatibil cu existentele familii logice linia de date IButton este concepută ca o drenare la ieșire deschisă cum ne numelui „DALLAS”.
Figura 2.2. Gravarea datelor pe capac și specificația lor
Standardul electric
Tehnologia
Pentru a realiza un sistem economic, interfața electrică este redusă la minim absolut, fiind necesare numai două fire (linia de date și masa). Energia necesară transmisiei este luată din linia de date. În figura 2.3 ne este prezentată o privire de ansamblu a infobutonului.
Figura 2.3. Diagrama bloc a infobutonului
Cipul din interior este produs folosind tehnologia CMOS și consumă numai curentul disersat când este în stare inactivă. Pentru a menține energia consumată la o valoare cât mai joasă posibil în timpul activ și pentru a fi compatibil cu existentele familii logice linia de date IButton este concepută ca o drenare la ieșire deschisă cum ne este prezentat în figura 2.4. Sursa curentă care este de la linia de date la masă întoarce linia de date la masă dacă infobutonul este depărtat de cititor. Interfața drenă deschisă face ca infobutonul să fie compatibil cu toate microprocesoarele și sistemele logice standard. Într-un mediu CMOS e necesar numai un rezistor cu putere nominală de 5 kΩ de tip pull-up la 5 V VDD pentru a opera în condiții normale pe un port bidirecțional de tip drenă deshisă (figura 2.5). Dacă intrarea și ieșirea procesorului folosește pini separați, conexiunea din figura 2.6 va furniza o interfață adecvată.
Figura 2.4. Interfață de date internă Figura 2.5. Circuit Bus Master
iButton (open-drain)
Figura 2.6. Circuit Bus Master ce separă intrarea de ieșire
Protocolul
Într-un mediu simplu precum cel descris mai devreme o apropiere optimizată pentru comunicație bidirecțională numit protocol pe un fir (1-wire) este folosit. Transferul serial se face half duplex (transmisia sau recepția se face pe rând) în cadrul intervalelor de timp definite discret. În fiecare caz, microcontrolerul (ca master folosind un cititor specific) inițiază transferul trimițând un o comandă de tip cuvânt la IButtonul de tip slave. Similar ștecherelor electrice, unde capetele de tip mamă si tată definesc polaritatea pozitivă și cea negativă, în mediul de atingere (touch) cititorul în formă de cupă este definit ca master și infobutonul ca slave. Aceste definiri explicite evită conflictele de gen master-master sau slave-slave.
Comenzile și datele sunt transmise bit după bit începând cu cel mai puțin semnificativ bit. Sincronizarea dintre master și slave se bazează pe panta abruptă pe care semnalul master o generează extrăgând linia de date la valoare joasă. La un anumit timp după această pantă, depinzând de direcția datei, masterul sau slaveul probează tensiunea de pe linia de date pentru a lua un bit de informație. Această metodă poartă numele de transfer de date în intervale de timp. Fiecare interval de timp este independent programat astfel încât să apară pauze de comunicație între biți dacă este necesar, fără a se cauza erori. Figura 2.7 ne ilustrează caracteristicile generale ale acestui tip de comunicație.
Figura 2.7 Transferul datelor în intervale de timp
Sincronizarea
Transferul datelor nu se poate realiza înainte de conectarea iButtonului la master sau înainte ca memoria să atingă linia de date și de masă a microcontrolerului. La câteva microsecunde după stabilirea legăturii (după atingere) iButtonul trimite impulsuri pe linia de date joasă pentru a spune masterului că este pe fir și așteaptă sa primească o comandă. Această formă de undă este numită impuls de prezență. Masterul poate și el să ceară un iButton pentru a da un impuls de prezență emițând un impuls de reset. Dacă iButtonul primește un impuls de reset sau este deconectat, va simți un nivel scăzut al semnalului pe linia de date și va genera un impuls de prezență chiar după ce linia ajunge din nou la un nivel ridicat de semnal. O secvență completă de impuls prezență/reset ne este indicată în figura 2.8.
Figura 2.8 Impuls de prezență și reset
Transferul de date
După impulsul de prezență, iButtonul așteaptă să primească o comandă. Orice comandă este scrisă iButtonului prin concatenarea intervalelor de timp cu scriere de zero și de unu pentru crearea unui bit de comandă complet.
Transferul datelor în direcția opusă (de la iButton) folosește aceleași reguli de temporizare pentru reprezentarea biților de unu și de zero. Având în vedere că infobutoanele sunt proiectate sa fie slave-uri, lasă pe seama masterului în definirea începutului fiecărui interval de timp. Pentru realizarea acestui lucru, masterul inițiază un interval de timp cu scriere de unu pentru citirea unui bit de date. Dacă iButtonul are nevoie să trimită un bit de unu tot ce trebuie să facă este să aștepte următorul interval de timp. Dacă are de trimis un zero va ține linia la nivel scăzut pentru un anumit timp, în ciuda eliberării de către master. Un exemplu complet de secvență de comandă ce începe cu impulsul de prezență și se termină cu data este prezentat în figura 2.9. Activitatea masterului este desenată în linii îngroșate. Liniile marcate în gri reprezintă răspunsul iButtonului. Liniile subțiri indică faptul că nici unul nu e activ. Valoarea liniei de date este ridicată de rezistor.
Figura 2.9 Exemplu de citire ROM
Structura datelor din memoria ROM
O secțiune ROM programată cu laser ce este specifică tuturor ibutoanelor conține un număr serial unic de șase biti, un cod de familie un bit și un bit de verificare CRC (cycle reductancy check).
Figura 2.10. Structura datei DS1990A
Bitul CRC
Bitul CRC este ultimul bit transmis din structura datei de mai sus. CRC-ul este un fel de semnătură a primilor șapte biți. Permite o verificare rapidă a secvenței complete de comunicație. Dacă CRC-ul calculat de masterul de citire corespunde cu CRC-ul citit de la dispozitiv, citirea a fost corectă. În caz contrar se reia citirea. CRC-uri care nu corespund pot apărea în momentul când contactul nu este bun sau când se încearcă citirea mai multor dispozitive simultan. Acesta este unul din motivele pentru care Ibuttoanele nu necesită contacte electrice stabile. Acest bit de control protejează codul familiei și numărul serial. CRC-ul este generat cu ajutorul polinomului x8 + x5 +x4 + 1 și este înscris în forma sa reală fiecărui cip cu laserul în timpul fabricației și rămâne permanent în memorie.
Codul de familie
Codul de familie este o valoare specifică tipului ce face referință la funcționalitatea și capacitatea dispozitivului. Este primul bit din structura datei ce este transmis după acesta urmând numărul serial al cheii. El reprezintă tipul dispozitivului. Pentru DS1990A codul familiei este 01. În tabelul 2.1 putem vedea câteva exemple de chei cu caracteristici specifice.
Tabelul 2.1 Dispozitive iButton
.
Numărul serial
Numărul serial de 48 biți (6 bytes) poate rerezenta orice număr zecimal până la 2.81 * 1014. Dacă s-ar produce 1000 de miliarde (1.0 * 1012) dispozitive cu același cod de familie pe an ar fi suficiente pentru 281 ani. Așadar sunt disponibile 128 familii de cod. Dacă cel mai semnificativ bit a codului de familie este setat, funcționalitatea dispozitivului nu se schimbă dar numărul serial trebuie să urmeze anumite reguli speciale.
Dat fiind faptul designului și controlului strict în fabricație, DS1990A este un identificator electronic unic ce nu este practic în falsificare. Este adecvat pentru aplicații unde identificarea absolută este necesară.
Cititorul de chei
Infobutoanele sunt citite sau scrise cu ajutorul unui cititor. El este sub forma unui soclu cu contact metalic. Învelișul exterior poate fi fie metalic fie din plastic în funcție de modelul ales. Tot în funcție de model avem cititoare cu led (CZ-2-S) sau fără led (CZ-0-S) în partea contactului metalic [2]. Cititorul este de preferat să fie fix iar cheia mobilă. Rolul lui principal e de preluare a codului unic de la cheie și transmiterea acestuia mai departe în circuit la controler în vederea procesării. Acest lucru se face prin folosirea protocolului pe un fir (1-wire). În figura 2.11 ne este prezentat cititorul CZ-0-S, iar în figura 2.12 o secțiune a acestuia [3].
Figura 2.11 Cititorul CZ-0-S fără led
Figura 2.12. Structură printr-un cititor CZ-0-S fără LED
Menționăm că firul maro reprezintă masa, iar firul alb reprezintă linia de date ca în figura 2.13 [4].
Figura 2.13. Diagrama conexiunii
Varianta CZ-2-S cu LED ne este prezentată mai jos în figura 2.14, iar în figura 2.15. avem o secțiune prin acest cititor [5]. Are în componență un LED bicolor. Ledul poate lumina în trei culori. Sistemul poate fi programat astfel:
Să lumineze portocaliu cand echipamentul așteaptă o cerere de acces adică o cheie;
Să lumineze verde când accesul a fost acordat;
Să lumineze roșu când accesul nu a fost acordat.
După o cerere de acces cititorul poate să păsteze culoarea verde sau roșie timp de 1.6 secunde după care se întoarce la starea de așteptare pentru cerere de acces (portocaliu). Conexiunea diagramă a acestui cititor o avem în figura 2.16 [7]. Firul gri reprezintă masa iar firul alb linia de date. Ledul din acest model funcționează la 10 mA.
Figura 2.14. Cititorul CZ-2-S cu LED
Figura 2.15. Structură printr-un cititor CZ-2-S cu LED
Figura 2.16. Diagrama conexiunii
Elementele de execuție
Elementele de execuție sunt elementele comandate de microcontroler. Acesta la rândul lui răspunde în funcție de semnalul primit de la cititor acționând un releu ce mai departe va deschide ușa și informând programul de pontaj în vederea stabilirii identității persoanei.
2.3. Calculatorul și software-ul de administrare și
pontaj
Sistemul este supervizat de un calculator care preia informațiile de la cititor și le procesează în vederea întocmirii anumitor rapoarte. Acesta are la bază un program specializat.
Prin intermediul acestui software se pot întocmi rapoarte cu privire la:
Persoanele care au intrat-ieșit prin anumite puncte de acces precum și stabilirea identității acestora cu ajutorul codului de identificare a cheii
Prezența personalului pe parcursul unei perioade de timp.
Programul folosit pe calculator poate fi dedicat controlului accesului ca mod de
securitate dar și pentru pontaj, management de personal, calcul salarial în funcție de ore muncite, etc. În cazul în care un angajat pierde cheia aceasta poate sa fie invalidată prin soft pentru a nu se poate folosi de persoane neautorizate.
Rețeaua de comunicație și conectare
Asigură conectarea tuturor echipamentelor la sistem. De asemenea în cadrul unei firme printr-o rețea de tip intranet datele culese privind accesul și pontajul de o anumită stație pot fi trimise unui server central în vederea unei gestiuni mai riguroase. Acest lucru se poate face fie cu ajutorul modemurilor fie cu ajutorul plăcilor de rețea pentru comunicarea cu alte calculatoare.
Funcționarea sistemului de acces cu iButton
Identificare prin apăsare
Pentru a folosi un dispozitiv de identificare prin apăsare e necesar ca legătura dintre cele două dispozitive să se facă ușor, prin cât mai puține terminale și să nu depindă de orientarea dispozitivelor de citire cât mai simplu și ieftin. Astfel firma Dallas Semiconductor a realizat cele mai simple chei inteligente ce nu necesită decât două contacte: unul de masă și unul de date.
Cheile inteligente produse de Dallas Semiconductor se întâlnesc sub denumirea de iButton. Cele două contacte sunt sensibile la poziționarea unghiulară iar prin proiectare nu permit conectarea incorectă. iButton este de fapt o memorie nevolatilă ce poate fi citită fără un echipament sofisticat, poate memora până la 64 Kbiți de informație, poate transfera date la viteze de până la 142 Kbiți/sec. Fiecare iButton are un cod propriu de identificare care este unic și nu poate fi schimbat. Memoria de date este partiționată în pagini de câte 256 biți. Integritatea datelor e asigurată de protocolul special de citire/scriere a datelor.
Echipamentul de citire este simplu și mic deoarece iButton nu necesită energie pentru a fi citit sau scris. Pentru transfer de date se folosește protocolul pe un fir. Prin acest protocol pot comunica un dispozitiv „master” și unul sau mai multe dispozitive „slave”.
Conexiunea cu un circuit „master” este de obicei realizat cu un microcontroler.
Structura unui sistem de limitare a accesului este următoarea (figura 3.1):
Figura 3.1. Structura unui sistem de limitare a accesului
Funcționarea sistemului cu iButton
Citirea numărului de 64 biți este începută la efectuarea contactului fizic cu memoria touch. Rezultatul citirii este comparat cu alte numere memorate în memoria EEPROM (Electrically Erasable Programmable Read-Only Memory) a microcontrolerului însuși. Dacă numărul din “touch memory” este identic cu unele din numerele stocate în EEPROM-ul microcontrolerului, un releu este activat timp de aproximativ două secunde și în consecință ușa se va deschide. În timpul acestui interval se aude un sunet de la un buzzer piezo. Frecvența trebuie să fie în jur de 4 kHz. Aceasta este frecvența de rezonanță a buzzerului, pentru a face sunetul mai audibil. În circuit am folosit microcontrolerul ATMEL ATTINY2313. Acesta nu are nevoie de rezistoare “pull-up”, pentru că ele sunt deja implementate în microcontroler. Releul este alimentat de tensiunea de 5V.
Fiecare persoană autorizată deține câte un iButton pe care sunt memorate codurile de acces ale diferitelor zone de securitate. O persoană poate avea astfel accesul la o zonă mai mică sau mai mare în funcție de codurile proprii de acces. Fiecare zonă de securitate va fi dotată cu un sistem de limitare a accesului compus din:
cititor pentru iButton realizat din două contacte ce nu necesită nici o altă parte electronică. El poate fi montat chiar în încuietoarea ușii (vezi figura 3.2) [8];
memoria nevolatilă are memorate în ea toate codurile unice ale iButton-urilor folosite precum și codurile de acces pentru zona respectivă. De asemenea, memoria este folosită pentru realizarea unei baze de date cu privire la persoanele care au accesat sistemul memorând;
sistemul cu microcontroler realizează implementarea protocolului de comunicație pe un fir pentru citirea iButton, verifică autenticitatea iButton prin compararea codului unic citit din iButton cu cele din baza sa de date, verifică apoi dacă codul de acces este valid sau nu acționând în funcție de situație.
Datorită folosirii unei memorii nevolatile cu capacitate relativ mică, periodic sistemul cu microcontroler transferă datele prin modulul de comunicație la un calculator central unde se realizează o bază de date generală. În cazul în care zona deservită de mai multe sisteme de limitare a accesului este mare iar sistemele nu se pot conecta toate la un calculator central atunci folosirea iButton de către o persoană duce la înscrierea în aceasta a momentului accesării zonei respective.
Figura 3.2. Încuietoare pentru ușă
La prima conectare a iButton la un sistem de limitare a accesului conectat la calculatorul central datele înscrise în iButton sunt transferate calculatorului. Se poate ști astfel când, cine și unde a pătruns în cazul apariției unor fenomene deosebite costul relativ scăzut al iButton il face foarte folosibil în diverse alte aplicații.
Microcontrolerul ATTINY2313
ATTINY2313 este un microcontroler de 8 biți cu CMOS de putere joasă bazat pe arhitectura RISC (Reduced Instruction Set Computer) adaptat pe AVR cu 20 de pini [9]. Executând instrucțini puternice într-un singur ciclu de ceas, ajunge la o capacitate de transport de un MIPS/MHz permițând fabricantului sistemului să optimizeze consumul puterii vis-a-vis de viteza de procesare.
Miezul AVR combină un set bogat de instrucțiuni cu 32 de scopuri generale ce lucrează cu regiștri. Toși cei 32 de regiștri sunt direct conectați la unitatea aritmetico- logică (ALU) cum se poate observa și în diagrama bloc a figurii 3.1., pemițând ca doi regiștri independenți să fie accesați cu o singură instrucțiune executată obținându-se capacități de transport de până la zece ori mai rapide decât microcontrellerele convenționale CISC.
ATTINY2313 ne funizează următoarele caracteristici: 2 Kbytes de Flash programabil în sistem, 128 bytes EEPROM, 128 bytes SRAM, 18 linii generale cu scop de I/O, 32 regiștri funcționali generali, o interfață cu un singur fir pentru Debugging pe cip (On-Chip), două Timere/Numărătoare flexibile cu moduri de comparare, întreruperi interne și externe, un USART (Universal Synchronous/Asynchronous Receiver/Transmitter) programabil serial, Interfață Serială Universală cu Detector de Condiție Start, un Timer Watchdog programabil cu oscilator intern și trei moduri de selecție software a economisirii alimentării. Modul de repaus oprește CPU-ul în timp ce permite SRAM-ului (Static Random Acces Memory), Timerului/ Numărătorului și sistemului de întrerupere să iși continue funcționarea.
Modul închis salvează conținutul regiștrilor dar stagnează oscilatorul, dezactivând toate celelalte funcțiuni ale chipului până la următoarea întrerupere sau reset de hardware. În modul de așteptare, oscilatorul de cristal sau rezonator funcționează în timp ce restul dispozitivelor sunt în stare de veghe. Aceasta permite un start-up rapid combinat cu un consum mic de putere.
Dispozitivul este fabricat cu ajutorul tehnologiei memoriei ATMEL nevolatile de densitate înaltă. Flash-ul ISP (In-System Programming) din cadrul cipului permite memoriei din program să fie reprogramată în sistem prin interfața serială SPI sau prin programatoare convenționale de memorie nevolatile.
Figura 4.1. Diagrama bloc a microcontrolerului ATTINY2313
Combinând un CPU RISC de opt biți cu un Flash din cadrul sistemului ce se programează singur aflat pe un chip monolitic, ATTINY2313 este un microcontroler puternic care furnizează o flexibilitate înaltă și soluție de cost efectivă pentru multe aplicații de control incorporate.
Avr-ul ATTINY2313 este suportat de o suită întreagă de programe și unelte de dezvoltare a sistemului inclusiv: Compilatoare C, Macroasambloare, Simulatoare/ Debuggere de program, Emulatoare de circuit și Kituri de evaluare.
Descrierea pinilor
Figura 4.2. Configurația pinilor microcontrolerului ATTINY2313
VCC – tensiune de alimentare digitală
GND – impământarea
Port A (PA2…PA0) – portul A este un port de intrare ieșire pe trei biți bidirecțional cu rezistoare pull-up interne (pentreu fiecare bit). Bufferele de ieșire din port A au caracteristici simetrice de condus cu capacități înalte pe sursă și masă. Ca intrări, pinii portului A care au valori externe joase devin surse curente dacă rezistorii pull-up au fost activați. Pinii portului A sunt cu trei stări când o condiție de reset devine activă, chiar și când ceasul nu funcționează.
Portul A mai servește și la funcțiuni speciale variate cum ar fi:
PA2 -> RESET, dW;
PA1 -> XTAL2;
PA0 -> XTAL1.
Port B (PB7..PB0) – este un port bidirecțional de intrare/ieșire pe opt biți cu rezistori de tip pull-up (selectați pentru fiecare bit). Bufferele de ieșire din port B au caracteristici simetrice de condus cu capacități înalte pe sursă și masă. Ca intrări, pinii portului B care au valori externe joase devin surse curente dacă rezistorii pull-up au fost activați. Pinii portului B sunt cu trei stări când o condiție de reset devine activă, chiar și când ceasul nu funcționează.
Portul B mai servește și la funțiuni speciale variate cum ar fi:
PB7 -> USCK/SCL/PCINT7;
PB6 -> DO/PCINT6;
PB5 -> DI/SDA/PCINT6;
PB4 -> OC1B/PCINT4;
PB3 -> OC1A/PCINT3;
PB2 -> OC0A/PCINT2;
PB1 -> AIN1/PCINT1;
PB0 -> AIN0/PCINT0;
Port D (PD6..PD0) – este un port bidirecțional de intrare/ieșire pe șapte biți cu rezistori de tip pull-up (selectați pentru fiecare bit). Bufferele de ieșire din port D au caracteristici simetrice de condus cu capacități înalte pe sursă și masă. Ca intrări, pinii portului D care au valori externe joase devin surse curente dacă rezistorii pull-up au fost activați. Pinii portului D sunt cu trei stări când o condiție de reset devine activă, chiar și când ceasul nu funcționează.
Portul D mai servește și la funțiuni speciale variate cum ar fi:
PD6 -> ICP;
PD5 -> OC0B/T1;
PD4 -> T0;
PD3 -> INT1;
PD2 -> INT0/XCK/CKOUT;
PD1 -> TXD;
PD0 -> RXD;
– Intrarea Reset. O valoare de nivel jos pe acest pin pentru lungimea unui puls mai mare decât minim va genera un reset chiar dacă ceasul funcționează. Condiția este conform relației (4.1) de mai jos și valoarea maximă de RESET este 2.5 μs. Pulsurile mai scurte nu sunt recomandate pentru generarea unui reset. Intrarea Reset este o funcție alternativă entru PA2 și dW.
Vcc = 1.8 – 5.5V (4.1)
XTAL1 – Intrare către amplificatorul oscilator inversor și intrare circuitului operator intern de ceas. XTAL1 este o funcție alternativă pentru PA0.
XTAL2 – Ieșire de la ampificatorul oscilator inversor. XTAL2 este o funcție alternativă pentru PA1.
Memorii
Arhitectura AVR are două spații de memorie principale. Acestea sunt memoria de date și memoria program. Pentru înmagazinarea datelor ATTINY2313 mai folosește o memorie EEPROM. Toate cele trei spații de memorie sunt liniare și regulate.
Memoria program reprogramabilă în cadrul sistemului de tip Flash
Microcontrolerul conține o asemenea memorie de 2 Kbytes pentru depozitarea programului. Având în vedere că toate instrucțiunile AVR sunt de 16 sau 32 bits Flash-ul este organizat ca 1 Kbit x 16.
Flashul are o rezistență de cel puțin 10.000 cicli de scriere/ștergere. Numărătorul program (PC) al microcontrolerului este de zece biți, astfel că se adresează la o locație de memorie program de 1 Kbit. Mai departe ne este reprezentată harta memoriei program în figura 4.3.
Figura 4.3. Harta memoriei Program
Memoria de date SRAM
Figura 4.4 ne înfățișează felul cum este organizată memoria SRAM.
Figura 4.4. Harta memoriei de date
Locațiile din memoria de date sub 224 adresează ambele fișiere registru , memoria I/O, memoria I/O extinsă și SRAM-ul de date intern. Primele 32 de locații adresează registrul fișier, următoarele 64 de locații memoria standard I/O și următoarele 128 locații adresează SRAM-ul de date intern.
Cele cinci moduri de adresare pentru memoria de date acoperă: Direct, Indirect cu deplasare, Indirect, Indirect cu pre-decrementare și Indirect cu post-incrementare. În fișierul registru, regiștrii R26 și R31 reprezintă regiștrii pointer de adresare indirectă. Adresare directă atinge întregul spațiu de date al memoriei.
Modul de adresare Indirect cu deplasare ajunge la 63 locații de adresă de la adresa de bază dată de registrul Y sau de registrul Z.
Când se folosește modul de adresare indirect al registrului cu pre-decrementare și post-decrementare automată, regiștrii de adresă X, Y și Z sunt incrementați sau decremntați.
Cei 32 de regiștri generali funcționali, 64 de I/O și 128 bytes de date SRAM interni în microcontroler sunt toți accesibili acestor moduri de adresare.
Memoria de date EEPROM
Microcontrolerul ATTINY2313 conține 128 bytes de memorie de date EEPROM. Este organizată ca un spațiu separat de date în care biții pot fi citiți sau scriși singuri. EEPROM-ul are o rezistență de 10.000 cicli scriere/ștergere. Mai departe ne este descris accesul dintre EEPROM și CPU specificând regiștrii de adresă EEPROM, regiștrii de date EEPROM precum și regiștrii de control EEPROM.
Accesul EEPROM de scriere/citire
Regiștri de scriere/citire sunt accesibile în spațiul I/O. Timpul de acces al EEPROM-ului il putem observa în tabelul 4.1
O funcție auto-temporizatoare lasă software-ul utilizatorului să detecteze când poate fi scris următorul bit. Dacă un cod al utlilizatorului conține instrucțiuni ce scriu în EEPROM, trebuie luate anumite măsuri de precauție. În surse de putere cu filtrare masivă, Vcc este capabil să crească sau să scadă ușor la întreruperea sau oprirea alimentării. Efectul asupra dispozitivului este ca pentru anumite perioade de timp acesta să funcționeze la tensiuni mai joase decât cele minime specificate în frecvența de ceas folosită.
Tabelul 4.1 Biții de mod EEPROM
În vederea prevenirii scrierii nedorite în EEPROM, o procedură specifică de scriere trebuie luată în calcul. Când EEPROM-ul este citit, CPU-ul este oprit patru cicli de ceas înainte ca următoarea instrucțiune să fie executată. Cînd EEPROM-ul este scris, CPU-ul este oprit doi cicli de ceas înainte ca următoarea instrucțiune sa fie executată.
Registru de adresă EEPROM (EEAR)
Figura 4.5. Registrul de adresă EEPROM
Bitul 7 din figura 4.5. este rezervat și va fi întotdeauna citit ca fiind zero.
Biții din locațiile 6 la 0 sau EEAR6-EEAR0 sunt regiștri de adresare. EEAR (Electrically Erasable Address Register) specifică adresa EEPROM din cei 128 bytes de memorie. Biții de date EEPROM sunt adresați liniar între 0 și 127. Valoarea inițială EEAR este nedefinită. O valoare adecvată trebuie scrisă înainte ca EEPROM-ul să fie accesat.
Registrul de date EEPROM (EEDR)
Figura 4.6. Registrul de date EEPROM
Biții de la 7 la 0 sau EEDR7 – EEDR0 sunt biți de date EEPROM. Pentru operația de scriere, registrul EEDR (Electrically Erasable Data Register) conține data ce urmează a fi scrisă în adresa EEPROM-ului dată de registrul EEAR. Pentru operația de scriere , EEDR conține data citită din EEPROM la adresa dată de EEAR.
Registrul de control EEPROM (EECR)
Figura 4.7. Registrul de control EEPROM
Biții 7 și 6 sunt biți rezervați și vor fi întotdeauna citiți ca fiiind 0.
Biții 5 și 4 sau EEPM1 și EEMP0 (Electrically Erasable Program Memory) sunt biți de mod programabili EEPROM. Setările biților de mod programabili EEPROM definesc ce acțiune de programare va fi inițiată când se scrie EEPE (Electrically Erasable Program Empty). Se poate programa data într-o singură operațiune atomică (ștergerea vechii valori și programarea celei noi) sau să se impartă operațiunile de scriere și citire în două operații distincte. Timpii de programare pentru diferite moduri ne sunt arătați în tabelul 4.1 de mai sus. În timp ce EEPE este setat orice scriere a EEPMn-urilor este ignorată. În timpul resetului, biții EEPMn vor fi resetați la 0b00 cu excepția cazului când EEPROM-ul este ocupat cu programarea.
Bitul 3 EERIE: întrerupere pregătită și activată a EEPROM-ului.
Scrierea registrului EERIE (Electrically Erasable Register intrerupt Empty) cu unu activează întreruperea dacă bitul unu din SREG este setat. Scrierea registrului cu zero dezactivează întreruperea.
Bitul 2 EEMPE: activarea programului Master din EEPROM. Acest bit determină dacă scrierea de 1 în EEMPE (Electrically Erasable Master Program Empty) are efect sau nu. Când EEMPE a fost scris în 1 prin software , hardware-ul șterge bitul la zero după patru cicli de ceas.
Bitul 1 EEPE : Activarea programului din EEPROM. Semnalul EEPE este semnalul de activare din program a EEPROM-ului. Când EEPE este scris, EEPROM-ul va fi programat conform setărilor de biți EEPMn. Când EEPE-ul este setat CPU-ul este oprit 2 cicli de ceas înainte ca următoarea instrucțiune să fie executată.
Bitul 0 EERE: Activarea citirii EEPROM. Semnalul EERE este ca o eșantionare a citirii din registru. Când EEPROM-ul este citit, CPU-ul este oprit pentru patru cicli de timp înainte ca următoarea instrucțiune să fie executată.
Întreruperea vectorilor
Tabel 4.2 Vectori de întrerupere reset
Porturi intrare/ieșire
Toate porturile AVR au funcții de citire, modificare și scriere când sunt folosite ca porturi intrare-ieșire generale digitale. Asta înseamnă că direcția unui pin poate fi schimbată fără schimbarea neintenționată a oricărui alt pin cu instrucțiunile CBI și SBI. Același lucru e valabil și când se schimbă valoarea de conducere (la configurarea ca ieșire) sau activării/dezactivării rezistoarelor pull-up (la configurarea ca intrare). Fiecare buffer de ieșire are caracterisitici de conducere simetrice cu cu posibilități mari ale sursei si minusului. Toți pinii de port au rezistoare selectabile pull-up individuale cu o rezistență invariantă a tensiunii de alimentare. Toți pinii I/O au diode de protecție atât la Vcc cât și la masă așa cum ne este figurat în figura 4.8.
Trei locații adresă de memorie intrare/ieșire sunt alocate fiecărui port, câte unul fiecare pentru registrul de date – PORTx, registrul de date și direcție – DDRx și pinii de intrare la port PINx. Locația de intrare/ieșire a pinilor portului de intrare este în modul numai de citire (Read-Only) în timp ce celelalte două, registrul de date și registrul de direcție date, sunt în modul citire/scriere. Totodată scrierea unui unu logic unui bit din registrul PINx va rezulta o declanșare a bitului de corespondență din cadrul registrului de date.
Figura 4.8. Schema echivalentă a pinilor de intrare/ieșire
Interfața serială RS232
5.1. Prezentare generală
Sistemele de calcul pot să comunice în două moduri: paralel și serial. În modul paralel, de obicei se utilizează 8 sau mai multe linii (cabluri). Exemple de utilizare a comunicației paralele sunt imprimanta sau hard discul. Comunicația paralelă se utilizează doar pentru distanțe foarte scurte (câțiva metri). Motivul este de fapt ca pentru cablurile lungi, semnalele sunt atenuate și pot apare distorsiuni. În plus nu este deloc de neglijat costul cablurilor și problemele ce pot apare la conexiuni. Avantajul comunicației paralele este viteza mare de transmisie.
Comunicația serială este utilizată pentru sisteme aflate la mare distanță între ele. Comunicația serială utilizează un număr redus de cabluri. În comunicația serială, datele transmise trebuie serializate la transmisie și deserializate la recepție. Pentru aceasta, la transmisie se utiliează un registru paralel-serie iar la recepție un registru serie-paralel. Registrul paralel-serie este utilizat pentru transformarea unei date de 8 biți într-un șir de biți. Registrul serie-paralel este utilizat pentru transformarea unui șir de 8 biți într-un octet.
Pentru distanțe lungi, comunicația paralelă poate utiliza linia telefonică. În acest caz semnalele logice zero și unu trebuie transformate în semnale sinusoidale. Această conversie este realizată de un dispozitiv numit modem (MODulator/DEModulator). Pentru distanțe scurte această conversie nu este necesară. De exemplu, tastatura și mouse-ul comunica serial informația către unitatea centrală PC.
Comunicația serială utilizează două metode:
sincronă: se transferă blocuri de octeți (caractere);
asincronă: se transferă câte un octet.
Se pot realiza programe pentru realizarea comunicației seriale însă acestea pot fi lungi. Este indicat ca programatorul să se concentreze asupra problemelor specifice aplicației și nu asupra unei probleme extrem de generale precum comunicația serială. Aici intervin și aspectele economice legate de productivitatea muncii. Din acest motiv producătorii de circuite au realizat circuite ce rezolvă problemele legate de comunicația serială. Aceste circuite se numesc UART (Universal Asyncronus Receiver Transmitter).
Simplex
Half Duplex
Full Duplex
Figura 5.1. Metode de comunicație
Microcontrolerul ATTINY2313 conține un asemenea modul (UART) înglobat. Din acest motiv in cele ce urmează ne vom referi doar la comunicația asincronă. Dacă datele pot fi transmise și recepționate simultan, se spune că avem comunicația „full duplex” (figura 5.1) [10]. Dacă datele nu pot fi trimise și recepționate simultan, se spune că avem comunicație „half duplex”. Aici termenul „simultan” se referă la faptul că ambele sisteme pot transmite date în același moment de timp. O altă situație este cazul în care unul din sisteme este doar un transmițător celălalt este doar un receptor (comunicație „simplex”). Pentru comunicația full duplex sunt necesare două fire (plus firul de masă).
5.2 Comunicația sincronă și asincronă
Cele două sisteme, pentru a putea comunica între ele, trebuie să respecte o serie de reguli. Trebuie stabilite convenții referitoare la:
modul de impachetare al datelor;
numărul de biți ai unui caracter;
cum se identifică începutul unei date;
cum se identifică sfârșitul unei date;
care este durata unui bit.
Dacă emițătorul și receptorul au același semnal de tact atunci se spune că lucrează in mod sincron. Altfel, dacă au semnale de tact separate , atunci lucrează în mod asincron [11].
În modul asincron, emițătorul nu trimite un tact deodată cu datele, ci inserează un pseudo-impuls de tact, cunoscut ca bit de start, în fața fiecărui octet transmis. Astfel, pentru fiecare caracter ASCII avem o transmisie independentă, cu adăugarea biților de start, stop și paritate. Viteza de lucru se stabilește numai la începutul transmisiei. Pentru informația de fază, receptorul trebuie să detecteze începutul bitului de start. Pentru ca această metodă să funcționeze, trebuie să existe, o perioadă de liniște între caractere, realizată cu bitul de stop.
În modul sincron, caracterele sunt transmise rapid, unul după altul, fără biți de start și de stop. Pentru sincronizare, mesajul transmis este precedat de caractere speciale de sincronizare, detectabile de circuistica receptorului. Acestea sunt transmise în continuu și când nu sunt date de transmis. Transmisiile în mod sincron pot folosi scheme inteligente de modulare, care se bazează pe circuistica suplimentară, iar semnalele de date și tact folosesc aceeași pereche de fire, această metodă, cunoscută sub numele de codificare Manchester fiind folosită în rețele Ethernet. O metodă sincronă alternativă este folosită pentru transmisii seriale rapide non-caracter, orientate pe bit. Protocoalele care folosesc această metodă permit transferul de date la viteze mari. Un astfel de protocol este și protocolul HLDC (High-Level Data Link Control).
Formatul datelor
Comunicația asincronă este frecvent utilizată pentru transmisia orientată pe caracter; comunicația sincronă este utilizată pentru transmisia orientată pe blocuri de date. În comunicația asincronă fiecare caracter este încadrat între biți de start și biți de stop. De fapt totdeauna se folosește un bit de start (zero logic) și de obicei un bit de stop (unu logic).
În figura 5.2. este repezentat modul de transmisie al caracterului ASCII „A” al cărui cod binar este 0100 0001. Se observă că transmisia biților se face în ordinea
START(0), D0(1),D1(0) … D7(0),STOP(1).
TRANSMIS d7 d0 TRANSMIS ULTIMUL PRIMUL
Figura 5.2. Transmisia caracterului ASCII”A”
Se transmite mai întâi bitul cel mai puțin semnificativ al octetului (LSB – D0). Se observă că de fapt pentru transmisia unui caracter se utilizează zece biți. Sunt și alte posibilități de transmisie. De exemplu, se poate prevede un bit suplimentar care sp reprezinte paritatea octetului. Scopul acestui bit este verificarea păstrării integrității datelor. De aceea programatorul trebuie să recunoască datele de catalog ale portului serial și modul lui de programare.
Rata de transfer
Rata de transfer reprezintă numărul de biți ce pot fi transmiși într-o secundă. Este dată în bps (biți per secundă). Alt termen des utilizat pentru bps este baud rate. Cei doi termeni nu sunt identici. Termenul baud este preluat din terminologia medemurilor unde este definit ca numărul de schimbări pe secundă ale unui semnal. Sunt situații când o singură modificare a semnalului conduce transferul mai multor biți de date. Totuși și dacă nu se utilizează modemul se pot utiliza ambii termeni. Rata de transfer depinde de portul de comunicație a sistemului. De exemplu, pentru PC-urile mai vechi rata de transfer de date este 100 … 9600 bps. Noile PC-uri suportă o rată maximă de transfer de 115,2 kbps.
Standardul RS232
Astăzi cel mai popular standard de comunicație serială este EIA/TIA-232-E. Acest standard, care a fost dezvoltat de “Electronic Industry Asociation and the Telecommunications Industry Association” (EIA/TIA) este cunoscut mai simplu ca “RS-232”, unde “RS” înseamnă “recomended standard”. Se mai folosește și denumirea EIA/TIA atunci când se dorește a sugera originea acestui standard.
Numele oficial al standardului EIA/TIA-232-E este “Interface Between Data Terminal Equipment and Data Circuit Termination Equipment Employing Serial Binary Data Interchange”. Deși denumirea poate părea complicată, acest standard este pur și simplu dedicat comunicației seriale între un sistem gazdă (Data Terminal Equipment sau DTE) și un sistem periferic (Data Circuit-Terminating Equipment sau DCE).
Standardul EIA/TIA-232-E, care a fost introdus în 1962, a fost reactualizat de patru ori de la introducea sa, pentru a întâmpina cât mai bine necesitățile comunicației seriale. Litera “E” în denumirea sa indică cea de-a cincea revizuire a standardului.
RS232 este un standard “complet”. Aceasta înseamnă că standardul asigură compatibilitatea între sistemele gazdă și periferice specificând:
Nivelurile tensiunii și semnalului
Configurația pinilor și a legăturilor
Controlul informației între cele două echipamente.
Deoarece standardul a fost adoptat înainte de apariția familiei logice TTL, standardul nu este compatibil cu nivelele TTL. Nivelul 1 logic este reprezentat de o tensiune electrică cuprinsă între -3 și +25 V, zonă situată între -3 și 3 V fiind nedefinită. Pentru conversia de nivele TTL/RS232 se utilizează circuite specializate ca MAX232.
Pinii interfeței seriale RS232
Tabelul 5.1. Pinii conectorului DB25 Tabelul 5.2 Pinii conectorului DB9
Se utilizează două tipuri de conectoare: cel de 25 de pini (fig.5.3) și cel de 9 pini (fig.5.4). Tabelul 5.1 arată semnalele interfeței RS232, deoarece în PC-uri nu se mai utilizează toate semnalele, IBM a introdus versiunea de conector pe nouă pini. Tabelul 4.2 arată semnalele interfeței seriale în acest caz.
Terminologie: se definesc noțiunile de terminal (DTE – Data Terminal Equipment) și echipament de comunicație (DCE – Data Comunication Equipment). DTE se referă la terminale și computere ce transmit și recepționează date, iar DCE se referă la echipamentele de comunicație cum ar fi modemurile. De notat că toate funcțiile definite în tabelele 5.1 și 5.2 sunt din punctul de vedere al DTE-ului. În cazul cel mai simplu, pentru a face conectarea unui microcontoler cu PC-ul sunt necesari doar trei pini, respectiv, RxD, TxD și masa. De notat că la conectare trebuie inversate semnalele RxD cu TxD la unul din echipamente.
Semnalele de control
Pentru a realiza rapid și sigur comunicația între două echipamente, trebuie ca transferul de date să țină cont de unele situații specifice. De exemplu, se poate întâmpla ca unul din echipamente să nu poată primi date datorită faptului că nu mai are unde să le depună. Într-un asemenea caz el trebuie să informeze transmițătorul că trebuie să aștepte. Se definesc următoarele semnale de control mai des utilizate:
DTR (Data Terminal Ready) – După alimentarea terminalului și după ce trece prin rutinele de inițializare, el trimite semnalul DTR ce indică faptul că este gata pentru comunicație. Semnalul este de intrare pentru modem (DCE).
DSR (Data Set Ready) – Este un semnal emis de DCE (modem) ce indică că este gata să primească date de la DTE.
RTS (Request to Send) – Este un semnal prin care DTE informează DCE că poate să transmită o dată.
CTS (Clear to Send) – Este un semnal de răspuns pentru semnalul RTS prin care DCE informează DTE că este gata să primească date. Acest semnal este utilizat de DTE pentru a începe transmisia datelor.
Conectarea microcontroler-ului ATTINY2313 la interfața serială RS232
Conectarea unui microcontroler ATTINY2313 la PC se poate face pe portul serial COM2 deoarece COM1 se utilizează de obicei pentru mouse. ATTINY2313 are doi pini numiti TxD și RxD ce sunt funcții alternative ale portului PD (PD.0 și PD.1). acești pini sunt compatibili TTL, prin urmare este nevoie de un circuit de adaptare pentru conversia nivelelor. De exemplu, se poate utiliza circuitul MAX232 al fimei Maxim sau un echivalent. Acest circuit convertește nivelele TTL în nivele RS232 și invers (fig. 5.5).
Un avantaj al acestui circuit este faptul că utilizează o singură tensiune de 5 V. Conține două canale deci se poate utiliza pentru două interfețe seriale RS232. Circuitul are nevoie de patru condensatoare având valoarea cuprinsă între 1 și 22 μF (de obicei se utilizează 22 μF).
Figura 5.5. Interfața serială realizată cu MAX232
Descrierea driver-ului/ receiver-ului MAX232
Figura 6.1. Pinii MAX232
MAX232 este un driver/ receiver dual ce conține un generator capacitiv de tensiune ce trebuie să alimenteze nivelele de tensiune TIA/ EIA-232-E de la o singură sursă de alimentare de 5 V [12]. Fiecare receptor convertește intrarea TIA/ EIA-232-E la nivele de 5 V TTL/ CMOS. Aceste receptoare au o limită tipică de 1.3 V, un histerezis tipic de 0.5 V și poate accepta intrări de ±30 V. Fiecare driver convertește nivelele de intrare TTL/CMOS în nivele TIA/EIA-232-E.
Caracteristici:
Operează la viteze de până la 120 kbit/s;
Conține 2 drivere și 2 receptoare;
Curent de alimentare jos, tipic 8 mA;
Aplicații:
TIA/EIA-232-E;
sisteme de alimentare pe baterii;
terminale;
modemuri;
computere.
Deci rolul unui MAX232 și cam a tuturor driverelor/receptoarelor din familia MAX este să translateze semnalele de tip RS232 care au ca nivele logice maxime pe 1 de +12 V și pe 0 de -12 V la semnale TTL pe 1 cu 2.5-5 V și pe 0 cu 0-0.7 V aproximativ.
Tabel 6.1, 6.2. Tabele cu funcțiuni
unde H-nivel înalt, L-nivel coborât
Figura 6.2. Diagrama logică (logic pozitiv)
În figura 6.2. avem felul în care circulă un semnal prin MAX232. Observăm că prin T1IN/T2IN este preluat semnalul TTL/CMOS din circuit și este trimis la ieșire prin T1OUT/T2OUT spre o interfață RS232, în principiu spre un conector serial DB9 sau în variante mai vechi DB25. Prin R1IN/R2IN semnalul este preluat de la RS232, conectori, și este transmis spre R1OUT/R2OUT în circuitul din care face parte montajul. În figura 6.3 avem o vedere mai clară a componentelor acestui convertor MAX232.
Figura 6.3. Circuit operațional tipic MAX232
Suportul software al sistemului de control acces cu button Dallas – SAM
7.1. Generalități
Suportul software al sistemului de acces folosit de mine este HyperTerminal. Acesta este un program de comunicație utilitar ce se distribuie împreună cu platforma de operare Windows. În caz de nevoie programul poate fi descărcat de la adresa “http://www.hilgraeve.com”. Programul este folosit în general pentru primirea și trimiterea caracterelor pe portul serial.
Inițial acest program era cunoscut sub denumirea de “HyperACCESS” [22]. A fost primul produs software a firmei Hilgraeve și a fost proiectat pentru comunicația calculatoarelor pe 8 biți de tip Heath cu un modem. În 1985 acest produs a fost trecut pe PC-urile IBM. De-a lungul anilor aceeași versiune a tehnologiei avea să fie preluată și de sistemele de operare ce includeau OS/2, Windows 95 și Windows NT.
În 1995 cei de la Hilgraeve a dat sub licență firmei Microsoft o versiune “Lite” a programului HyperACCESS cunoscută sub numele de HyperTerminal pentru utilizarea acestuia în cadrul setului de utlitare destinate comunicației. Inițial a fost implementat în platforma Windows 95 și rând pe rând toate versiunile de windows au avut în componență acest utilitar inclusiv Windows XP. Ultima versiune de windows, Vista, nu are în componență standardul program HyperTerminal dar în schimb suportă produsele comerciale HyperTerminal Private Edition cu ultima versiune 6.4 și HyperACCESS-ul cu ultima versiune 8.4. Într-un final în februarie 2008 bunurile firmei Hilgraeve au fost cumpărate de cei de la Covisint.
Programul HyperTerminal poate fi accesat în două moduri din meniul start. Primul mod este urmând calea „Start -> Programs -> Accessories -> HyperTerminal” (la Windows XP „Accesories” are un director „Communications” unde găsim HyperTerminal-ul). Al doilea mod mai simplu de accesare al programului este prin meniul „Run” din „Start”. Aici se tastează „hypertrm” ca în figura 7.1 și se apasă „OK”.
Figura 7.1 Accesarea HyperTerminal-ului din Run
La accesarea HyperTerminal-ului prima fereastră ajută la crearea unei conexiuni. Se face selecția iconiței dorite din meniu și se dă un nume conexiunii ca în figura 7.2. Numele și iconița conexiunii pot fi schimbate și din program urmând calea File -> Properties -> Change Icon. La apăsarea butonului „OK” mai departe ne apare fereastra de alegere a portului de comunicație COM1, COM2 sau alte porturi ce sunt disponibile pe sistem (figura 7.3). E bine să se cunoască ce porturi de comunicație (COM-uri) pot fi folosite. În cadrul sistemelor vechi COM1 era asignat mouse-urilor urmând ca următoarele porturi (COM2, COM3, etc) să poată fi folosite în alte scopuri. După selectarea portului se apasă tasta „OK” și mai departe ni se cere a se face setările portului selectat (figura 7.4).
Figura 7.2 Numirea conexiunii Figura 7.3 Selecția portului de comunicație
În general, ca și în cazul acesta de altfel, se lucrează cu setările implicite ale portului. Pentru obținerea setărilor implicite se apasă tasta „Restore Defaults”. La apăsarea tastei „OK” ia final configurarea conexiunii intrându-se în programul
propriu-zis.
Interfața sistemului meu de acces a fost concepută sub forma unui meniu ce se încarcă automat în HyperTerminal la conectarea pe serială a suportului hardware. În caz că nu se încarcă automat meniul se apasă butonul reset prevăzut pe cutia sistemului de acces. Meniul menționat mai devreme cuprinde patru opțiuni ca în figura 7.5. Acestea sunt:
Listă chei
Adaugă cheie
Șterge cheie
Reinițializare sistem
Figura 7.4 Setările portului de Figura 7.5 Meniul de acces
comunicație
Selecția tuturor opțiunilor din meniu se face după numărul de ordine. Prima opțiune „Listă chei” ne afișează lista tuturor cheilor memorate în EEPROM-ul microcontrolerului ca în figura 7.6. După cum putem vedea în figură orice cheie este memorată după numărul de ordine, serie și nivelul de acces. Acest sistem poate memora un număr de 16 chei. Seria cheii este formată din 12 caractere (cifre sau litere) care este introdusă manual în listă. Nivelurile de acces folosite sunt Master Key, Paza, Management și Personal. A doua opțiune din meniu „Adaugă cheie” este opțiunea de adăugare a cheilor. La apăsarea tastei 2 din meniul principal se accesează această optiune. Prima dată se cere indicarea locației de memorie unde va fi pusă cheia. Se indică un număr de la 0 la 9 sau în continuare o literă de la A la F. După memorarea locației se cere introducerea seriei cheii formată din 12 caractere. După serie se cere introducerea nivelului de acces indicată printr-o cifră de la 1 la 4. A treia opțiune din meniul principal este ștergere cheie. La accesarea acestei opțiuni cu cifra 3 ni se cere locația respectivei chei ce se dorește a fi ștearsă. O dată dezactivată respectiva locație de memorie a cheii folosirea respectivei chei nu mai poate anclanșa releul. Ultima opțiune din meniul principal este echivalentul butonului de reset de pe partea hardware. Această opțiune are ca efect reinițializarea interfeței având loc o reîncărcare a meniului. Acest meniu a fost scris în microcontroler cu ajutorul programului AvrStudio 4. Codul aplicației il găsim la anexe.
Figura 7.6 Opțiunea de listare a cheilor
Funcționarea unui sistem de acces cu buton Dallas-SAM
8.1. Generalități
Schema acestui montaj o putem găsi în anexa 1.
La atingerea butonului Dallas de cititor este generat un impuls de prezență ce ajunge la microcontroler prin pinul 6 (PD2) generându-se o întrerupere. Această linie este o linie de intrare în microcontroler a semnalului 1-wire. Dioda zener ZD1 are rol de protecție a semnalului la fel ca și rezistența R1. Prin pinul 7 sau PD3 este transmis impulsul de reset la tranzistorul MOFFSET T1. Acesta este ca o poartă permițând sau nepermițând trecerea semnalului. O dată ce a fost atinsă cheia de cititor și recunoscută timp de câteva secunde orice alt contact cu o altă cheie va fi ignorat tranzistorul menționat mai devreme având un rol destul de important în acest sens. Transmisia 1-wire este una full duplex după cum se observă. Frecvența de ceas a microcontrolerului este dată de cuarțul Q de 8 MHz conectat la pinii 4 (XTAL2) și 5 (XTAL1).
În momentul în care este detectat un semnal de prezență pe linie se aprinde atât ledul verde de pe placă cât și ledul roșu situat pe carcasă, acestea fiind conectate în paralel pe placă. Sunt conectate la pinul 19 (PB7) al microcontrolerului. Tot la detectarea semnalului de prezență un buzzer situat la pinul 18 (PB6) bipuie la o frecvență de 4 KHz . Felul în care bipuie depinde de cheie dacă aceasta este în memoria EEPROM a microcontrolerului sau nu. Dacă cheia nu e în memoria microcontrolerului sau dacă contactul de cititor se face cu o șurubelniță de exemplu buzzerul bipuie o singură dată scurt. În cazul în care contactul este cu o cheie aflată în memoria cipului buzzerul scoate un sunet liniar timp de aproximativ 4 secunde având loc și anclanșarea releului în acest interval de timp. Rezistențele R5, R6 și R7 sunt rezistențe de limitare a curentului.
În pinul 1 de reset este conectat un întrerupător K1 care în cazul nostru este sub forma unui buton. Acesta este situat atât pe placă cât și în exterior. Rolul său este de resetare a sistemului. Releul este conectat la microcontroler prin pinul 11 (PD6). Tranzistorul T2 are rol de comandă a releului, iar dioda D2 de protecție la tensiune autoinductivă. Prin pinii 2 (PD0) și 3 (PD1) se face comunicația serială cu MAX232 și mai departe cu calculatorul. Pinul PD1 este folosit pentru transmisie, iar PD0 pentru recepție. MAX232 se conectează la acest microcontroler prin pinii 10 (Tx2in) și 9 (Rx2out). Condensatoarele C7, C8, C9 și C10 conectate în paralel la pinii MAX232-ului au rolul de acumularea a energiei în dublor și a tensiunii în inversor. Alimentarea se face prin pinii 15 (GND) și 16 (Vcc). Transferul de date propriu-zis cu calculatorul se face cu ajutorul conectorului DB9 de tip mamă. Printr-un cablu serial se conectează în spatele calculatorului la un port serial de timp tată.
Alimentarea circuitului se face cu o sursă. Aceasta primește tensiunea exterioară de la priză de 220 V și o aduce la 5 V pentru o funcționare optimă a întregului asamblu prezentat. Condensatoarele C1, C2, C3 și C4 au rolul de filtrare a tensiunii. Puntea redresoare are rolul de a stabiliza tensiunea alternativă de 220 V venită din cablul de alimentare la 10 V. Regulatorul de tensiune U1 7805 oferă o stabilitate a acestei tensiuni la 5 V și transformă curentul din alternativ în continuu. La intrare a fost montată o siguranță fuzibilă pentru protecția la supratensiuni. Sursa o avem reprezentată de asemeni în prima anexă.
Mai specificăm că în cazul în care se dorește un cablu mai lung de 30 metri pentru cititor trebuie schimbată și recalculată valoarea rezistenței R1 la 1K2 (minim 800) pentru eliminarea perturbațiilor.
Aplicații
Conceptul de iButton are o gamă largă de aplicații, sistemul de acces descris de mine în această lucrare fiind doar unul din ele.
Un exemplu interesant de aplicație folosită cu succes în Brazilia este cel pentru parcarea pe străzile aglomerate dezvoltat de firma FlexPark [14]. În oraș sunt instalate peste 1000 de contoare de parcare bazate pe iButton. Contoarele de parcare sunt concepute cu două cititoare iButton și două ecrane LCD astfel încât fiecare contor să deservească două locuri de parcare de o parte și de alta a aparatului. Utilizatorul atinge cheia iButton de cititorul aparatului pentru a descărca credit în acesta și permite parcării mașinii personale timp de treizeci minute.
Aceeași operațiune este făcută cu cheia și la întoarcerea utilizatorului la autovehicul, restul timpului nefolosit asociat parcării fiind raportat și utlilizabil la o parcare viitoare. Fiecare contor de parcare este amplasat lângă un chioșc unde se poate achiziționa contracost credit pentru iButton.
Folosind acest sistem de parcare inteligent se evită furturile și vandalismul acestora deoarece acestea nu conțin valori. Contoarele au o viață a bateriei mare și durabilitate în comparație cu alte sisteme bazate pe RFID (Radio Frequency Identification) sau smartcard. O imagine cu acest sistem avem în figura 9.1.
O altă aplicație interesantă tot legată de mașini e folosirea unui sistem cu computer de bord pentru siguranță în trafic activat cu cheia iButton [15]. Acest sistem este asemeni unei cutii negre de pe avioane și poate monitoriza cam tot ce se întâmplă cum mașina, lucruri cum ar fi viteza, frânarea, virajele și așa mai departe. Este proiectat pentru a ne arăta ce fel de șoferi suntem. Este ușor de ascuns dar imposibil de uitat. Înainte de a se porni mașina șoferul trebuie să se logheze cu o
Figura 9.1. Sistem de parcare iButton cu cheie specifică
cheie iButton pentru autentificare. Din acel punct orice mișcare făcută este înregistrată strict. Dispozitivul monitorizează viteza în viraje sau dacă frânezi prea repede. Atâta timp cât condusul este lin și constant dispozitivul este silențios. Dar când are loc o accelerare mai bruscă oricât de mică ar fi dispozitivul începe să scoată un sunet de țăcănit. Același lucru se întâmplă și în regim de viteză. Aceste sunete pot fi la un moment dat deranjante dacă persistă așa că singura metodă de a scăpa de ele este conducerea prudentă. La sfărșitul călătoriei se întocmește un raport în care ne sunt precizate date în legătură cu viraje luate brusc, porțiuni cu viteze excesive, etc. În figura 9.2 avem aspectul acestui dispozitiv.
Figura 9.2. Sistem de monitorizare a datelor pentru mașină
Alte aplicații ale acestor chei mai găsim în măsurarea temperaturii, a umidității, plata anumitor lucruri precum și verificarea lor, etc. Ca sistem de acces se mai poate folosi și la accesul unui utilizator la un calculator dotat cu un astfel de dispozitiv [16]. Cheia iButton este folosită pentru autentificare și numai posesorul cheii are acces la calculator. Dispozitivul este montat chiar în respectivul calculator de unde ia și alimentarea. Această aplicație este folositoare pentru controlul parental acolo unde există copii care au tendința să joace în mod abuziv jocuri. Un exemplu de astfel de montaj cu iButton ce este montat în serie cu calculatorul avem în figura 9.3 precum și semnificația cifrelor din figură.
Figura 9.3 Sistem iButton conectat pe calculator și semnificația cifrelor
Concluzii
Folosirea cheilor inteligente de tip iButton permite realizarea unor sisteme complexe de limitare a accesului sigure și ieftine. Codurile de acces memorate în iButton se pot schimba ușor fără a fi necesară înlocuirea acestora (o cheie este garantată la cel puțin zece ani de funcționare).
De asemenea acest sistem prezintă și un nivel destul înalt de securitate față de alte sisteme, falsificarea acestor chei fiind o operație destul de grea dacă nu imposibilă. Aceste chei sunt si foarte ușor de folosit fiind și destul de mici diametrul acestora nedepășind mărimea unei monede de un ban. Cu ajutorul sistemului de pontaj se permite o administrare a personalului mai strictă. În funcție de numărul de ore lucrat în fiecare zi calculat în acest sens după accesul în birou și introduse într-o bază de date se pot calcula salariile angajaților.
În cadrul realizării proiectului se poate constata finalizarea în mare parte a obiectului propus. S-a efectuat comunicația dintre calculator și circuit cu ajutorul unui cablu serial având la un capăt un conector DB9 de tip male ce se conectează la circuit și la celalălalt un conector DB9 de tip female ce se conectează la calculator, circuitul funcționând ca emițător și calculatorul ca receptor. Se pot stoca în memoria microcontrolerului pâna la douăzeci de chei slave plus cheia master. Accesul cu cheia slave se poate face în acest caz numai cu ajutorul cheii master ambele fiind în memorie. Am folosit în cadrul proiectului meu o singură cheie ce va fi implementată ca master. În loc de încuietoarea propriu-zisă cu yală am folosit un mecanism de anclanșare cu un releu, în acest fel fiind simulată descuierea și încuierea ușii. Suportul software folosit este un soft de pontaj ce a fost proiectat în Visual Basic.
Importanța asigurării securității instituțiilor a crescut exponențial, în aces sens controlul accesului joacă un rol deosebit de important în planul organizatoric general de securitate. Sistemele de control acces au rolul de a limita și controla accesul personalului în zone de interes și securitate, putând ușor prelua și funcția de evidență a prezenței personalului în program. Ca sistem de securitate, sistemul de control acces este flexibil și modular, ceea ce permite extinderea pe etape a acestuia la cererea și resurselor clientului.
În prezent soluția cea mai des adoptată pe plan mondial este utilizarea cartelelor de proximitate, a cartelelor magnetice, a tagurilor RFID sau a tastaturilor cu cod de acces și implementarea unui software adecvat pentru controlul fluxului de personal și/sau valori. Deși sistemele bazate pe butoane Dallas sunt apărute încă de la mijlocul anilor ’90 nu sunt la fel de folosite ca cele enumerate mai devreme, cel puțin la noi, dar încetul cu încetul acest sistem relativ nou va fi din ce în ce mai folosit.
Tendința de integrare prin software a sistemelor de control acces, detecție a începutului de incendiu, protecție la efracție și supraveghere video transferă aplicațiile complexe din domeniul abstract în cel concret.
Sistemul este supervizat de un calculator care preia informațiile de la cititor și le procesează în vederea întocmirii anumitor rapoarte și memorarea lor într-o bază de date.
Conceptul de iButton are o gamă largă de aplicații, sistemul de acces descris de mine în această lucrare fiind doar unul din ele. Alte posibile aplicații au fost descrise în capitolul anterior.
Bibliografie
http://pdfserv.maxim-ic.com/en/an/appibstd.pdf
http://www.demiurg.pl/eng/czytniki.html
http://www.demiurg.pl/diagram.html?co=diagram3&co1=Diagram
http://www.demiurg.pl/diagram.html?co=connect1&co1=Connection%20diagram
http://www.demiurg.pl/diagram.html?co=diagram4a&co1=Diagram
http://www.demiurg.pl/diagram.html?co=orange2&co1=Orange%20colour
http://www.demiurg.pl/diagram.html?co=connect2&co1=Connection%20diagram
http://www.utgjiu.ro/conf/8th/S5/16.pdf
http://www.atmel.com/dyn/resources/prod_documents/doc2543.PDF
http://www.alingliga.go.ro/diploma/cap3.pdf
http://comunicatii.referate.bubble.ro/transmisia_seriala_date/
http://focus.ti.com/lit/ds/symlink/max232.pdf
http://dimelec.web1000.com/EN-lock.html
http://www.maxim-ic.com/products/ibutton/applications/index.cfm?Action=DD&id=-2
http://www.maxim-ic.com/products/ibutton/applications/index.cfm?Action=DD&id=25
http://www.demiurg.pl/eng/instr_en.pdf
Revista “Conex Club”, nr. 10/2003
http://pdfserv.maxim-ic.com/en/an/appibstd.pdf
http://www.asu.ro/acces.htm
http://www.asu.ro/pontaj.htm
Revista „Computerworld Romania”, nr. 3/1997
http://en.wikipedia.org/wiki/Hyperterminal
Anexa 1. Schema principală cu sursa de alimentare
Anexa 2. Cablaj schemă principală cu sursa de alimentare
Anexa 3. Schema interfeței RS232
Anexa 4. Cablajul interfeței RS232
Anexa 5. Sistemul de acces folosit cu cheie (vedere de sus și vedere laterală)
Anexa 6. Codul microcontrolerului ATTINY2313
.include "tn2313def.inc"
.include "eLook.inc"
;
.set ATTiny2313 = 1 ; USART …
;**************************************************************************
;* Reset and Interrupt Vectors
;**************************************************************************
.cseg
.org $0000 ; Reset handler
rjmp reset
.org INT0addr ; External Interrupt0
rjmp INT0isr
.org INT1addr ; External Interrupt1 , 1 wire
rjmp reset
.org ICP1addr ; Input capture interrupt 1
rjmp reset
.org OC1Aaddr ; Timer/Counter1 Compare Match A
rjmp reset
.org OVF1addr ; Overflow1 Interrupt
reti
.org OVF0addr ; Overflow0 Interrupt
reti
.org URXC0addr ; USART0 RX Complete Interrupt
rjmp UARTRCV
.org UDRE0addr ; USART0 Data Register Empty Interrupt
reti
.org UTXC0addr ; USART0 TX Complete Interrupt
reti
.org ACIaddr ; Analog Comparator Interrupt
rjmp reset
.org PCIaddr ; Pin Change Interrupt
rjmp reset
.org OC1Baddr ; Timer/Counter1 Compare Match B
rjmp reset
.org OC0Aaddr ; Timer/Counter0 Compare Match A
rjmp reset
.org OC0Baddr ; Timer/Counter0 Compare Match B
rjmp reset
.org USI_STARTaddr ; USI start interrupt
rjmp reset
.org USI_OVFaddr ; USI overflow interrupt
rjmp reset
.org ERDYaddr ; EEPROM write complete
rjmp reset
.org WDTaddr ; Watchdog Timer Interrupt
rjmp reset
;**************************************************************************
;* INT
;**************************************************************************
INT0isr: ; External Interrupt 0
;„„„`
push Temp ; Save Temp then save status register.
in Temp, sreg
push Temp
;–
in Temp, MCUCR
andi Temp, 0b00000001 ; mask ISC00
cpi Temp, 0x01
breq Rising ; rising edge
;
Falling:
;„„„`
in Temp,MCUCR
sbr Temp, 1 ; ISC00 =1 , next int. on rising edge
out MCUCR, Temp
ldi Temp2, 0
out TCNT0, Temp2 ; init counter
rjmp INTdone
;
Rising:
;„„„
in Temp, MCUCR
cbr Temp, 1
out MCUCR, Temp ; ISC00 =0 , next int. on falling edge
in Temp, TCNT0 ; read time …
ldi Temp2, 0
out TCNT0, Temp2 ; reinit counter
cpi Temp, 55 ; min. presence pulse (60 us < tPDL < 240 us)
brlo Noise
cpi Temp, 250
brge Noise
sbr Flags, Presence+1 ;Set flag presence pulse detected
rjmp INTdone
;
Noise:
;„„`
rjmp INTdone
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UARTRCV: ; UART receive interrupt
;„„„`
push Temp ; Save Temp then save status register.
in Temp, sreg
push Temp
;–
in Temp, USR
in RxMemo, UDR ; Read the char.
sbr Flags, HostRx+1 ; Set flag …
; mov emp, RxMemo
; rcall USART_Transmit
;–––––––––––––––––––––––––
; exit int
;–––––––––––––––––––––––––
INTdone:
;„„„`
pop Temp ; Restore status regiser then restore Temp.
out sreg,Temp
pop Temp
reti
;**************************************************************************
;* End INT ;**************************************************************************
;**************************************************************************
;* Routine: main *
;* Purpose: *
;* Notes: *
;**************************************************************************
main:
;„„
rcall Delay_1s ; Wait 2 seconds for display to come up.
rcall Delay_1s
rcall crlf ; Start new line
rcall SendMessage ; Send welcome message
rcall SendMenu
clr Flags
wdr ; Reset the watchdog timer -make sure its not
clr BeepCnt0
clr BeepCnt1
sei ; Enable interrupts
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ main_loop:
;„„„„`
sbrc Flags, Presence ; test 1w
rjmp Beep
sbrc Flags,PresenceOK
rjmp KeyIn
wdr
sbrc Flags, HostRx ; Skip if Bit in Register is Cleared (rs232)
rjmp RS232Rx
sbrc Flags, HostSearchOk; "co"
rcall TxResponse
nop
wdr
rjmp main_loop
;~~~~~~~~~~~~~~~~~~~~~~~~~~
;…..
KeyIn: ; uLAN activity ( presence pulse detected )
;„„`
; ldi Temp, '*'
; rcall USART_Transmit
;– disable INT0 –
in Temp2, GIMSK
andi Temp2, 0b10111111 ; INT0 =0
out GIMSK, Temp2
;–
rcall ReadROMid ; send "read ROM Id" command
rcall Read_8B ; read ROM Id
;– enable INT0 –
in Temp2, GIMSK
ori Temp2, 0b01000000 ; INT0 =1
out GIMSK, Temp2
;–
rcall SendROMid ; RS232
rcall SearchKey
cbr Flags,PresenceOK +2 ; clear flag …
rjmp main_loop
;~~~~~~~~~~~~~~~~~~~~~~~~~~
;….
Beep:
;„„
cbi PORTB, LED_G_B ; turn on green LED
inc BeepCnt0
cpi BeepCnt0,0 ; If .. 2…
brne bCont
inc BeepCnt1
cpi BeepCnt1, 150
breq EndBeep ; end…
in Temp, PORTB
sbrc Temp, Buzer_B
cbi PORTB, Buzer_B ; beep
sbrs Temp, Buzer_B
sbi PORTB, Buzer_B
;
bCont:
;„„`
rjmp main_loop
;
EndBeep:
;„„„`
cbr Flags,Presence +1 ; clear flag …
rcall TestPresence ; noise ?
sbi PORTB, LED_G_B ; turn off green LED
cbi PORTB, Buzer_B ; turn off beep
clr BeepCnt0 ; init
clr BeepCnt1
rjmp main_loop
;~~~~~~~~~~~~~~~~~~~~~~~~~~
;…….
RS232Rx:
;„„„`
mov Temp, RxMemo ; echo, test
;rcall USART_Transmit
sbrc Flags, HostSearch ; 'c'
rjmp RxTst_o
;-
cpi Temp, 'c'
brne RxContF
sbr Flags,HostSearch +5 ; set flag (8)… 'c'
rcall USART_Transmit ; tst –
nop
cbr Flags,HostRx +1 ; clear flag …
rjmp main_loop
;
RxTst_o:
;„„„`
cpi Temp, 'o'
brne RxContO
nop
rcall USART_Transmit ; tst 2
sbr Flags,HostSearchOk +12 ; set flag (16)… 'co'
;
RxContO:
;„„„
cbr Flags,HostSearch +5 ; reset flag (8)… 'c'
;
RxContF:
;„„„`
cbr Flags,HostRx +1 ; clear flag …
cpi Temp, '1' ; menu
breq KeyList
cpi Temp, '2'
breq KeyAdd
cpi Temp, '3'
breq KeyDel1
cpi Temp, '4'
breq GoReset
rjmp main_loop
;……..
KeyDel1:
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
rjmp KeyDel
rjmp main_loop
;…….
GoReset:
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
rjmp reset
;…….
KeyList:
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
rcall crlf
rcall crlf
ldi Dly_2, 35
;
lpnxthdr1:
;„„„„
ldi Temp, '*'
rcall USART_Transmit
dec Dly_2
cpi Dly_2, 0x0
brne lpnxthdr1
rcall crlf
;-
ldi ZH, high(2*msgHead) ;Load high part of byte address into ZH
ldi ZL, low(2*msgHead) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
rcall crlf
;-
ldi Dly_2, 35
;
lpnxthdr2:
;„„„„
ldi Temp, '*'
rcall USART_Transmit
dec Dly_2
cpi Dly_2, 0x0
brne lpnxthdr2
rcall crlf
;–
clr EEAddr
;
lplst1:
;„„„
rcall read_eeprom_array ; value in r0
; SBRS r0, 0
rcall SendKeyRec ; send row
SBRS EEAddr,7
rjmp lplst1
;-
ldi Dly_2, 35
;
lpnxthdr3:
;„„„„
ldi Temp, '*'
rcall USART_Transmit
dec Dly_2
cpi Dly_2, 0x0
brne lpnxthdr3
rcall crlf
rjmp main_loop
; END KeyList
;
;……
KeyAdd:
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
rcall crlf
rcall crlf
;-
ldi ZH, high(2*msgAdd); Load high part of byte address into ZH
ldi ZL, low(2*msgAdd) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
ldi ZH, high(2*msgIndex) ; Load high part of byte address into ZH
ldi ZL, low(2*msgIndex) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
;-
uentry1:
;„„„`
wdr
sbrs Flags, HostRx
rjmp uentry1
cbr Flags,HostRx +1 ; clear flag …
mov Temp, RxMemo
rcall USART_Transmit ; echo
mov Temp, RxMemo
cpi Temp, 0x3A
brsh inhex
;
indec:
;„„`
andi Temp, 0x0F
rjmp StEEAddr
;
inhex:
;„„`
andi Temp, 0xDF ; caps.
subi Temp, 0x37
;
StEEAddr:
;„„„„
lsl Temp
lsl Temp
lsl Temp ; Temp = Temp * 8
mov EEAddr, Temp
;=
clr r0
rcall write_eeprom_array
inc EEAddr
rcall crlf
;-
ldi ZH, high(2*msgSerial)
ldi ZL, low(2*msgSerial)
rcall SendRomstring ; Send mesage
;;-
ldi Dly_2, 0x06 ; 12 char
clr ZH
ldi ZL, Buffer_end
;
uentry2:
;„„„`
wdr
sbrs Flags, HostRx
rjmp uentry2
cbr Flags,HostRx +1 ; clear flag …
mov Temp, RxMemo
rcall USART_Transmit ; echo
;-
mov Temp, RxMemo ; test 'copy buffer'
cpi Temp, ' '
breq KeyCopy
;-
st Z, Temp ; Store byte in RAM buffer
;-
uentry2a:
;„„„`
wdr
sbrs Flags, HostRx
rjmp uentry2a
cbr Flags,HostRx +1 ; clear flag …
mov Temp, RxMemo
rcall USART_Transmit ; echo
;-
mov Temp, RxMemo ; test 'copy buffer'
cpi Temp, ' '
breq KeyCopy
;-
ld Temp,Z ; reload first char (high nible)
rcall Hex2Bin
lsl Temp
lsl Temp
lsl Temp
lsl Temp ; align to MSB
st Z, Temp ; store high
mov Temp, RxMemo ; get low nible
rcall Hex2Bin
ld Temp2,Z
or Temp, Temp2
st Z+, Temp
;–
dec Dly_2
cpi Dly_2, 0x0
brne uentry2
;–––––––
StooreKey2EE:
;„„„„„„ ; store in EE
ldi Dly_2, 0x06 ; 6 byte
clr ZH
ldi ZL, Buffer_end
;
storeKloop:
;„„„„„
ld r0, Z+
rcall write_eeprom_array ; store
inc EEAddr
dec Dly_2
cpi Dly_2, 0x0
brne storeKloop
rjmp AccLevel
;
KeyCopy:
„„„„
ldi Temp, 0x0D ; CR
rcall USART_Transmit
ldi Temp, '>'
rcall USART_Transmit
ldi Temp, '>'
rcall USART_Transmit
rcall SendROMid ; display serial number
;;– ; copy last key to EEprom
ldi Dly_2, 0x06 ; 6 byte
clr ZH
ldi ZL, Buffer_begin+1; Z vector (pointer) , start buffer (RS232)
; inc EEAddr ; first is CRC
CopyKloop: ; RAM(1wire buff)
;„„„„„
ld r0, Z+
rcall write_eeprom_array ; store
inc EEAddr
dec Dly_2
cpi Dly_2, 0x0
brne CopyKloop
;
AccLevel:
;„„„„
rcall crlf
;-
ldi ZH, high(2*msgLevel)
ldi ZL, low(2*msgLevel)
rcall SendRomstring ; Send mesage
;
uentry3:
;„„„`
wdr
sbrs Flags, HostRx
rjmp uentry3
cbr Flags,HostRx +1 ; clear flag …
mov Temp, RxMemo
rcall USART_Transmit ; echo
;-
mov Temp, RxMemo
andi Temp, 0x07
mov r0, Temp
rcall write_eeprom_array ; store access level
rjmp main_loop
;; END KeyAdd
;………………………………………………………………..
Hex2Bin:
;„„„`
cpi Temp, 0x3A
brsh InHexa
;
InDeci:
;„„`
andi Temp, 0x0F
ret
;
InHexa:
;„„`
andi Temp, 0xDF ; caps.
subi Temp, 0x37
ret
;–––
;
; END KeyAdd
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
KeyDel:
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
rcall crlf
rcall crlf
;-
ldi ZH, high(2*msgDel); Load high part of byte address into ZH
ldi ZL, low(2*msgDel) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
ldi ZH, high(2*msgIndex); Load high part of byte address into ZH
ldi ZL, low(2*msgIndex); Load low part of byte address into ZL
rcall SendRomstring ; Send it
;-
usentry1:
;„„„`
wdr
sbrs Flags, HostRx
rjmp usentry1
cbr Flags,HostRx +1 ; clear flag …
mov Temp, RxMemo
rcall USART_Transmit ; echo
mov Temp, RxMemo
cpi Temp, 0x3A
brsh inphexa
;
inpdeci:
;„„`
andi Temp, 0x0F
rjmp StEEAddress
;
inphexa:
;„„`
andi Temp, 0xDF ; caps.
subi Temp, 0x37
;
StEEAddress:
;„„„„
lsl Temp
lsl Temp
lsl Temp ; Temp = Temp * 8
mov EEAddr, Temp
;=
ldi Temp,0xFF
mov r0 , Temp
rcall write_eeprom_array
rcall crlf
;–––––––-
ldi Temp,0x07
add EEAddr, Temp ; access level address
ldi Temp,0xFF
. mov r0, Temp
rcall write_eeprom_array
rjmp main_loop
; END KeyDel
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
; END main_loop
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; END main
;**************************************************************************
;* Routine: SearchKey *
;* Purpose: Search serial Key match in EEprom records *
;* Inputs: Buffer_begin ( ROM Id ) *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;……….
SearchKey:
;„„„„`
clr EEAddr ; point to first record in EE
inc EEAddr ; first is CRC
;
RecordsLoop:
;„„„„„`
clr ZH
ldi ZL, Buffer_begin+1 ; Z vector (pointer) , start buffer
sbr Flags,KeyMatch +27; set flag (32 = 5+27)…
;
TestLoop:
;„„„„`
ld r0,Z+ ; read buffer & inc. pointer
mov Dly_1,r0 ; save value
rcall read_eeprom_array ; read EEprom
mov Dly_2, r0 ; save value
cp Dly_1,Dly_2 ; compare
brne GoNextRec
; ok, next byte in record ?
inc EEAddr
mov Temp, EEAddr
andi Temp, 0x07
cpi Temp, 0x07
brne TestLoop ; not last, go next byte
rjmp FoundtMatch
;
GoNextRec:
;„„„„`
ldi Temp, 0xF8
and EEAddr, Temp ; record begin
ldi Temp, 0x09
add EEAddr, Temp ; next record address +1 ( skip CRC )
SBRS EEAddr,7 ; Test EEprom end … ( 128×8 -> 16 rec.)
rjmp RecordsLoop
;–
NoMatch:
;„„„`
ldi ZH, high(2*msgNone); msg "INTERZIS"
ldi ZL, low(2*msgNone)
rcall SendRomstring
ret ; no match found…
;
FoundtMatch:
;„„„„„„„„„„„„„„„„„„„„
rcall SendRights
;–
cbi PORTB, LED_G_B ; turn on green LED
sbi PORTD, Releu_B ; Rel. on
clr BeepCnt0
clr BeepCnt1
clr Dly_0
clr Dly_1
;
lpRelBeep:
;„„„„`
inc BeepCnt0
cpi BeepCnt0,0
brne lpRelBeep
wdr
inc Dly_0
cpi Dly_0,20
brne lpRelBeep
clr Dly_0
inc BeepCnt1
cpi BeepCnt1, 254
breq EndBeep1 ; end…
in Temp, PORTB
sbrc Temp, Buzer_B
cbi PORTB, Buzer_B ; beep
sbrs Temp, Buzer_B
sbi PORTB, Buzer_B
rjmp lpRelBeep
;
EndBeep1:
;„„„`
clr BeepCnt1
inc Dly_1
cpi Dly_1, 4
brne lpRelBeep ; end…
;;=
sbi PORTB, LED_G_B ; turn off green LED
cbi PORTD, Releu_B ; Rel. on
cbi PORTB, Buzer_B ; turn off beep
; clr BeepCnt0
clr BeepCnt1
ret
; END SearchKey
;**************************************************************************
;**************************************************************************
;* Routine: SendKeyRec *
;* Purpose: send EEprom record *
;* Inputs: EEAddr *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;……….
SendKeyRec:
;„„„„„
ldi Temp, '*'
rcall USART_Transmit
ldi Temp, ' '
rcall USART_Transmit
mov Temp, EEAddr
asr Temp
asr Temp
asr Temp ; /8
rcall Bin2Hex
rcall USART_Transmit ; crt.
mov Temp,Temp2
rcall USART_Transmit
ldi Temp, ' '
rcall USART_Transmit
ldi Temp, '*'
rcall USART_Transmit
ldi Temp, ' '
rcall USART_Transmit
;-
ldi Dly_2, 0x06
;
lpnxtbt:
;„„„`
inc EEAddr
rcall read_eeprom_array ; value in r0
mov Temp, r0
rcall Bin2Hex
rcall USART_Transmit ; crt.
mov Temp,Temp2
rcall USART_Transmit
dec Dly_2
cpi Dly_2, 0x0
brne lpnxtbt
inc EEAddr
rcall SendRights
;
SendKeyEND:
;„„„„„
inc EEAddr ;next ….
rcall crlf
ret
; END SendKeyRec
;**************************************************************************
;* Routines: SendRights *
;* Purpose: send access rights on RS232 *
;* Inputs: EEAddr *
;* Outputs: *
;* Exit: *
;* Notes:
;**************************************************************************
;……….
SendRights:
;„„„„„
rcall read_eeprom_array
mov Temp, r0
cpi Temp, 0x00
brne FGuard
;
FMaster:
;„„„`
ldi ZH, high(2*msgMaster) ; Load high part of byte address into ZH
ldi ZL, low(2*msgMaster) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
ret
;
FGuard:
;„„„
cpi Temp, 0x01
brne FSUser
ldi ZH, high(2*msgGuard)
ldi ZL, low(2*msgGuard)
rcall SendRomstring
ret
;
FSUser:
;„„„
cpi Temp, 0x02
brne FUser
ldi ZH, high(2*msgSUser)
ldi ZL, low(2*msgSUser)
rcall SendRomstring
ret
;
FUser:
;„„`
cpi Temp, 0x03
brne FNone
ldi ZH, high(2*msgUser)
ldi ZL, low(2*msgUser)
rcall SendRomstring
ret
;
FNone:
;„„`
ldi ZH, high(2*msgNone)
ldi ZL, low(2*msgNone)
rcall SendRomstring
ret
; END SendRights
;**************************************************************************
;* Routines: 1 wire *
;* Purpose: read data from 'DS1990' *
;* Inputs: *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;–––––––––––––––––––-
;| ReadROMid command ( 0x33 ) |
;–––––––––––––––––––-
ReadROMid:
;„„„„`
rcall w1_one ; LSB first …
rcall w1_one
rcall w1_zero
rcall w1_zero
rcall w1_one
rcall w1_one
rcall w1_zero
rcall w1_zero
ret
;–––––––––––––––––––-
;| Read 8 byte |
;–––––––––––––––––––-
Read_8B:
;„„„`
clr ZH
ldi ZL, Buffer_end ; 0x68
lp_Bytes:
;„„„„
dec ZL ; buffer index –
ldi Dly_2, 0x08
clr w1Byte
;
lp_bits:
;„„„`
asr w1Byte ; Arithmetic Shift Right,
; prepare for next bit
andi w1Byte,0x7F ; clear b7
sbi PORTD, w1nonTx ; Tx=1 , bus = 0
nop ; delay
nop
nop
nop
cbi PORTD, w1nonTx ; Tx=0 , bus = 1
rcall w5us ; read slot begin
in Temp2,PIND ; read 1 wire bus (b2)
sbrc Temp2, w1Rx
sbr w1Byte, 0x80 ; store bit
rcall w60us
dec Dly_2
brne lp_bits ; 8 bits ?
st Z, w1Byte ; Store byte in RAM buffer
cpi ZL, Buffer_begin ; 0x60
brne lp_Bytes ; 8 Bytes
ret ; done
;–––––––––––––––––––-
;| 1 wire , write 'one' |
;–––––––––––––––––––-
w1_one:
;„„„
sbi PORTD, w1nonTx ; Tx=1 , bus = 0
rcall w5us ; wait 5 microseconds
cbi PORTD, w1nonTx ; Tx=0 , bus = 1
rcall w60us
ret
;–––––––––––––––––––-
;| 1 wire , write 'zero' |
;–––––––––––––––––––-
w1_zero:
;„„„`
sbi PORTD, w1nonTx ; Tx=1 , bus = 0
rcall w60us
cbi PORTD, w1nonTx ; Tx=0 , bus = 1
rcall w5us
ret
;–––––––––––––––––––-
;| test |
;–––––––––––––––––––-
TestPresence:
;„„„„„„
test:
;„„
;– disable INT0 –
in Temp2, GIMSK
andi Temp2, 0b10111111 ; INT0 =0
out GIMSK, Temp2
;–
nop
nop
sbi PORTD, w1nonTx ; Tx=1 , bus = 0
rcall w480us ; 480 ms < tRSTL
cbi PORTD, w1nonTx ; Tx=0
rcall w30us
rcall w30us ; 15 ms < tPDH < 60 ms
in Temp2,pind ; read 1 wire bus
sbrs Temp2, w1Rx ; b2
sbr Flags,PresenceOK +2 ; set flag … key present
tstj:
;
rcall w480us
;– enable INT0 –
in Temp2, GIMSK
ori Temp2, 0b01000000 ; INT0 =1
out GIMSK, Temp2
;–
cbr Flags,Presence +1
ret
;–––––––––––––––––––-
;| test |
;–––––––––––––––––––-
; END 1 wire
;**************************************************************************
;* Routine: read_eeprom_array *
;* Purpose: read data from the internal processor EEprom *
;* Inputs: EEAddr = address of EEprom data to read *
;* Outputs: r0 = data read from EEprom *
;* Exit: *
;* Notes: *
;**************************************************************************
;……………..
read_eeprom_array:
;„„„„„„„„`
in Temp, SREG ; store SREG value
cli ; disable interrupts during timed sequence
;
read_eeprom_array_1:
;„„„„„„„„„`
sbic EECR,EEWE ; if EEWE not clear
rjmp read_eeprom_array_1; wait more
out EEAR, EEAddr ; output address low
sbi EECR, EERE ; set EEPROM Read strobe
; This instruction takes 4 clock cycles since
; it halts the CPU for two clock cycles
in r0, EEDR ; get data
out SREG, Temp ; restore SREG value (I-bit)
ret
; END read_eeprom_array
;**************************************************************************
;* Routine: write_eeprom_array *
;* Purpose: write data to the internal processor EEprom *
;* Inputs: EEAddr = address of EEprom data to read *
;* r0 = data to write to EEprom *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;………………
write_eeprom_array:
;„„„„„„„„„
in Temp, SREG ; store SREG value
cli ; disable interrupts during timed sequence
;
write_eeprom_array_1:
;„„„„„„„„„„
sbic EECR, EEPE ; if EEWE not clear
rjmp write_eeprom_array_1 ; wait more
out EEAR, EEAddr ; output address low
out EEDR, r0
sbi EECR, EEMPE ; set master write enable
sbi EECR, EEPE ; set EEPROM Write strobe
; This instruction takes 4 clock cycles since
; it halts the CPU for two clock cycles
out SREG, Temp ; restore SREG value (I-bit)
ret
; END write_eeprom_array
;**************************************************************************
;* Routine: USART_Transmit *
;* Purpose: Send Char via UART, preserves content ( RS232 ) *
;* Inputs: Temp = string to send *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;…………..
USART_Transmit:
;„„„„„„„
.IFDEF ATTiny2313
;„„„„„„„„
sbis UCSRA,UDRE
.ELSE
sbis USR,udre
.ENDIF
rjmp USART_Transmit ; Wait for empty transmit buffer
out UDR,Temp ; Put data into buffer, sends the data
ret
; END USART_Transmit
;**************************************************************************
;* Routine: crlf *
;* Purpose: Send CR LF (new line) *
;* Inputs: none *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;….
crlf:
;„„
ldi Temp,$0A ; LF
rcall USART_Transmit
ldi Temp,$0D ; CR
rcall USART_Transmit
ret
; END crlf
;**************************************************************************
;* Routine: SendROMid *
;* Purpose: Send Dallas DS1990 ROM ID ( serial number ) *
;* Inputs: none *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;………
SendROMid:
;„„„„`
clr ZH
ldi ZL, Buffer_begin+1 ; 0x60
rcall crlf ; new line
lp_snd:
;„„„
ld Temp,Z+ ; load byte from RAM buffer & post increment
rcall Bin2hex
rcall USART_Transmit
mov Temp, Temp2
rcall USART_Transmit
cpi ZL, Buffer_end-1 ; 0x67
brne lp_snd ; 6 Bytes
ret
; END SendROMid
;**************************************************************************
;* Routine: Bin2hex *
;* Purpose: BIN -> HEX *
;* Inputs: Temp , bin value * *
;* Outputs: Temp, Temp2 *
;* Exit: *
;* Notes: *
;**************************************************************************
;…….
Bin2hex:
;„„„`
mov Temp2, Temp ; copy value
ldi Dly_0, 0x30
ldi Dly_1, 0x07
asr Temp
asr Temp
asr Temp
asr Temp
andi Temp, 0x0F ; mask
cpi Temp, 0x0A ; convert to ASCII
brlt numm ; < 10
add Temp, Dly_1 ; > 9
numm:
add Temp, Dly_0
;-
andi Temp2, 0x0F
cpi Temp2, 0x0A ; convert to ASCII
brlt numm2 ; < 10
add Temp2, Dly_1 ; > 9
numm2:
add Temp2, Dly_0
ret
; END Bin2hex
;**************************************************************************
;* Routine: Delay_1s *
;* Purpose: delay , 1 second *
;* Inputs: none * *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
Delay_1s:
;„„„„
nop
ret
; END Delay_1s
;**************************************************************************
;* Routine: Delay *
;* Purpose: delay … *
;* Inputs: *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;–––––––––––––––––––-
;| w5us |
;–––––––––––––––––––-
w5us:
;„„
ldi Dly_0,12 ;1~
dlp01:
dec Dly_0 ;1~
brne dlp01 ;2~ 1+(1+2)*13+4=242=5.5us
ret ;4~
;–––––––––––––––––––-
;| Delay 30us(1+(1+2)*79+4=242=30.25us) |
;–––––––––––––––––––-
w30us:
;„„`
ldi Dly_0,79 ;1~
dlp02:
dec Dly_0 ;1~
brne dlp02 ;2~ 1+(1+2)*79+4=242=30.25us
ret ;4~
;–––––––––––––––––––-
;| w60us(1+(1+2)*160+4=125~=60.62us) |
;–––––––––––––––––––-
w60us:
;„„`
ldi Dly_0,160 ;1~
dlp03:
dec Dly_0 ;1~
brne dlp03 ;2~
ret ;4~
;–––––––––––––––––––-
;| w300us |
;–––––––––––––––––––-
w300us:
;„„„
ldi Dly_0,0x4
dlp04:
ldi Dly_1,0xff
dlp05:
dec Dly_1
brne dlp05
dec Dly_0
brne dlp04
ret
;–––––––––––––––––––-
;| w480us |
;–––––––––––––––––––-
w480us:
;„„„
ldi Dly_0,0x5
dlp06:
ldi Dly_1,0xff
dlp07:
dec Dly_1
brne dlp07
dec Dly_0
brne dlp06
ret
;–––––––––––––––––––-
;| w200ms |
;–––––––––––––––––––-
w200ms:
;„„„
ldi Dly_2, 16 ;1~
dlp08:
ldi Dly_1,0x82 ;1~
dlp09:
ldi Dly_0,0xff ;1~
dlp10:
dec Dly_0 ;1~
brne dlp10 ;2~
dec Dly_1 ;1~
brne dlp09 ;2~
dec Dly_2 ;1~
brne dlp08 ;2~
ret ;4~
;–
; END Delay
;**************************************************************************
;* Routine: reset routines *
;* Purpose: init *
;* Inputs: *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
reset:
;„„`
; reset stack pointer
;–––––––
ldi Temp,low(RAMEND)
out SPL,Temp
; set up port B
;–––––
ldi Temp, DDRB_INIT
out DDRB, Temp ; set up port B direction
ldi Temp, PORTB_INIT
out PORTB, Temp ; set up port B data
; set up ports D
;–––––
ldi Temp, DDRD_INIT
out DDRD, Temp ; set up port D direction
ldi Temp, PORTD_INIT
out PORTD, Temp
; set up initial hardware registers
;–––––––––––-
.IFDEF ATTiny2313
;„„„„„„„„
ldi Temp, GIMSK_DATA ; int.
out GIMSK, Temp
ldi Temp, TIMSK_DATA
out TIMSK, Temp
ldi Temp, MCUCR_DATA ; edge
out MCUCR, Temp
ldi Temp, TCCR0_DATA
out TCCR0, Temp
ldi Temp, TCCR1A_DATA
out TCCR1A, Temp
ldi Temp, TCCR1B_DATA
out TCCR1B, Temp
ldi Temp, WDTCR_DATA
out WDTCR, Temp
;
.MESSAGE "ATTiny2313… USART config"
; USART
;––
ldi Temp, UCSRB_DATA
out UCSRB, Temp
ldi Temp, UCSRC_DATA
out UCSRC, Temp
ldi Temp, UBRRL_DATA
out UBRRL, Temp
ldi Temp, UBRRH_DATA
out UBRRH, Temp
ldi Temp, ACSR_DATA
out ACSR, Temp
.ELSE
;„„
.MESSAGE "AT90S2313… UART config"
;
ldi Temp,BAUD_VALUE_INIT
out UBRR,Temp ; Load baud rate.
sbi UCR,txen ; Enable UART transmitter.
sbi UCR,rxen ; Enable UART receiver.
sbi UCR,rxcie ; Enable UART receive interrupts.
wdr
; Reset the watchdog timer -make sure its ; not about to trip.
ldi Temp,0b00001111 ; Enable the watchdog
out wdtcr,Temp
.ENDIF
;
; enable Interrupts, and set up port directions
;–––––––––––––––-
sei
rjmp main
; END reset
;**************************************************************************
;* Routine: SendMessage
;* Purpose: Send welcome message
;* Inputs:
;* Outputs:
;* Exit:
;* Notes:
;**************************************************************************
SendMessage: ; Send welcome
;„„„„„`
ldi ZH, high(2*Message); Load high part of byte address into ZH
ldi ZL, low(2*Message) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
;
StringEnd:
;„„„„`
ret
;
SendRomstring: ; Send string pointed to by ZH,ZL.
;„„„„„„`
lpm ; Load byte from program memory into r0
tst r0 ; Check if we've reached the end of the message
breq StringEnd ; If so, return
wdr
mov Temp, r0
rcall USART_Transmit
adiw ZL, 1 ; Increment Z registers
rjmp SendRomstring
; END SendMessage
;……..
SendMenu:
;„„„„
ldi ZH, high(2*msgMenu) ; Load high part of byte address into ZH
ldi ZL, low(2*msgMenu) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
ret
; END SendMenu
;**************************************************************************
;* Routine: TxResponse
;* Purpose: Send response to host ( "co" )
;* Inputs:
;* Outputs:
;* Exit:
;* Notes:
;**************************************************************************
;……….
TxResponse:
;„„„„„
cbr Flags,HostSearchOk +12 ; reset flag (16)… 'c'
; 2008Locked
ldi Temp, '2'
rcall USART_Transmit
ldi Temp, '3'
rcall USART_Transmit
ldi Temp, '_'
rcall USART_Transmit
ldi Temp, '0'
rcall USART_Transmit
ldi Temp, '6'
rcall USART_Transmit
ldi Temp, '_'
rcall USART_Transmit
ldi Temp, '2'
rcall USART_Transmit
ldi Temp, '0'
rcall USART_Transmit
ldi Temp, '0'
rcall USART_Transmit
ldi Temp, '9'
rcall USART_Transmit
ldi Temp, 0x01
ret
;
; END TxResponse
;**************************************************************************
Message:
;„„„`
.db " Universitatea Stefan cel Mare "
.db $0A,$0D ; LF CR
.db " Suceava"
.db $0A,$0D ; LF CR
.db " Facultatea de Inginerie"
.db $0A,$0D ; LF CR
.db " Electrica "
.db $0A,$0D ; LF CR
.db " Sistem de acces cu buton Dallas"
.db $0A,$0D ; LF CR
.db $00,$00 ; null
msgMenu:
.db "**********************************"
.db $0A,$0D ; LF CR
.db "* MENU *"
.db $0A,$0D ; LF CR
.db "**********************************"
.db $0A,$0D ; LF CR
.db " [1] Lista chei"
.db $0A,$0D ; LF CR
.db " [2] Adauga cheie"
.db $0A,$0D ; LF CR
.db " [3] Sterge cheie"
.db $0A,$0D ; LF CR
.db " [4] Reinitializare sistem "
.db $0A,$0D ; LF CR
.db $00,$00 ; null
msgHead:
.db "* nr * Serie cheie * Nivel acces * "
.db $00,$00 ; null
msgMaster:
.db " * Master Key *"
.db $00,$00 ; null
msgGuard:
.db " * Paza … *"
.db $00,$00 ; null
msgSUser:
.db " * Management *"
.db $00,$00 ; null
msgUser:
.db " * Personal *"
.db $00,$00 ; null
msgNone:
.db " * INTERZIS *"
.db $00,$00 ; null
msgAdd:
.db "* Adauga sau modifica cheie…"
.db $0A,$0D ; LF CR
.db $0A,$0D ; LF CR
.db $00,$00 ; null
msgDel:
.db "* Dezactiveaza cheie… "
.db $0A,$0D ; LF CR
.db $0A,$0D ; LF CR
.db $00,$00 ; null
msgIndex:
.db " Index ? ( 0,..,9,A,..,F )"
.db $0A,$0D ; LF CR
.db ">>"
.db $00,$00 ; null
msgSerial:
.db " Serie ? ( 12 cifre hexazecimale )"
.db $0A,$0D ; LF CR
.db ">>"
.db $00,$00 ; null
msgLevel:
.db " Nivel acces ?"
.db $0A,$0D ; LF CR
.db "[0] Master Key"
.db $0A,$0D ; LF CR
.db "[1] Paza …"
.db $0A,$0D ; LF CR
.db "[2] Management"
.db $0A,$0D ; LF CR
.db "[3] Personal"
.db $0A,$0D ; LF CR
.db ">>"
.db $00,$00 ; null
.exit
Bibliografie
http://pdfserv.maxim-ic.com/en/an/appibstd.pdf
http://www.demiurg.pl/eng/czytniki.html
http://www.demiurg.pl/diagram.html?co=diagram3&co1=Diagram
http://www.demiurg.pl/diagram.html?co=connect1&co1=Connection%20diagram
http://www.demiurg.pl/diagram.html?co=diagram4a&co1=Diagram
http://www.demiurg.pl/diagram.html?co=orange2&co1=Orange%20colour
http://www.demiurg.pl/diagram.html?co=connect2&co1=Connection%20diagram
http://www.utgjiu.ro/conf/8th/S5/16.pdf
http://www.atmel.com/dyn/resources/prod_documents/doc2543.PDF
http://www.alingliga.go.ro/diploma/cap3.pdf
http://comunicatii.referate.bubble.ro/transmisia_seriala_date/
http://focus.ti.com/lit/ds/symlink/max232.pdf
http://dimelec.web1000.com/EN-lock.html
http://www.maxim-ic.com/products/ibutton/applications/index.cfm?Action=DD&id=-2
http://www.maxim-ic.com/products/ibutton/applications/index.cfm?Action=DD&id=25
http://www.demiurg.pl/eng/instr_en.pdf
Revista “Conex Club”, nr. 10/2003
http://pdfserv.maxim-ic.com/en/an/appibstd.pdf
http://www.asu.ro/acces.htm
http://www.asu.ro/pontaj.htm
Revista „Computerworld Romania”, nr. 3/1997
http://en.wikipedia.org/wiki/Hyperterminal
Anexa 1. Schema principală cu sursa de alimentare
Anexa 2. Cablaj schemă principală cu sursa de alimentare
Anexa 3. Schema interfeței RS232
Anexa 4. Cablajul interfeței RS232
Anexa 5. Sistemul de acces folosit cu cheie (vedere de sus și vedere laterală)
Anexa 6. Codul microcontrolerului ATTINY2313
.include "tn2313def.inc"
.include "eLook.inc"
;
.set ATTiny2313 = 1 ; USART …
;**************************************************************************
;* Reset and Interrupt Vectors
;**************************************************************************
.cseg
.org $0000 ; Reset handler
rjmp reset
.org INT0addr ; External Interrupt0
rjmp INT0isr
.org INT1addr ; External Interrupt1 , 1 wire
rjmp reset
.org ICP1addr ; Input capture interrupt 1
rjmp reset
.org OC1Aaddr ; Timer/Counter1 Compare Match A
rjmp reset
.org OVF1addr ; Overflow1 Interrupt
reti
.org OVF0addr ; Overflow0 Interrupt
reti
.org URXC0addr ; USART0 RX Complete Interrupt
rjmp UARTRCV
.org UDRE0addr ; USART0 Data Register Empty Interrupt
reti
.org UTXC0addr ; USART0 TX Complete Interrupt
reti
.org ACIaddr ; Analog Comparator Interrupt
rjmp reset
.org PCIaddr ; Pin Change Interrupt
rjmp reset
.org OC1Baddr ; Timer/Counter1 Compare Match B
rjmp reset
.org OC0Aaddr ; Timer/Counter0 Compare Match A
rjmp reset
.org OC0Baddr ; Timer/Counter0 Compare Match B
rjmp reset
.org USI_STARTaddr ; USI start interrupt
rjmp reset
.org USI_OVFaddr ; USI overflow interrupt
rjmp reset
.org ERDYaddr ; EEPROM write complete
rjmp reset
.org WDTaddr ; Watchdog Timer Interrupt
rjmp reset
;**************************************************************************
;* INT
;**************************************************************************
INT0isr: ; External Interrupt 0
;„„„`
push Temp ; Save Temp then save status register.
in Temp, sreg
push Temp
;–
in Temp, MCUCR
andi Temp, 0b00000001 ; mask ISC00
cpi Temp, 0x01
breq Rising ; rising edge
;
Falling:
;„„„`
in Temp,MCUCR
sbr Temp, 1 ; ISC00 =1 , next int. on rising edge
out MCUCR, Temp
ldi Temp2, 0
out TCNT0, Temp2 ; init counter
rjmp INTdone
;
Rising:
;„„„
in Temp, MCUCR
cbr Temp, 1
out MCUCR, Temp ; ISC00 =0 , next int. on falling edge
in Temp, TCNT0 ; read time …
ldi Temp2, 0
out TCNT0, Temp2 ; reinit counter
cpi Temp, 55 ; min. presence pulse (60 us < tPDL < 240 us)
brlo Noise
cpi Temp, 250
brge Noise
sbr Flags, Presence+1 ;Set flag presence pulse detected
rjmp INTdone
;
Noise:
;„„`
rjmp INTdone
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UARTRCV: ; UART receive interrupt
;„„„`
push Temp ; Save Temp then save status register.
in Temp, sreg
push Temp
;–
in Temp, USR
in RxMemo, UDR ; Read the char.
sbr Flags, HostRx+1 ; Set flag …
; mov emp, RxMemo
; rcall USART_Transmit
;–––––––––––––––––––––––––
; exit int
;–––––––––––––––––––––––––
INTdone:
;„„„`
pop Temp ; Restore status regiser then restore Temp.
out sreg,Temp
pop Temp
reti
;**************************************************************************
;* End INT ;**************************************************************************
;**************************************************************************
;* Routine: main *
;* Purpose: *
;* Notes: *
;**************************************************************************
main:
;„„
rcall Delay_1s ; Wait 2 seconds for display to come up.
rcall Delay_1s
rcall crlf ; Start new line
rcall SendMessage ; Send welcome message
rcall SendMenu
clr Flags
wdr ; Reset the watchdog timer -make sure its not
clr BeepCnt0
clr BeepCnt1
sei ; Enable interrupts
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ main_loop:
;„„„„`
sbrc Flags, Presence ; test 1w
rjmp Beep
sbrc Flags,PresenceOK
rjmp KeyIn
wdr
sbrc Flags, HostRx ; Skip if Bit in Register is Cleared (rs232)
rjmp RS232Rx
sbrc Flags, HostSearchOk; "co"
rcall TxResponse
nop
wdr
rjmp main_loop
;~~~~~~~~~~~~~~~~~~~~~~~~~~
;…..
KeyIn: ; uLAN activity ( presence pulse detected )
;„„`
; ldi Temp, '*'
; rcall USART_Transmit
;– disable INT0 –
in Temp2, GIMSK
andi Temp2, 0b10111111 ; INT0 =0
out GIMSK, Temp2
;–
rcall ReadROMid ; send "read ROM Id" command
rcall Read_8B ; read ROM Id
;– enable INT0 –
in Temp2, GIMSK
ori Temp2, 0b01000000 ; INT0 =1
out GIMSK, Temp2
;–
rcall SendROMid ; RS232
rcall SearchKey
cbr Flags,PresenceOK +2 ; clear flag …
rjmp main_loop
;~~~~~~~~~~~~~~~~~~~~~~~~~~
;….
Beep:
;„„
cbi PORTB, LED_G_B ; turn on green LED
inc BeepCnt0
cpi BeepCnt0,0 ; If .. 2…
brne bCont
inc BeepCnt1
cpi BeepCnt1, 150
breq EndBeep ; end…
in Temp, PORTB
sbrc Temp, Buzer_B
cbi PORTB, Buzer_B ; beep
sbrs Temp, Buzer_B
sbi PORTB, Buzer_B
;
bCont:
;„„`
rjmp main_loop
;
EndBeep:
;„„„`
cbr Flags,Presence +1 ; clear flag …
rcall TestPresence ; noise ?
sbi PORTB, LED_G_B ; turn off green LED
cbi PORTB, Buzer_B ; turn off beep
clr BeepCnt0 ; init
clr BeepCnt1
rjmp main_loop
;~~~~~~~~~~~~~~~~~~~~~~~~~~
;…….
RS232Rx:
;„„„`
mov Temp, RxMemo ; echo, test
;rcall USART_Transmit
sbrc Flags, HostSearch ; 'c'
rjmp RxTst_o
;-
cpi Temp, 'c'
brne RxContF
sbr Flags,HostSearch +5 ; set flag (8)… 'c'
rcall USART_Transmit ; tst –
nop
cbr Flags,HostRx +1 ; clear flag …
rjmp main_loop
;
RxTst_o:
;„„„`
cpi Temp, 'o'
brne RxContO
nop
rcall USART_Transmit ; tst 2
sbr Flags,HostSearchOk +12 ; set flag (16)… 'co'
;
RxContO:
;„„„
cbr Flags,HostSearch +5 ; reset flag (8)… 'c'
;
RxContF:
;„„„`
cbr Flags,HostRx +1 ; clear flag …
cpi Temp, '1' ; menu
breq KeyList
cpi Temp, '2'
breq KeyAdd
cpi Temp, '3'
breq KeyDel1
cpi Temp, '4'
breq GoReset
rjmp main_loop
;……..
KeyDel1:
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
rjmp KeyDel
rjmp main_loop
;…….
GoReset:
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
rjmp reset
;…….
KeyList:
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
rcall crlf
rcall crlf
ldi Dly_2, 35
;
lpnxthdr1:
;„„„„
ldi Temp, '*'
rcall USART_Transmit
dec Dly_2
cpi Dly_2, 0x0
brne lpnxthdr1
rcall crlf
;-
ldi ZH, high(2*msgHead) ;Load high part of byte address into ZH
ldi ZL, low(2*msgHead) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
rcall crlf
;-
ldi Dly_2, 35
;
lpnxthdr2:
;„„„„
ldi Temp, '*'
rcall USART_Transmit
dec Dly_2
cpi Dly_2, 0x0
brne lpnxthdr2
rcall crlf
;–
clr EEAddr
;
lplst1:
;„„„
rcall read_eeprom_array ; value in r0
; SBRS r0, 0
rcall SendKeyRec ; send row
SBRS EEAddr,7
rjmp lplst1
;-
ldi Dly_2, 35
;
lpnxthdr3:
;„„„„
ldi Temp, '*'
rcall USART_Transmit
dec Dly_2
cpi Dly_2, 0x0
brne lpnxthdr3
rcall crlf
rjmp main_loop
; END KeyList
;
;……
KeyAdd:
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
rcall crlf
rcall crlf
;-
ldi ZH, high(2*msgAdd); Load high part of byte address into ZH
ldi ZL, low(2*msgAdd) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
ldi ZH, high(2*msgIndex) ; Load high part of byte address into ZH
ldi ZL, low(2*msgIndex) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
;-
uentry1:
;„„„`
wdr
sbrs Flags, HostRx
rjmp uentry1
cbr Flags,HostRx +1 ; clear flag …
mov Temp, RxMemo
rcall USART_Transmit ; echo
mov Temp, RxMemo
cpi Temp, 0x3A
brsh inhex
;
indec:
;„„`
andi Temp, 0x0F
rjmp StEEAddr
;
inhex:
;„„`
andi Temp, 0xDF ; caps.
subi Temp, 0x37
;
StEEAddr:
;„„„„
lsl Temp
lsl Temp
lsl Temp ; Temp = Temp * 8
mov EEAddr, Temp
;=
clr r0
rcall write_eeprom_array
inc EEAddr
rcall crlf
;-
ldi ZH, high(2*msgSerial)
ldi ZL, low(2*msgSerial)
rcall SendRomstring ; Send mesage
;;-
ldi Dly_2, 0x06 ; 12 char
clr ZH
ldi ZL, Buffer_end
;
uentry2:
;„„„`
wdr
sbrs Flags, HostRx
rjmp uentry2
cbr Flags,HostRx +1 ; clear flag …
mov Temp, RxMemo
rcall USART_Transmit ; echo
;-
mov Temp, RxMemo ; test 'copy buffer'
cpi Temp, ' '
breq KeyCopy
;-
st Z, Temp ; Store byte in RAM buffer
;-
uentry2a:
;„„„`
wdr
sbrs Flags, HostRx
rjmp uentry2a
cbr Flags,HostRx +1 ; clear flag …
mov Temp, RxMemo
rcall USART_Transmit ; echo
;-
mov Temp, RxMemo ; test 'copy buffer'
cpi Temp, ' '
breq KeyCopy
;-
ld Temp,Z ; reload first char (high nible)
rcall Hex2Bin
lsl Temp
lsl Temp
lsl Temp
lsl Temp ; align to MSB
st Z, Temp ; store high
mov Temp, RxMemo ; get low nible
rcall Hex2Bin
ld Temp2,Z
or Temp, Temp2
st Z+, Temp
;–
dec Dly_2
cpi Dly_2, 0x0
brne uentry2
;–––––––
StooreKey2EE:
;„„„„„„ ; store in EE
ldi Dly_2, 0x06 ; 6 byte
clr ZH
ldi ZL, Buffer_end
;
storeKloop:
;„„„„„
ld r0, Z+
rcall write_eeprom_array ; store
inc EEAddr
dec Dly_2
cpi Dly_2, 0x0
brne storeKloop
rjmp AccLevel
;
KeyCopy:
„„„„
ldi Temp, 0x0D ; CR
rcall USART_Transmit
ldi Temp, '>'
rcall USART_Transmit
ldi Temp, '>'
rcall USART_Transmit
rcall SendROMid ; display serial number
;;– ; copy last key to EEprom
ldi Dly_2, 0x06 ; 6 byte
clr ZH
ldi ZL, Buffer_begin+1; Z vector (pointer) , start buffer (RS232)
; inc EEAddr ; first is CRC
CopyKloop: ; RAM(1wire buff)
;„„„„„
ld r0, Z+
rcall write_eeprom_array ; store
inc EEAddr
dec Dly_2
cpi Dly_2, 0x0
brne CopyKloop
;
AccLevel:
;„„„„
rcall crlf
;-
ldi ZH, high(2*msgLevel)
ldi ZL, low(2*msgLevel)
rcall SendRomstring ; Send mesage
;
uentry3:
;„„„`
wdr
sbrs Flags, HostRx
rjmp uentry3
cbr Flags,HostRx +1 ; clear flag …
mov Temp, RxMemo
rcall USART_Transmit ; echo
;-
mov Temp, RxMemo
andi Temp, 0x07
mov r0, Temp
rcall write_eeprom_array ; store access level
rjmp main_loop
;; END KeyAdd
;………………………………………………………………..
Hex2Bin:
;„„„`
cpi Temp, 0x3A
brsh InHexa
;
InDeci:
;„„`
andi Temp, 0x0F
ret
;
InHexa:
;„„`
andi Temp, 0xDF ; caps.
subi Temp, 0x37
ret
;–––
;
; END KeyAdd
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
KeyDel:
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
rcall crlf
rcall crlf
;-
ldi ZH, high(2*msgDel); Load high part of byte address into ZH
ldi ZL, low(2*msgDel) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
ldi ZH, high(2*msgIndex); Load high part of byte address into ZH
ldi ZL, low(2*msgIndex); Load low part of byte address into ZL
rcall SendRomstring ; Send it
;-
usentry1:
;„„„`
wdr
sbrs Flags, HostRx
rjmp usentry1
cbr Flags,HostRx +1 ; clear flag …
mov Temp, RxMemo
rcall USART_Transmit ; echo
mov Temp, RxMemo
cpi Temp, 0x3A
brsh inphexa
;
inpdeci:
;„„`
andi Temp, 0x0F
rjmp StEEAddress
;
inphexa:
;„„`
andi Temp, 0xDF ; caps.
subi Temp, 0x37
;
StEEAddress:
;„„„„
lsl Temp
lsl Temp
lsl Temp ; Temp = Temp * 8
mov EEAddr, Temp
;=
ldi Temp,0xFF
mov r0 , Temp
rcall write_eeprom_array
rcall crlf
;–––––––-
ldi Temp,0x07
add EEAddr, Temp ; access level address
ldi Temp,0xFF
. mov r0, Temp
rcall write_eeprom_array
rjmp main_loop
; END KeyDel
;„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„
; END main_loop
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; END main
;**************************************************************************
;* Routine: SearchKey *
;* Purpose: Search serial Key match in EEprom records *
;* Inputs: Buffer_begin ( ROM Id ) *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;……….
SearchKey:
;„„„„`
clr EEAddr ; point to first record in EE
inc EEAddr ; first is CRC
;
RecordsLoop:
;„„„„„`
clr ZH
ldi ZL, Buffer_begin+1 ; Z vector (pointer) , start buffer
sbr Flags,KeyMatch +27; set flag (32 = 5+27)…
;
TestLoop:
;„„„„`
ld r0,Z+ ; read buffer & inc. pointer
mov Dly_1,r0 ; save value
rcall read_eeprom_array ; read EEprom
mov Dly_2, r0 ; save value
cp Dly_1,Dly_2 ; compare
brne GoNextRec
; ok, next byte in record ?
inc EEAddr
mov Temp, EEAddr
andi Temp, 0x07
cpi Temp, 0x07
brne TestLoop ; not last, go next byte
rjmp FoundtMatch
;
GoNextRec:
;„„„„`
ldi Temp, 0xF8
and EEAddr, Temp ; record begin
ldi Temp, 0x09
add EEAddr, Temp ; next record address +1 ( skip CRC )
SBRS EEAddr,7 ; Test EEprom end … ( 128×8 -> 16 rec.)
rjmp RecordsLoop
;–
NoMatch:
;„„„`
ldi ZH, high(2*msgNone); msg "INTERZIS"
ldi ZL, low(2*msgNone)
rcall SendRomstring
ret ; no match found…
;
FoundtMatch:
;„„„„„„„„„„„„„„„„„„„„
rcall SendRights
;–
cbi PORTB, LED_G_B ; turn on green LED
sbi PORTD, Releu_B ; Rel. on
clr BeepCnt0
clr BeepCnt1
clr Dly_0
clr Dly_1
;
lpRelBeep:
;„„„„`
inc BeepCnt0
cpi BeepCnt0,0
brne lpRelBeep
wdr
inc Dly_0
cpi Dly_0,20
brne lpRelBeep
clr Dly_0
inc BeepCnt1
cpi BeepCnt1, 254
breq EndBeep1 ; end…
in Temp, PORTB
sbrc Temp, Buzer_B
cbi PORTB, Buzer_B ; beep
sbrs Temp, Buzer_B
sbi PORTB, Buzer_B
rjmp lpRelBeep
;
EndBeep1:
;„„„`
clr BeepCnt1
inc Dly_1
cpi Dly_1, 4
brne lpRelBeep ; end…
;;=
sbi PORTB, LED_G_B ; turn off green LED
cbi PORTD, Releu_B ; Rel. on
cbi PORTB, Buzer_B ; turn off beep
; clr BeepCnt0
clr BeepCnt1
ret
; END SearchKey
;**************************************************************************
;**************************************************************************
;* Routine: SendKeyRec *
;* Purpose: send EEprom record *
;* Inputs: EEAddr *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;……….
SendKeyRec:
;„„„„„
ldi Temp, '*'
rcall USART_Transmit
ldi Temp, ' '
rcall USART_Transmit
mov Temp, EEAddr
asr Temp
asr Temp
asr Temp ; /8
rcall Bin2Hex
rcall USART_Transmit ; crt.
mov Temp,Temp2
rcall USART_Transmit
ldi Temp, ' '
rcall USART_Transmit
ldi Temp, '*'
rcall USART_Transmit
ldi Temp, ' '
rcall USART_Transmit
;-
ldi Dly_2, 0x06
;
lpnxtbt:
;„„„`
inc EEAddr
rcall read_eeprom_array ; value in r0
mov Temp, r0
rcall Bin2Hex
rcall USART_Transmit ; crt.
mov Temp,Temp2
rcall USART_Transmit
dec Dly_2
cpi Dly_2, 0x0
brne lpnxtbt
inc EEAddr
rcall SendRights
;
SendKeyEND:
;„„„„„
inc EEAddr ;next ….
rcall crlf
ret
; END SendKeyRec
;**************************************************************************
;* Routines: SendRights *
;* Purpose: send access rights on RS232 *
;* Inputs: EEAddr *
;* Outputs: *
;* Exit: *
;* Notes:
;**************************************************************************
;……….
SendRights:
;„„„„„
rcall read_eeprom_array
mov Temp, r0
cpi Temp, 0x00
brne FGuard
;
FMaster:
;„„„`
ldi ZH, high(2*msgMaster) ; Load high part of byte address into ZH
ldi ZL, low(2*msgMaster) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
ret
;
FGuard:
;„„„
cpi Temp, 0x01
brne FSUser
ldi ZH, high(2*msgGuard)
ldi ZL, low(2*msgGuard)
rcall SendRomstring
ret
;
FSUser:
;„„„
cpi Temp, 0x02
brne FUser
ldi ZH, high(2*msgSUser)
ldi ZL, low(2*msgSUser)
rcall SendRomstring
ret
;
FUser:
;„„`
cpi Temp, 0x03
brne FNone
ldi ZH, high(2*msgUser)
ldi ZL, low(2*msgUser)
rcall SendRomstring
ret
;
FNone:
;„„`
ldi ZH, high(2*msgNone)
ldi ZL, low(2*msgNone)
rcall SendRomstring
ret
; END SendRights
;**************************************************************************
;* Routines: 1 wire *
;* Purpose: read data from 'DS1990' *
;* Inputs: *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;–––––––––––––––––––-
;| ReadROMid command ( 0x33 ) |
;–––––––––––––––––––-
ReadROMid:
;„„„„`
rcall w1_one ; LSB first …
rcall w1_one
rcall w1_zero
rcall w1_zero
rcall w1_one
rcall w1_one
rcall w1_zero
rcall w1_zero
ret
;–––––––––––––––––––-
;| Read 8 byte |
;–––––––––––––––––––-
Read_8B:
;„„„`
clr ZH
ldi ZL, Buffer_end ; 0x68
lp_Bytes:
;„„„„
dec ZL ; buffer index –
ldi Dly_2, 0x08
clr w1Byte
;
lp_bits:
;„„„`
asr w1Byte ; Arithmetic Shift Right,
; prepare for next bit
andi w1Byte,0x7F ; clear b7
sbi PORTD, w1nonTx ; Tx=1 , bus = 0
nop ; delay
nop
nop
nop
cbi PORTD, w1nonTx ; Tx=0 , bus = 1
rcall w5us ; read slot begin
in Temp2,PIND ; read 1 wire bus (b2)
sbrc Temp2, w1Rx
sbr w1Byte, 0x80 ; store bit
rcall w60us
dec Dly_2
brne lp_bits ; 8 bits ?
st Z, w1Byte ; Store byte in RAM buffer
cpi ZL, Buffer_begin ; 0x60
brne lp_Bytes ; 8 Bytes
ret ; done
;–––––––––––––––––––-
;| 1 wire , write 'one' |
;–––––––––––––––––––-
w1_one:
;„„„
sbi PORTD, w1nonTx ; Tx=1 , bus = 0
rcall w5us ; wait 5 microseconds
cbi PORTD, w1nonTx ; Tx=0 , bus = 1
rcall w60us
ret
;–––––––––––––––––––-
;| 1 wire , write 'zero' |
;–––––––––––––––––––-
w1_zero:
;„„„`
sbi PORTD, w1nonTx ; Tx=1 , bus = 0
rcall w60us
cbi PORTD, w1nonTx ; Tx=0 , bus = 1
rcall w5us
ret
;–––––––––––––––––––-
;| test |
;–––––––––––––––––––-
TestPresence:
;„„„„„„
test:
;„„
;– disable INT0 –
in Temp2, GIMSK
andi Temp2, 0b10111111 ; INT0 =0
out GIMSK, Temp2
;–
nop
nop
sbi PORTD, w1nonTx ; Tx=1 , bus = 0
rcall w480us ; 480 ms < tRSTL
cbi PORTD, w1nonTx ; Tx=0
rcall w30us
rcall w30us ; 15 ms < tPDH < 60 ms
in Temp2,pind ; read 1 wire bus
sbrs Temp2, w1Rx ; b2
sbr Flags,PresenceOK +2 ; set flag … key present
tstj:
;
rcall w480us
;– enable INT0 –
in Temp2, GIMSK
ori Temp2, 0b01000000 ; INT0 =1
out GIMSK, Temp2
;–
cbr Flags,Presence +1
ret
;–––––––––––––––––––-
;| test |
;–––––––––––––––––––-
; END 1 wire
;**************************************************************************
;* Routine: read_eeprom_array *
;* Purpose: read data from the internal processor EEprom *
;* Inputs: EEAddr = address of EEprom data to read *
;* Outputs: r0 = data read from EEprom *
;* Exit: *
;* Notes: *
;**************************************************************************
;……………..
read_eeprom_array:
;„„„„„„„„`
in Temp, SREG ; store SREG value
cli ; disable interrupts during timed sequence
;
read_eeprom_array_1:
;„„„„„„„„„`
sbic EECR,EEWE ; if EEWE not clear
rjmp read_eeprom_array_1; wait more
out EEAR, EEAddr ; output address low
sbi EECR, EERE ; set EEPROM Read strobe
; This instruction takes 4 clock cycles since
; it halts the CPU for two clock cycles
in r0, EEDR ; get data
out SREG, Temp ; restore SREG value (I-bit)
ret
; END read_eeprom_array
;**************************************************************************
;* Routine: write_eeprom_array *
;* Purpose: write data to the internal processor EEprom *
;* Inputs: EEAddr = address of EEprom data to read *
;* r0 = data to write to EEprom *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;………………
write_eeprom_array:
;„„„„„„„„„
in Temp, SREG ; store SREG value
cli ; disable interrupts during timed sequence
;
write_eeprom_array_1:
;„„„„„„„„„„
sbic EECR, EEPE ; if EEWE not clear
rjmp write_eeprom_array_1 ; wait more
out EEAR, EEAddr ; output address low
out EEDR, r0
sbi EECR, EEMPE ; set master write enable
sbi EECR, EEPE ; set EEPROM Write strobe
; This instruction takes 4 clock cycles since
; it halts the CPU for two clock cycles
out SREG, Temp ; restore SREG value (I-bit)
ret
; END write_eeprom_array
;**************************************************************************
;* Routine: USART_Transmit *
;* Purpose: Send Char via UART, preserves content ( RS232 ) *
;* Inputs: Temp = string to send *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;…………..
USART_Transmit:
;„„„„„„„
.IFDEF ATTiny2313
;„„„„„„„„
sbis UCSRA,UDRE
.ELSE
sbis USR,udre
.ENDIF
rjmp USART_Transmit ; Wait for empty transmit buffer
out UDR,Temp ; Put data into buffer, sends the data
ret
; END USART_Transmit
;**************************************************************************
;* Routine: crlf *
;* Purpose: Send CR LF (new line) *
;* Inputs: none *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;….
crlf:
;„„
ldi Temp,$0A ; LF
rcall USART_Transmit
ldi Temp,$0D ; CR
rcall USART_Transmit
ret
; END crlf
;**************************************************************************
;* Routine: SendROMid *
;* Purpose: Send Dallas DS1990 ROM ID ( serial number ) *
;* Inputs: none *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;………
SendROMid:
;„„„„`
clr ZH
ldi ZL, Buffer_begin+1 ; 0x60
rcall crlf ; new line
lp_snd:
;„„„
ld Temp,Z+ ; load byte from RAM buffer & post increment
rcall Bin2hex
rcall USART_Transmit
mov Temp, Temp2
rcall USART_Transmit
cpi ZL, Buffer_end-1 ; 0x67
brne lp_snd ; 6 Bytes
ret
; END SendROMid
;**************************************************************************
;* Routine: Bin2hex *
;* Purpose: BIN -> HEX *
;* Inputs: Temp , bin value * *
;* Outputs: Temp, Temp2 *
;* Exit: *
;* Notes: *
;**************************************************************************
;…….
Bin2hex:
;„„„`
mov Temp2, Temp ; copy value
ldi Dly_0, 0x30
ldi Dly_1, 0x07
asr Temp
asr Temp
asr Temp
asr Temp
andi Temp, 0x0F ; mask
cpi Temp, 0x0A ; convert to ASCII
brlt numm ; < 10
add Temp, Dly_1 ; > 9
numm:
add Temp, Dly_0
;-
andi Temp2, 0x0F
cpi Temp2, 0x0A ; convert to ASCII
brlt numm2 ; < 10
add Temp2, Dly_1 ; > 9
numm2:
add Temp2, Dly_0
ret
; END Bin2hex
;**************************************************************************
;* Routine: Delay_1s *
;* Purpose: delay , 1 second *
;* Inputs: none * *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
Delay_1s:
;„„„„
nop
ret
; END Delay_1s
;**************************************************************************
;* Routine: Delay *
;* Purpose: delay … *
;* Inputs: *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
;–––––––––––––––––––-
;| w5us |
;–––––––––––––––––––-
w5us:
;„„
ldi Dly_0,12 ;1~
dlp01:
dec Dly_0 ;1~
brne dlp01 ;2~ 1+(1+2)*13+4=242=5.5us
ret ;4~
;–––––––––––––––––––-
;| Delay 30us(1+(1+2)*79+4=242=30.25us) |
;–––––––––––––––––––-
w30us:
;„„`
ldi Dly_0,79 ;1~
dlp02:
dec Dly_0 ;1~
brne dlp02 ;2~ 1+(1+2)*79+4=242=30.25us
ret ;4~
;–––––––––––––––––––-
;| w60us(1+(1+2)*160+4=125~=60.62us) |
;–––––––––––––––––––-
w60us:
;„„`
ldi Dly_0,160 ;1~
dlp03:
dec Dly_0 ;1~
brne dlp03 ;2~
ret ;4~
;–––––––––––––––––––-
;| w300us |
;–––––––––––––––––––-
w300us:
;„„„
ldi Dly_0,0x4
dlp04:
ldi Dly_1,0xff
dlp05:
dec Dly_1
brne dlp05
dec Dly_0
brne dlp04
ret
;–––––––––––––––––––-
;| w480us |
;–––––––––––––––––––-
w480us:
;„„„
ldi Dly_0,0x5
dlp06:
ldi Dly_1,0xff
dlp07:
dec Dly_1
brne dlp07
dec Dly_0
brne dlp06
ret
;–––––––––––––––––––-
;| w200ms |
;–––––––––––––––––––-
w200ms:
;„„„
ldi Dly_2, 16 ;1~
dlp08:
ldi Dly_1,0x82 ;1~
dlp09:
ldi Dly_0,0xff ;1~
dlp10:
dec Dly_0 ;1~
brne dlp10 ;2~
dec Dly_1 ;1~
brne dlp09 ;2~
dec Dly_2 ;1~
brne dlp08 ;2~
ret ;4~
;–
; END Delay
;**************************************************************************
;* Routine: reset routines *
;* Purpose: init *
;* Inputs: *
;* Outputs: *
;* Exit: *
;* Notes: *
;**************************************************************************
reset:
;„„`
; reset stack pointer
;–––––––
ldi Temp,low(RAMEND)
out SPL,Temp
; set up port B
;–––––
ldi Temp, DDRB_INIT
out DDRB, Temp ; set up port B direction
ldi Temp, PORTB_INIT
out PORTB, Temp ; set up port B data
; set up ports D
;–––––
ldi Temp, DDRD_INIT
out DDRD, Temp ; set up port D direction
ldi Temp, PORTD_INIT
out PORTD, Temp
; set up initial hardware registers
;–––––––––––-
.IFDEF ATTiny2313
;„„„„„„„„
ldi Temp, GIMSK_DATA ; int.
out GIMSK, Temp
ldi Temp, TIMSK_DATA
out TIMSK, Temp
ldi Temp, MCUCR_DATA ; edge
out MCUCR, Temp
ldi Temp, TCCR0_DATA
out TCCR0, Temp
ldi Temp, TCCR1A_DATA
out TCCR1A, Temp
ldi Temp, TCCR1B_DATA
out TCCR1B, Temp
ldi Temp, WDTCR_DATA
out WDTCR, Temp
;
.MESSAGE "ATTiny2313… USART config"
; USART
;––
ldi Temp, UCSRB_DATA
out UCSRB, Temp
ldi Temp, UCSRC_DATA
out UCSRC, Temp
ldi Temp, UBRRL_DATA
out UBRRL, Temp
ldi Temp, UBRRH_DATA
out UBRRH, Temp
ldi Temp, ACSR_DATA
out ACSR, Temp
.ELSE
;„„
.MESSAGE "AT90S2313… UART config"
;
ldi Temp,BAUD_VALUE_INIT
out UBRR,Temp ; Load baud rate.
sbi UCR,txen ; Enable UART transmitter.
sbi UCR,rxen ; Enable UART receiver.
sbi UCR,rxcie ; Enable UART receive interrupts.
wdr
; Reset the watchdog timer -make sure its ; not about to trip.
ldi Temp,0b00001111 ; Enable the watchdog
out wdtcr,Temp
.ENDIF
;
; enable Interrupts, and set up port directions
;–––––––––––––––-
sei
rjmp main
; END reset
;**************************************************************************
;* Routine: SendMessage
;* Purpose: Send welcome message
;* Inputs:
;* Outputs:
;* Exit:
;* Notes:
;**************************************************************************
SendMessage: ; Send welcome
;„„„„„`
ldi ZH, high(2*Message); Load high part of byte address into ZH
ldi ZL, low(2*Message) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
;
StringEnd:
;„„„„`
ret
;
SendRomstring: ; Send string pointed to by ZH,ZL.
;„„„„„„`
lpm ; Load byte from program memory into r0
tst r0 ; Check if we've reached the end of the message
breq StringEnd ; If so, return
wdr
mov Temp, r0
rcall USART_Transmit
adiw ZL, 1 ; Increment Z registers
rjmp SendRomstring
; END SendMessage
;……..
SendMenu:
;„„„„
ldi ZH, high(2*msgMenu) ; Load high part of byte address into ZH
ldi ZL, low(2*msgMenu) ; Load low part of byte address into ZL
rcall SendRomstring ; Send it
ret
; END SendMenu
;**************************************************************************
;* Routine: TxResponse
;* Purpose: Send response to host ( "co" )
;* Inputs:
;* Outputs:
;* Exit:
;* Notes:
;**************************************************************************
;……….
TxResponse:
;„„„„„
cbr Flags,HostSearchOk +12 ; reset flag (16)… 'c'
; 2008Locked
ldi Temp, '2'
rcall USART_Transmit
ldi Temp, '3'
rcall USART_Transmit
ldi Temp, '_'
rcall USART_Transmit
ldi Temp, '0'
rcall USART_Transmit
ldi Temp, '6'
rcall USART_Transmit
ldi Temp, '_'
rcall USART_Transmit
ldi Temp, '2'
rcall USART_Transmit
ldi Temp, '0'
rcall USART_Transmit
ldi Temp, '0'
rcall USART_Transmit
ldi Temp, '9'
rcall USART_Transmit
ldi Temp, 0x01
ret
;
; END TxResponse
;**************************************************************************
Message:
;„„„`
.db " Universitatea Stefan cel Mare "
.db $0A,$0D ; LF CR
.db " Suceava"
.db $0A,$0D ; LF CR
.db " Facultatea de Inginerie"
.db $0A,$0D ; LF CR
.db " Electrica "
.db $0A,$0D ; LF CR
.db " Sistem de acces cu buton Dallas"
.db $0A,$0D ; LF CR
.db $00,$00 ; null
msgMenu:
.db "**********************************"
.db $0A,$0D ; LF CR
.db "* MENU *"
.db $0A,$0D ; LF CR
.db "**********************************"
.db $0A,$0D ; LF CR
.db " [1] Lista chei"
.db $0A,$0D ; LF CR
.db " [2] Adauga cheie"
.db $0A,$0D ; LF CR
.db " [3] Sterge cheie"
.db $0A,$0D ; LF CR
.db " [4] Reinitializare sistem "
.db $0A,$0D ; LF CR
.db $00,$00 ; null
msgHead:
.db "* nr * Serie cheie * Nivel acces * "
.db $00,$00 ; null
msgMaster:
.db " * Master Key *"
.db $00,$00 ; null
msgGuard:
.db " * Paza … *"
.db $00,$00 ; null
msgSUser:
.db " * Management *"
.db $00,$00 ; null
msgUser:
.db " * Personal *"
.db $00,$00 ; null
msgNone:
.db " * INTERZIS *"
.db $00,$00 ; null
msgAdd:
.db "* Adauga sau modifica cheie…"
.db $0A,$0D ; LF CR
.db $0A,$0D ; LF CR
.db $00,$00 ; null
msgDel:
.db "* Dezactiveaza cheie… "
.db $0A,$0D ; LF CR
.db $0A,$0D ; LF CR
.db $00,$00 ; null
msgIndex:
.db " Index ? ( 0,..,9,A,..,F )"
.db $0A,$0D ; LF CR
.db ">>"
.db $00,$00 ; null
msgSerial:
.db " Serie ? ( 12 cifre hexazecimale )"
.db $0A,$0D ; LF CR
.db ">>"
.db $00,$00 ; null
msgLevel:
.db " Nivel acces ?"
.db $0A,$0D ; LF CR
.db "[0] Master Key"
.db $0A,$0D ; LF CR
.db "[1] Paza …"
.db $0A,$0D ; LF CR
.db "[2] Management"
.db $0A,$0D ; LF CR
.db "[3] Personal"
.db $0A,$0D ; LF CR
.db ">>"
.db $00,$00 ; null
.exit
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Sistem de Acces Ibutton (ID: 123894)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
