Both sides previous revisionPrevious revisionNext revision | Previous revision |
en:avr:registers [2010/02/28 14:31] – mikk.leini | en:avr:registers [2020/07/20 09:00] (current) – external edit 127.0.0.1 |
---|
====== Registers ====== | ====== Registers ====== |
| |
Ü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. | One of the toughest things for beginners to understand in a microcontroller is typically a register. When dealing with microcontrollers, it is impossible to get by without knowing what this device is. This book is in no way different, as the reader is also expected to familiarize him/herself with the concept of a register and therefore the following text will try to explain it in simple enough terms so that even a beginner can grasp the idea of a register. |
| |
===== Olemus ===== | ===== Essence ===== |
| |
[{{ :images:logic:tape_buttons.jpg?240|Kassetimängija nupud}}] | [{{ :images:logic:tape_buttons.jpg?240|Tape player's buttons}}] |
| |
Register on nagu mõne kodumasina nuppude paneel. Seal on lülitid, mida saab sisse vajutada või välja lükata. Üks parim näide on kassetimängija. Kes veel mäletab, siis kassetimängijatel on (oli) vasakult paremale 6 nuppu: | A register is like a panel of buttons on a home appliance. It has switches, which can be turned on or off. One of the best examples is a simple tape player. For those, who don't remember, the tape player has (had) 6 buttons, left to right: |
| |
* Salvestamine | * Record |
* Tagasikerimine | * Rewind |
* Mängimine | * Play |
* Edasikerimine | * Fast forward |
* Stopp | * Stop |
* Paus | * Pause |
| |
Iga nupp teeb midagi, kuid ainult õigel kasutamisel. Näiteks stopp-nupp ei tee midagi enne, kui kassett on mängima pandud - alles siis teeb see midagi arusaadavat ja peatab mängimise. Edasi- või tagasikerimise nuppe võib aga igal ajal vajutada, sest linti hakatakse kerima nii poole mängimise kui seismise ajal. Salvestama hakkab kassetimängija aga ainult siis, kui salvestamise nupp koos mängimise nupuga alla vajutada. Mõni on ehk proovinud mitu nuppu või kõik nupud korraga alla vajutada - sel juhul võis mängija mida iganes teha või üldse katki minna. | Each button does something, but only when it is used correctly. For example, the stop button does nothing unless a tape is playing - only then will it do something visible and stop the playback. Forward and rewind buttons, on the other hand, can be pressed at any time, because the tape can be wound in both directions, no matter if it is playing or stopped. The recording begins only when the play and record buttons are pressed down simultaneously. Some may have tried to press down several or all buttons at once - in this case, the tape player might have done something unexpected or break altogether. |
| |
Mikrokontrolleri registriga on sama lugu nagu kassetimängija nuppudega - iga nupuke paneb seal õigel kasutamisel midagi käima. Valesid nuppe vajutades mikrokontroller (enamasti) küll katki ei lähe, kuid ei tööta ka. Tegelikult registris selliseid nuppe nagu kodumasinatel muidugi pole, on hoopis hulk transistore, mis elektrit sisse ja välja lülitavad. Lihtsamatel mikrokontrolleritel on registris 8 transistoridel põhinevat elektrilist lülitit. Registrit võib aga käsitleda nagu 8-bitist arvu, milles iga bitt tähistab ühe lüliti olekut. Näiteks biti väärtus 1 võib tähendada, et lüliti on sees ja 0, et lüliti on väljas. | Microcontroller registers behave like buttons on a tape player - each button does something, when used correctly. By pressing the wrong buttons, a microcontroller usually won't break, but it won't work either. In reality, there are no buttons in the registers, instead there are a whole lot of transistors, which turn the electricity on and off. Simpler microcontrollers have 8 transistor-based switches in a single register. A register can be thought of as an 8-bit number, where every bit is marked by the state of one of those switches. For example, a bit value of 1 can mean that the switch is on and 0 that the switch is off. |
| |
[{{ :images:logic:register_buttons_and_bits.png?240|Registri "elektrilülitite asendid" ja nende bitiväärtused}}] | [{{ :images:logic:register_buttons_and_bits.png?240|Register's "buttons" and bit values}}] |
| |
Kuna registri lülitite olekut saab väga hästi esitada arvuna ja vastupidi, siis võib registrit võrrelda ka mäluga, mis suudab hoida ühe arvu suurust informatsiooni. Selle võrdlusega jõudis jutt selleni, et registrid ongi mälupesad. Vahe mälupesaga seisnebki üldjuhul ainult selles, et mälupesa ei tee muud, kui hoiab informatsiooni, registris see informatsioon aga juhib midagi. Ehk kui pildil kujutatud registrisse kirjutada binaarväärtus 01100001, siis kolm näilist lülitit lükatakse alla ja midagi hakkab toimuma. | Since the state of a register's switches can easily be displayed as a number, a register can be compared to a memory, which can hold data in the size of one number. By this comparison, we see that registers actually are memory slots. The difference between a register and a memory slot is that a memory slot only stores the information, but in a register this information actually controls something. For example, if a binary value of 01100001 is written to a register, then three imaginary buttons are pressed down and something happens. |
| |
Kui kassetimängijal võib igat nuppu eraldi vajutada, siis registrites on ühe "lüliti" või biti muutmine keerulisem. Üldjuhul tuleb muuta kogu registri sisu korraga. Enne kui bittide muutmisest rääkida, tuleks aga teada veel seda, et registreid on mikrokontrolleris palju. Mõnede mikrokontrolleri osade juhtimiseks võib kasutusel olla ka kümneid registreid. Registrite paljusus tähendab, et registreid peab kuidagi eristama ja seda tehakse nimega. Üks ilus registri nimi on näiteks PORTB. Tõe huvides võib mainida, et tegelikult on nimed vaid inimese välja mõeldud asendused numbrilistele aadressidele. | On a tape player it is possible to press each button separately, but in a register it is more difficult to change the value of one "switch" or bit. Typically it is necessary to change the entire content of the register. Before moving on to bit changing, one should know that there are a lot of registers in a microcontroller. Some parts of the microcontroller use tens of registers to control them. The variety of registers means that there has to be a way to distinguish between different registers and that is done by naming the registers. One register, for example, is called PORTB. Actually, these names are just to make things easier for the developer and each name corresponds to a numeric address. |
| |
===== Kasutamine ===== | ===== Usage ===== |
| |
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. | To write to a register or read a value from it, it has to be addressed as a variable in C. The following example demonstrates writing a binary value to an imaginary register REG and then reading it to variable //reg//. Binary values are distinguished by 0b (leading zero), so that the compiler understands the numeric system. |
| |
<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 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. | There is nothing difficult in writing and reading register values, but it gets a little tricky if only a single bit needs to be changed. To change bits, one needs to know how to do binary math and use different numeric systems. It isn't forbidden to deal only with binary numbers, but they can be a bit troublesome, because binary numbers are quite long, and this is why most people use shorter hexadecimal numbers. |
| |
[{{ :images:logic:logic_hexadecimal.png?209|Heksadetsimaalnumbrid}}] | [{{ :images:logic:logic_hexadecimal.png?209|Hexadecimal numbers}}] |
| |
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). | In hexadecimal, the numbers are not only 0 and 1 as in binary, or 0 to 9 as in decimal, but instead 0 to F. A hexadecimal number consists of four bits. The table on the right shows the binary numbers and their hexadecimal counterparts. Binary numbers are converted to hexadecimal by reading bits four at a time, starting from the lowest rank. Ranks are read from right to left and their numbers start from 0. For example, the lowest ranked (rank 0) bit is 0 and the highest (rank 3) is 1. In the previous example, the register's binary value is 01100001, which is 61 in hexadecimal and is written as 0x61 (leading zero) in C. |
| |
Ü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. | To change single bits in a number (register, variable or anywhere else for that matter) it is necessary to use binary operations. Binary operation is an operation between two binary numbers, where each bit of the numbers is subject to its own logical operation. Typically a microcontroller supports four binary operations, each having several names. The following section describes the logical operation behind each of these four binary operations with a single bit or multiple bits. |
| |
[{{ :images:logic:logic_all_4.png?550 |Eitus, loogiline korrutamine, loogiline liitmine ja mittesamaväärsus}}] | [{{ :images:logic:logic_all_4.png?550 |Negation, logical multiplication, logical addition and exclusive disjunction }}] |
| |
~~PB~~ | <pagebreak> |
| |
* **Eitus / Inversioon** \\ Eitus muudab biti väärtuse vastupidiseks ehk 0 muutub 1 ja 1 muutub 0. C-keeles on eituse märk "~". | * **Negation / Inversion** \\ Negation changes the bit's value to its opposite, a 0 becomes a 1 and vice versa. In C, negation is marked with "~". |
* **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 "&". | * **Logical multiplication / Conjunction** \\ When multiplying two bits, the answer is 1 if both bits are 1 and in any other case 0. In C, logical multiplication is marked with "&". |
* **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 "|". | * **Logical addition / Disjunction** \\ When adding two bits, the answer is 1 if at least one of the bits is 1 and 0 if both bits are 0. In C, logical addition is marked with "|". |
* **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 "^". | * **Exclusive disjunction / Exclusive OR / XOR** \\ Exclusive OR operation will return 1 if the two bits differ from each other (one is 1 and the other 0), otherwise the answer is 0. In C, exclusive disjunction is marked with "^". |
| |
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. | This is all one needs to know to change single bits. The theory alone is probably not enough, though, and that is why there are some typical examples with registers in the next few paragraphs. |
| |
~~CL~~ | ~~CL~~ |
| |
==== Üksiku biti kõrgeks seadmine ==== | ==== Setting a Single Bit High ==== |
| |
[{{ :images:logic:op_bit_set.png?230|Biti kõrgeks seadmise tehe}}] | [{{ :images:logic:op_bit_set.png?230|Setting a single bit high}}] |
| |
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: | To set one or more bits in a register high (1) a logical addition operation is needed. One of the operands of the operation must be the register and the other a binary number, where the only high bit is the one that needs to be set high in the register. This binary number is called a bitmask. Below is the C code for the operation shown on the right: |
| |
~~CL~~ | ~~CL~~ |
| |
<code c> | <code c> |
// Oletame, et REG = 0x0F | // Let's suppose REG = 0x0F |
REG = REG | 0x11; // Üks meetod | REG = REG | 0x11; // First method |
REG |= 0x11; // Teine meetod | REG |= 0x11; // Second method |
// Siinkohal REG = 0x1F | // Now REG = 0x1F |
</code> | </code> |
| |
==== Üksiku biti madalaks seadmine ==== | ==== Setting a Single Bit Low ==== |
| |
[{{ :images:logic:op_bit_clear.png?229|Biti madalaks seadmise tehe}}] | [{{ :images:logic:op_bit_clear.png?229|Setting a single bit low}}] |
| |
Ühe või enama biti registris madalaks ehk nulliks seadmiseks tuleb kasutada loogilise korrutamise tehet. Tehte üks operand peab olema register, teine bitimask, kus madalaks on seatud vaid see bitt, mida ka registris soovitakse madalaks seada. Kõrvalnäites toodud tehe näeb C-keeles välja nii: | To set one or more bits in a register low (0) a logical multiplication operation is needed. One operand of the operation must be the register and the other a bitmask, in which the only low bit is the one that needs to be set low in the register. Below is the C code for the operation shown on the right: |
| |
~~CL~~ | ~~CL~~ |
| |
<code c> | <code c> |
// Oletame, et REG = 0x0F | // Let's suppose REG = 0x0F |
REG = REG & 0xFE; // Üks meetod | REG = REG & 0xFE; // First method |
REG &= 0xFE; // Teine meetod | REG &= 0xFE; // Second method |
// Siinkohal REG = 0x0E | // Now REG = 0x0E |
</code> | </code> |
| |
~~PB~~ | <pagebreak> |
| |
==== Üksiku biti inverteerimine ==== | ==== Inverting a Single Bit ==== |
| |
[{{ :images:logic:op_bit_invert.png?229|Biti inverteerimise tehe}}] | [{{ :images:logic:op_bit_invert.png?229|Inverting a single bit}}] |
| |
Ühe või enama biti registris inverteerimiseks tuleb kasutada mittesamaväärsuse tehet. Tehte üks operand peab olema register, teine bitimask, kus kõrgeks on seatud vaid see bitt, mida ka registris soovitakse inverteerida. Kõrvalnäites toodud tehe näeb C-keeles välja järgmiselt: | To invert one or more bits in a register an exclusive disjunction operation is required. One of the operands of the operation must be the register and the other a bitmask, where the only high bit is the one that needs to be inverted in the register. Below is the C code for the operation shown on the right: |
| |
~~CL~~ | ~~CL~~ |
| |
<code c> | <code c> |
// Oletame, et REG = 0x0F | // Let's suppose REG = 0x0F |
REG = REG ^ 0x11; // Üks meetod | REG = REG ^ 0x11; // First method |
REG ^= 0x11; // Teine meetod (rakendada tohib korraga ainult üht) | REG ^= 0x11; // Second method (use only one per inversion) |
// Siinkohal REG = 0x1E | // Now REG = 0x1E |
</code> | </code> |
| |
==== Kogu registri inverteerimine ==== | ==== Inverting the Whole Register ==== |
| |
[{{ :images:logic:op_reg_invert.png?229|Bittide inverteerimise tehe}}] | [{{ :images:logic:op_reg_invert.png?229|Inverting all bits}}] |
| |
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: | To invert all bits in a register, a negation operation is used. This operation is unary, which means it has only one operand. Below is the C code for the operation shown on the right: |
| |
~~CL~~ | ~~CL~~ |
| |
<code c> | <code c> |
// Oletame, et REG = 0x0F | // Let's suppose REG = 0x0F |
REG = ~REG; | REG = ~REG; |
// Siinkohal REG = 0xF0 | // Now REG = 0xF0 |
</code> | </code> |
| |
==== Üksiku biti väärtuse lugemine ==== | ==== Reading the Value of a Single Bit ==== |
| |
[{{ :images:logic:op_bit_get.png?229|Biti lugemise tehe}}] | [{{ :images:logic:op_bit_get.png?229|Reading the value of a bit}}] |
| |
Ü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: | To read one or more bits from a register the same operation is required as was used for setting a bit low - logical multiplication. One of the operands of the operation must be the register and the other a bitmask, where the only high bit is the one that needs to be read from the register. Below is the C code for the operation shown on the right: |
| |
~~CL~~ | ~~CL~~ |
| |
<code c> | <code c> |
// Oletame, et REG = 0x0F | // Let's suppose REG = 0x0F |
unsigned char x = REG & 0x01; | unsigned char x = REG & 0x01; |
// Siinkohal x = 0x01 | // Now x = 0x01 |
</code> | </code> |
| |
~~PB~~ | <pagebreak> |
| |
==== Biti nihutamine ==== | ==== Shifting a Bit ==== |
| |
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. | Many programming languages actually have a few additional bitwise operations, which make it easier for programmers. These are bit shifting operations that shift bits left or right in a binary number. The main advantage of shift operations in dealing with registers is their ability to convert bit ranks to bitmasks and vice versa. |
| |
[{{ :images:logic:op_bit_shift_left.png?241|Bitinihe vasakule}}] | [{{ :images:logic:op_bit_shift_left.png?241|Shift left}}] |
| |
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: | The image on the right shows a shift-left operation. Although bit shifting is not a logical operation and has no corresponding symbol, in C it is marked as "<<". Shift-left is used to transform a bit rank to a bitmask. For example, to get the mask for the 6th bit (NB! rank 5), number 1 has to be shifted left 5 times. The example operation looks like this in C: |
| |
~~CL~~ | ~~CL~~ |
<code c> | <code c> |
REG = 0x01 << 5; | REG = 0x01 << 5; |
// Siinkohal REG = 0x20 | // Now REG = 0x20 |
</code> | </code> |
| |
[{{ :images:logic:op_bit_shift_right.png?241|Bitinihe paremale}}] | [{{ :images:logic:op_bit_shift_right.png?241|Shift right}}] |
| |
Sarnaselt bitinihkega vasakule toimib ka bitinihke operatsioon paremale. Selle operatsiooni tähis C-keeles on ">>". Nihet paremale kasutatakse bitimaskist biti loogilise väärtuse leidmiseks. Eespool oli toodud näiteks üksiku biti väärtuse lugemise tehe. Oletame, et bitt, mida lugeda, pole aga madalaima järguga, vaid näiteks järguga 5. Sel juhul oleks lugemisel vastus kas 0x20 või 0x00, kuid vahel läheb vaja vastust 1 või 0 ja siis tulebki appi nihe paremale. Kõrvalnäites toodud operatsioon näeb C-keeles välja nii: | The shift-right operation works similarly to the shift-left operation. It is marked as ">>" in C. Right-shift is used to get the logical value of a bit from a bitmask. A previous example showed how to read the value of a single bit. Let's suppose the bit to be read is not of the lowest rank, but for example of rank 5. In this case, the result would be either 0x20 or 0x00, but sometimes a result of 1 or 0 is needed and that is when the right-shift comes to the rescue. The example operation on the right looks like this in C: |
| |
~~CL~~ | ~~CL~~ |
| |
<code c> | <code c> |
// Oletame, et REG väärtus on 0x20 | // Let's suppose REG = 0x20 |
unsigned char x = REG >> 5; | unsigned char x = REG >> 5; |
// Siinkohal on x väärtus 0x01 (ehk lihtsalt 1) | // Now x = 0x01 (or simply 1) |
</code> | </code> |
| |
Kui bitinihke operatsioonidega nihkub bitt madalaimast järgust paremale või kõrgeimast järgust vasakule, siis see bitt kaob. Mõnedes programmeerimiskeeltes on olemas ka roteeruvad bitinihke operatsioonid, kus "servast" välja minev bitt tuleb teiselt poolt tagasi. C-keeles roteeruvad bitinihke operatsioonid puuduvad, kuid vajadusel saab need ise kirjutada. | If a bit is shifted right from the lowest rank or left from the highest rank by the bit shifting operation, it disappears. Some programming languages also have rotating bit shift operations, where the bit doesn't disappear, but moves from the lowest rank to the highest or vice versa. C doesn't have that kind of bit-shift operations, but they can be written by the programmer if needed. |
| |
Kõik toodud bitioperatsioonide näited toimivad peale registrite ka muutujatega ja konstantidega. Viimased saavad muidugi ainult operandideks, mitte vastusteks olla. | All bit operations work with not only registers, but with variables and constants as well. The latter can of course only be used as operands and not the result. |
| |
===== AVR registrid ===== | ===== AVR Registers ===== |
| |
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. | To actually do anything with the microcontroller's registers, one needs to know how to use that particular microcontroller. Each microcontroller comes with one or several datasheets, which describe the whole structure and functionality of the microcontroller. The datasheet also describes the registers. The following will help understand the register descriptions in AVR datasheets. |
| |
[{{ :images:logic:avr_example_register.png?580 |Üks AVR register selle andmelehest}}] | [{{ :images:logic:avr_example_register.png?580 |One of AVRs registers from its datasheet}}] |
| |
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. | The image shows ATmega128 microcontroller's UCSRnA register, which stands for "USART Control and Status Register A". This register is used to configure AVR's USART module and read its states. All AVR register names are written in capital letters, but as the reader might notice, the register name contains also a lower case n. A lower n is used to mark some module's index. Since ATmega128 has 2 almost identical USART modules, they are not described twice, but only once and the n must be read as 0 or 1 by the user. Therefore ATmega128 has registers UCSR0A and UCSR1A. |
| |
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. | The content of the register is marked by an 8-slot box with a bold line around it. Each slot marks one bit. Bit ranks are marked above the box - increasing from right to left. Since AVR is an 8-bit microcontroller, most of the registers are 8-bit as well. There are some exceptions, a few registers are 16-bit, but they actually consist of two 8-bit registers. Just as each register has a name, each bit in the register also has a name - just like the buttons on a tape player. Each bit is described in the datasheet. Bit names are abbreviations as well and the lower n must be substituted with the module's index, just like with register names. Some registers don't use all 8 bits, in this case the bit's slot is marked with a hyphen. |
| |
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 bit 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//). | Below the register's bits are two lines, which state whether the bit is readable (R), writable (W) or both (R/W). For example, the status bits can't be overwritten and even if it's attempted in the program, the bit will remain unchanged. If the bit is marked as writable, reading it will always result in one specific value stated in the datasheet. The second line specifies the default value of the bit, which it has after the reset of the microcontroller. |
| |
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. | While AVR register names point to an actual memory slot address, the bit names hold the rank number of the corresponding bit. Therefore it is necessary to transform the names to bitmasks using a shift operation, in order to manipulate with bits in a register. The following code contains a few example lines for using the USART 0 module's register. |
| |
<code c> | <code c> |
// TXC0 biti kõrgeks seadmine | // Set TXC0 bit high |
UCSR0A |= (1 << TXC0); | UCSR0A |= (1 << TXC0); |
| |
// U2X0 biti madalaks seadmine | // Set U2X0 bit low |
UCSR0A &= ~(1 << U2X0); | UCSR0A &= ~(1 << U2X0); |
| |
// UDRE0 biti(maski) väärtuse lugemine | // Read the value of UDRE0 bit(mask) |
unsigned char u = (UCSR0A & (1 << UDRE0)); | unsigned char u = (UCSR0A & (1 << UDRE0)); |
| |
// Siinkohal on u väärtus kas 0 või 32, | // At this point u value is either 0 or 32, |
// mis võimaldab seda loogilises avaldises kasutada | // which enables using it in a logical operation |
if (u) | if (u) |
{ | { |
// MPCM0 biti inverteerimine | // Invert MPCM0 bit |
UCSR0A ^= (1 << MPCM0); | UCSR0A ^= (1 << MPCM0); |
} | } |
| |
// Mõnikord on aga vaja saada konkreetne 0 või 1 väärtus, | // Sometimes it is necessary to acquire a specific 0 or 1 value, |
// selleks tuleb loetud bitti nihutada paremale | // so the read bit needs to be shifted right |
u >>= UDRE0; | u >>= UDRE0; |
| |
// Siinkohal on u väärtus kas 0 või 1 | // Now the value of u is either 0 or 1 |
</code> | </code> |
| |