| Both sides previous revisionPrevious revisionNext revision | Previous revision |
| et:avr:registers [2010/02/06 16:44] – peetersalong | et:avr:registers [2020/07/20 09:00] (current) – external edit 127.0.0.1 |
|---|
| ====== Registrid ====== | ====== Registrid ====== |
| |
| Üks kõige raskemini mõistetavaid asju mikrokontrollerite juures on algajate jaoks tavaliselt "register". Sellest mõistest ei pääse üle ega ümber, kui on soov mikrokontrolleritega tegeleda. Ka käesolev materjal eeldab, et lugeja on tuttav registri mõistega ja seepärast on järgnevalt seda algajale ka võimalikult lihtsalt selgitatud. | Üks kõige raskemini mõistetavaid asju mikrokontrollerite juures on algajate jaoks tavaliselt "register". Sellest mõistest ei pääse üle ega ümber, kui on soov mikrokontrolleritega tegeleda. Ka käesolev materjal eeldab, et lugeja saab tuttavaks registri mõistega ja seepärast on järgnevalt seda algajale ka võimalikult lihtsalt selgitatud. |
| |
| ===== Olemus ===== | ===== Olemus ===== |
| ===== Kasutamine ===== | ===== Kasutamine ===== |
| |
| C-keele programmis registri väärtuse kirjutamiseks või lugemiseks tuleb selle poole nagu muutuja poole pöörduda. Järgnev näide demonstreerib väljamõeldud registrisse REG binaarväärtuse kirjutamist ja selle väärtuse muutujasse //reg// lugemist. Binaarväärtuse ette kirjutatakse 0b (ees on null), et kompilaator arvusüsteemist aru saaks. | C-keele programmis registri väärtuse kirjutamiseks või lugemiseks tuleb selle poole pöörduda nagu muutuja poole. Järgnev näide demonstreerib väljamõeldud registrisse REG binaarväärtuse kirjutamist ja selle väärtuse muutujasse //reg// lugemist. Binaarväärtuse ette kirjutatakse 0b (ees on null), et kompilaator arvusüsteemist aru saaks. |
| |
| <code c> | <code c> |
| </code> | </code> |
| |
| Põhimõtteliselt registrite väärtuse kirjutamises ja lugemises midagi keerulist polegi, kuid keerulisemaks läheb lugu siis, kui soovitakse muuta registri üksikute bittide väärtust. Bittide muutmiseks tuleb enne aga selgeks saada binaartehted ja erinevad arvusüsteemid. Keegi ei keela tegutseda binaararvudega, kuid binaararvudega tegelemine on tülikas nende pikkuse tõttu ja tavaliselt kasutatakse nende asemel heksadetsimaalarve, mis on lühemad. | Põhimõtteliselt registrite väärtuse kirjutamises ja lugemises midagi keerulist polegi, kuid keerulisemaks läheb lugu siis, kui soovitakse muuta registri üksikute bittide väärtust. Bittide muutmiseks tuleb enne selgeks saada binaartehted ja erinevad arvusüsteemid. Keegi ei keela tegutseda binaararvudega, kuid binaararvudega tegelemine on tülikas nende pikkuse tõttu ja tavaliselt kasutatakse nende asemel heksadetsimaalarve, mis on lühemad. |
| |
| [{{ :images:logic:logic_hexadecimal.png?209|Heksadetsimaalnumbrid}}] | [{{ :images:logic:logic_hexadecimal.png?209|Heksadetsimaalnumbrid}}] |
| |
| Heksadetsimaalarvus pole numbrid mitte 0 ja 1, nagu binaarsüsteemis, ega 0-st 9-ni, nagu kümnendsüsteemis, vaid 0-st F-ni. Üks heksadetsimaalnumber moodustub neljast bitist. Kõrvalolev tabel näitab heksadetsimaalnumbritele vastavaid binaararve. Binaararve teisendatakse heksadetsimaalarvuks bitte nelja kaupa madalamast järgust alates lugedes. Järkusid loetakse paremalt vasakule ja nende nummerdamist alustatakse nullist. Näiteks binaararvu 1110 madalaima ehk 0. järgu väärtus on 0 ja kõrgeima ehk 3. järgu väärtus on 1. Eespool toodud näidisregistri binaarväärtus 01100001 on heksadetsimaalkujul 61, mis C-keeles kirjutatakse kujul 0x61 (ees on null). | Heksadetsimaalarvus pole numbrid mitte 0 ja 1, nagu binaarsüsteemis, ega 0-st 9-ni, nagu kümnendsüsteemis, vaid 0-st F-ni. Üks heksadetsimaalnumber moodustub neljast bitist. Kõrvalolev tabel näitab heksadetsimaalnumbritele vastavaid binaararve. Binaararve teisendatakse heksadetsimaalarvuks lugedes bitte nelja kaupa, alates madalamast järgust. Järkusid loetakse paremalt vasakule ja nende nummerdamist alustatakse nullist. Näiteks binaararvu 1110 madalaima ehk 0. järgu väärtus on 0 ja kõrgeima ehk 3. järgu väärtus on 1. Eespool toodud näidisregistri binaarväärtus 01100001 on heksadetsimaalkujul 61, mis C-keeles kirjutatakse kujul 0x61 (ees on null). |
| |
| ~~CL~~ | Üksikute bittide muutmiseks arvus (registris, muutujas või kus iganes) tuleb kasutada binaartehteid. Binaartehe on tehe binaararvude vahel, kus nende arvude iga biti vahel toimub omaette loogikatehe. Enamasti on mikrokontrollerites kasutusel neli binaartehet, millel kõigil on mitu nimetust. Järgnevalt on toodud kõigile neljale binaartehtele vastav loogikatehe üksiku biti või bittidega. |
| |
| [{{ :images:logic:logic_not.png?133|Eitus}}] | [{{ :images:logic:logic_all_4.png?550 |Eitus, loogiline korrutamine, loogiline liitmine ja mittesamaväärsus}}] |
| [{{ :images:logic:logic_and.png?133|Korrutamine}}] | |
| [{{ :images:logic:logic_or.png?133|Liitmine}}] | |
| [{{ :images:logic:logic_xor.png?133|Mittesamaväärsus}}] | |
| |
| Üksikute bittide muutmiseks arvus (registris, muutujas või kus iganes) tuleb kasutada binaartehteid. Binaartehe on tehe binaararvude vahel, kus nende arvude iga biti vahel toimub omaette loogikatehe. Enamasti on mikrokontrollerites kasutusel neli binaartehet, millel kõigil on mitu nimetust. Kõrval on toodud kõigile neljale binaartehtele vastav loogikatehe üksiku biti või bittidega. | |
| |
| * **Eitus / Inversioon** \\ Eitus muudab biti väärtuse vastupidiseks ehk 0 muutub 1 ja 1 muutub 0. C-keeles on eituse märk "~". | * **Eitus / Inversioon** \\ Eitus muudab biti väärtuse vastupidiseks ehk 0 muutub 1 ja 1 muutub 0. C-keeles on eituse märk "~". |
| * **Loogiline korrutamine / Konjunktsioon** \\ Kaht bitti korrutades on vastus 1, kui mõlemad bitid olid 1, muul juhul on vastus 0. C-keeles on korrutamise märk "&". | * **Loogiline korrutamine / Konjunktsioon** \\ Kahte bitti korrutades on vastus 1, kui mõlemad bitid olid 1, muul juhul on vastus 0. C-keeles on korrutamise märk "&". |
| * **Loogiline liitmine / Disjunktsioon** \\ Kahe biti liitmisel on vastus 1, kui vähemalt ühe biti väärtus oli 1, muul juhul on vastus 0. C-keeles on liitmise märk "|". | * **Loogiline liitmine / Disjunktsioon** \\ Kahe biti liitmisel on vastus 1, kui vähemalt ühe biti väärtus oli 1, muul juhul on vastus 0. C-keeles on liitmise märk "|". |
| * **Mittesamaväärsus / Välistav disjunktsioon** \\ Kahe bitiga mittesamaväärsuse tehte korral on vastus 1, kui bittide väärtused erinevad teineteisest, muul juhul on vastus 0. C-keeles on mittesamaväärsuse märk "^". | * **Mittesamaväärsus / Välistav disjunktsioon** \\ Kahe bitiga mittesamaväärsuse tehte korral on vastus 1, kui bittide väärtused teineteisest erinevad, muul juhul on vastus 0. C-keeles on mittesamaväärsuse märk "^". |
| |
| Nüüd on lühidalt selgitatud kõik, mida läheb vaja üksikute bittide väärtuste muutmiseks. Kuid ilmselt jääb teooriast ikkagi väheks ja seepärast on järgnevalt toodud mõningad tüüpnäited registritega. | Nüüd on lühidalt selgitatud kõik, mida läheb vaja üksikute bittide väärtuste muutmiseks. Kuid ilmselt jääb teooriast ikkagi väheks ja seepärast on järgnevalt toodud mõningad tüüpnäited registritega. |
| [{{ :images:logic:op_bit_set.png?230|Biti kõrgeks seadmise tehe}}] | [{{ :images:logic:op_bit_set.png?230|Biti kõrgeks seadmise tehe}}] |
| |
| Selleks, et üks või enam bitte registris kõrgeks ehk üheks seada, tuleb kasutada loogilist liitmise tehet. Liitmistehte üks operand peab olema register, teine binaararv, kus kõrge on ainult see bitt, mida ka registris soovitakse kõrgeks seada. Seda teist binaararvu nimetatakse ka bitimaskiks. Kõrvalnäites toodud tehe näeb C-keeles välja niimoodi: | Selleks et üks või enam bitte registris kõrgeks ehk üheks seada, tuleb kasutada loogilist liitmise tehet. Liitmistehte üks operand peab olema register, teine binaararv, kus kõrge on ainult see bitt, mida ka registris soovitakse kõrgeks seada. Seda teist binaararvu nimetatakse ka bitimaskiks. Kõrvalnäites toodud tehe näeb C-keeles välja niimoodi: |
| |
| ~~CL~~ | ~~CL~~ |
| [{{ :images:logic:op_reg_invert.png?229|Bittide inverteerimise tehe}}] | [{{ :images:logic:op_reg_invert.png?229|Bittide inverteerimise tehe}}] |
| |
| Kogu registri bittide inverteerimiseks tuleb kasutada eitustehet. See on unaarne tehe ehk tal on ainult üks operand. Kõrvalnäites toodu tehe näeb C-keeles välja niimoodi: | Kogu registri bittide inverteerimiseks tuleb kasutada eitustehet. See on unaarne tehe ehk tal on ainult üks operand. Kõrvalnäites toodud tehe näeb C-keeles välja niimoodi: |
| |
| ~~CL~~ | ~~CL~~ |
| [{{ :images:logic:op_bit_get.png?229|Biti lugemise tehe}}] | [{{ :images:logic:op_bit_get.png?229|Biti lugemise tehe}}] |
| |
| Ühe või enam biti väärtuse lugemiseks registrist tuleb kasutada sama tehet mis biti nullimisel - loogilist korrutamist. Tehte üks operand peab olema register, teine bitimask, kus kõrgeks on seatud vaid see bitt, mille väärtust registrist lugeda soovitakse. Kõrvalnäites toodud tehe näeb C-keeles välja järgmiselt: | Ühe või enama biti väärtuse lugemiseks registrist tuleb kasutada sama tehet, mis biti nullimisel - loogilist korrutamist. Tehte üks operand peab olema register, teine bitimask, kus kõrgeks on seatud vaid see bitt, mille väärtust registrist lugeda soovitakse. Kõrvalnäites toodud tehe näeb C-keeles välja järgmiselt: |
| |
| ~~CL~~ | ~~CL~~ |
| // Siinkohal x = 0x01 | // Siinkohal x = 0x01 |
| </code> | </code> |
| |
| ~~PB~~ | |
| |
| ==== Biti nihutamine ==== | ==== Biti nihutamine ==== |
| |
| Tegelikult on paljudes programmeerimiskeeltes peale binaartehete veel mõned bitioperatsioonid, mis teevad programeerija elu lihtsamaks. Need on bitinihutuse operatsioonid, mis binaararvus nihutavad bitte kas vasakule või paremale poole. Nihutusoperatsioonide põhiline väärtus seisneb registritega tegeldes nende võimes bitijärkusid bitimaskiks teisendada ja vastupidi. | Tegelikult on paljudes programmeerimiskeeltes peale binaartehete veel mõned bitioperatsioonid, mis teevad programmeerija elu lihtsamaks. Need on bitinihutuse operatsioonid, mis binaararvus nihutavad bitte kas vasakule või paremale poole. Nihutusoperatsioonide põhiline väärtus seisneb registritega tegeledes nende võimes bitijärkusid bitimaskiks teisendada ja vastupidi. |
| |
| [{{ :images:logic:op_bit_shift_left.png?241|Bitinihe vasakule}}] | [{{ :images:logic:op_bit_shift_left.png?241|Bitinihe vasakule}}] |
| |
| Kõrvaloleval pildil on toodud näide bitinihutuse operatsioonist vasakule. Bitinihutus pole loogikaoperatsioon ja sel puudub vastav tähis, C-keeles on see aga "<<". Nihet vasakule kasutatakse bitijärgu bitimaskiks teisendamiseks. Näiteks kui soovitakse kuuenda biti (NB! järk on 5) maski, siis tuleb arvu 1 nihutada vasakule 5 korda. Näites toodud operatsioon näeb C-keeles välja sedasi: | Kõrvaloleval pildil on toodud näide bitinihutuse operatsioonist vasakule. Bitinihutus pole loogikaoperatsioon ja sel puudub vastav tähis, C-keeles on see aga "<<". Nihet vasakule kasutatakse bitijärgu bitimaskiks teisendamiseks. Näiteks, kui soovitakse kuuenda biti (NB! järk on 5) maski, siis tuleb arvu 1 nihutada vasakule 5 korda. Näites toodud operatsioon näeb C-keeles välja järgmiselt: |
| |
| ~~CL~~ | ~~CL~~ |
| ===== AVR registrid ===== | ===== AVR registrid ===== |
| |
| Selleks et midagi reaalselt ka mikrokontrolleri registritega teha saaks, tuleb osata selle mikrokontrolleriga läbi saada. Kõigi mikrokontrolleritega käib kaasas andmeleht või mitu, kus on dokumenteeritud kogu selle struktuur ja funktsionaalsus. Andmelehes on kirjeldatud ka registreid. Järgnevalt uurime,kuidas aru saada AVR-i andmelehe registrite kirjeldusest. | Selleks, et midagi reaalselt mikrokontrolleri registritega teha saaks, tuleb osata selle mikrokontrolleriga läbi saada. Kõigi mikrokontrolleritega käib kaasas üks või mitu andmelehte, kus on dokumenteeritud kogu mikrokontrolleri struktuur ja funktsionaalsus. Andmelehes on kirjeldatud ka registrid. Järgnevalt uurime, kuidas saada aru AVR-i andmelehe registrite kirjeldusest. |
| |
| [{{ :images:logic:avr_example_register.png?580 |Üks AVR register selle andmelehest}}] | [{{ :images:logic:avr_example_register.png?580 |Üks AVR register selle andmelehest}}] |
| Pildil on toodud ATmega128 mikrokontrolleri register UCSRnA, mille pikem nimetus on "//USART Control and Status Register A//". See on register, millega sätitakse AVR-i USART moodulit ja kust saab lugeda selle mooduli olekuid. Kõik AVR-i registrite nimed kirjutatakse suurte tähtedega, kuid tähelepanelik lugeja ilmselt märkab, et selles registris on väike n-täht. Väikese n-tähega tähistatakse nimelt mõne mooduli indeksit. Kuna ATmega128-s on 2 üsna sarnast USART moodulit, siis ei kirjeldata nende registreid topelt, vaid ühe korra ja n-tähe asemele peab lugeja arvestama kas "0" või "1". Seega ATmega128-s on registrid UCSR0A ja UCSR1A. | Pildil on toodud ATmega128 mikrokontrolleri register UCSRnA, mille pikem nimetus on "//USART Control and Status Register A//". See on register, millega sätitakse AVR-i USART moodulit ja kust saab lugeda selle mooduli olekuid. Kõik AVR-i registrite nimed kirjutatakse suurte tähtedega, kuid tähelepanelik lugeja ilmselt märkab, et selles registris on väike n-täht. Väikese n-tähega tähistatakse nimelt mõne mooduli indeksit. Kuna ATmega128-s on 2 üsna sarnast USART moodulit, siis ei kirjeldata nende registreid topelt, vaid ühe korra ja n-tähe asemele peab lugeja arvestama kas "0" või "1". Seega ATmega128-s on registrid UCSR0A ja UCSR1A. |
| |
| Registri sisu tähistab paksu piirjoonega 8 lahtriga kast. Iga lahter tähistab üht bitti. Kasti kohal on toodud biti järgud - paremalt vasakule suurenevad. Kuna AVR on 8-bitine mikrokontroller, on ka enamik registreid 8-bitised. Mõningad erandid on 16-bitised registrid, mis koosnevad tegelikult kahest 8-bitisest. Peale selle, et registritel on nimi, on ka igal registri bitil nimi - täpselt nagu kassetimängija nuppudelgi. Iga biti kohta käib andmelehes ka selle selgitus. Biti nimed on samuti lühendid ja n-täht neis tuleb samuti asendada mooduli indeksiga. Mõnes registris pole kõiki 8 bitti kasutatud ja sel juhul tähistatakse biti lahter sidekriipsuga. | Registri sisu tähistab paksu piirjoonega 8 lahtriga kast. Iga lahter tähistab üht bitti. Kasti kohal on toodud biti järgud - suurenevad paremalt vasakule. Kuna AVR on 8-bitine mikrokontroller, on ka enamik registreid 8-bitised. Mõningad erandid on 16-bitised registrid, mis koosnevad tegelikult kahest 8-bitisest registrist. Lisaks registritele on nimi ka igal registri bitil - täpselt nagu kassetimängija nuppudelgi. Iga biti kohta on andmelehes olemas selle selgitus. Biti nimed on samuti lühendid ja n-täht neis tuleb samuti asendada mooduli indeksiga. Mõnes registris pole kõiki 8 bitti kasutatud ja sel juhul tähistatakse biti lahter sidekriipsuga. |
| |
| Registri bittide all on toodud kaks rida, kus on kirjas see, kas bitt on loetav (R), kirjutatav (W) või mõlemat (R/W). Näiteks olekubitte ei saa kirjutada, isegi kui seda programmis üritada - bitt lihtsalt ei omanda väärtust, mis talle antakse. Biti puhul, mida saab ainult kirjutada, on öeldud üks väärtus, mis selle lugemisel alati tuleb. Teises reas on bittide all toodud väärtus, mis on bitil pärast mikrokontrolleri käivitamist (inglise keeles //reset//). | Registri bittide all on toodud kaks rida, kus on kirjas, kas bitt on loetav (R), kirjutatav (W) või mõlemat (R/W). Näiteks olekubitte ei saa üle kirjutada ja isegi siis, kui seda programmis üritada, ei omanda bitt lihtsalt talle omistatavat väärtust. Biti puhul, mida saab ainult kirjutada, on öeldud üks kindel väärtus, mis selle lugemisel alati tuleb. Bittide all teises reas on toodud vaikeväärtus, mis on bitil pärast mikrokontrolleri käivitamist (inglise keeles //reset//). |
| |
| Kui AVR-i registrite nimed viitavad tegelikult mälupesade aadressidele, siis biti nimede taga peitub selle biti järgu number. Seega registris bittidega manipuleerimiseks tuleb bitinimed nihutusoperatsiooni abil bitimaskiks teisendada. Järgnevalt on toodud mõned C-keele näited eeltoodud USART 0 mooduli registri kasutamiseks. | Kui AVR-i registrite nimed viitavad tegelikult mälupesade aadressidele, siis biti nimede taga peitub selle biti järgu number. Seega registris bittidega manipuleerimiseks tuleb bitinimed nihutusoperatsiooni abil bitimaskiks teisendada. Järgnevalt on toodud mõned C-keele näitelaused eeltoodud USART 0 mooduli registri kasutamiseks. |
| |
| <code c> | <code c> |
| // UDRE0 biti(maski) väärtuse lugemine | // UDRE0 biti(maski) väärtuse lugemine |
| unsigned char u = (UCSR0A & (1 << UDRE0)); | unsigned char u = (UCSR0A & (1 << UDRE0)); |
| |
| // Siinkohal on u väärtus kas 0 või 32, | // Siinkohal on u väärtus kas 0 või 32, |
| // mis võimaldab seda loogilises avaldises kasutada | </code> |
| if (u) | |
| { | |
| // MPCM0 biti inverteerimine | |
| UCSR0A ^= (1 << MPCM0); | |
| } | |
| |
| // Mõnikord on aga vaja saada konkreetne 0 või 1 väärtus. | Atmeli xmega seeria kontrolleritel, mis on kasutusel Kodulabori III seeria plaatidel tuleb lisaks moodulile ära märkida ka port, mille moodulit kasutada soovitakse. Lisaks on defineeritud registri bittide maskid ning bittide positsioonid _bm(bit mask) ja _bp(bit position) lõppudega. |
| // Selleks tuleb loetud bitti nihutada paremale. | |
| u >>= UDRE0; | |
| |
| // Siinkohal on u väärtus kas 0 või 1 | <code c> |
| </code> | // TXEN biti kõrgeks seadmine |
| | USARTD0.CTRLB |= (USART_TXEN_bm); |
| |
| | // CLK2X biti madalaks seadmine |
| | USARTD0.CTRLB &= ~(USART_CLK2X_bm); |
| | |
| | // DREIF biti(maski) väärtuse lugemine |
| | unsigned char u = (USARTD0.STATUS & (USART_DREIF_bm)); |
| | // Siinkohal on u väärtus kas 0 või 32, |
| | u >>= USART_DREIF_bp; |
| | // Siinkohal on u väärtus kas 0 või 1, |
| | </code> |