| Next revision | Previous revision |
| pt:avr:registers [2014/12/04 16:35] – created aalmeida | pt:avr:registers [2020/07/20 09:00] (current) – external edit 127.0.0.1 |
|---|
| ====== Registers ====== | ====== Registros====== |
| |
| 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. | Um dos conceitos importantes que estão na base da compreensão dos microcontroladores são os registros. Para que possamos trabalhar com um microcontrolador é fundamental conhecer este dispositivo. |
| |
| ===== Essence ===== | ===== Essencial ===== |
| |
| [{{ :images:logic:tape_buttons.jpg?240|Tape player's buttons}}] | [{{ :images:logic:tape_buttons.jpg?240|Botões do equipamento de cassetes}}] |
| |
| 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: | O registro é como um painel de botões num controlo doméstico. Tem botões, que podem estar ligados ou desligados. Um dos melhores exemplos é um radio de cassetes. Estes equipamentos, como deve recordar, tem seis botões de controlo: |
| |
| * Record | * Gravar |
| * Rewind | * Retrocesso rápido |
| * Play | * Tocar |
| * Fast forward | * Avanço rápido |
| * Stop | * Parar |
| * Pause | * Pausa |
| |
| 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. | Cada botão faz algo, mas apenas quando corretamente acionado. Por exemplo, o botão Parar não faz nada caso a cassete não esteja a Tocar – só no caso de estar a tocar é que a sua ativação resulta em algo observável. Avançar ou Retroceder, por sua vez, podem ser pressionados a qualquer momento, dado que a cassete pode ser movimentada em ambas as direções, independentemente se está a Tocar ou não. Gravar começa quando o botão Tocar é Gravar são pressionados simultaneamente. Poderá tentar pressionar vários botões ao mesmo tempo – caso em que, o equipamento de cassetes poderá fazer algo inesperado ou mesmo deixar de funcionar. |
| |
| 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. | Os registros do microcontrolador comportam-se da mesma forma – cada botão faz algo, quando usado corretamente. Quando pressionamos o botão errado, o microcontrolador pode não deixar de funcionar, mas também não irá funcionar. Na realidade, não existem botões de registro, em vez disso existe um conjunto de transístores, os quais ligam ou desligam a eletricidade. Os microcontroladores mais simples tem 8 comutadores com base em transístores de um só registo. Um registo pode ser considerado como um número de 8 bits, onde cada bit é registado no estado de cada um dos transístores. Por exemplo, um bit com o valor de 1 pode significar que o comutador está ligado e com o valor 0 que o comutador está desligado. |
| |
| [{{ :images:logic:register_buttons_and_bits.png?240|Register's "buttons" and bit values}}] | [{{ :images:logic:register_buttons_and_bits.png?240|Botões do Registo e valores dos bits}}] |
| |
| 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. | Uma vez que o estado dos registos pode facilmente ser mostrado como um número, um registo pode ser comparado com a memória, a qual pode guardar dados do tamanho de um número. Com esta comparação, podemos depreender que os registros são espaços de memória. A diferença entre registos e espaços de memória é que a ultima apenas guarda informação, enquanto o registo na realidade controla algo mais. Por exemplo, se o valor binário 01100001 se encontrar escrito no registo, significa que três dos 8 botões encontram-se pressionados o que implicará algum acontecimento. |
| |
| 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. | No equipamento de cassetes é possível pressionar cada botão separadamente, enquanto que num registo é mais difícil mudar o valor de um comutador ou bit. Normalmente é necessário alterar todo o conteúdo do registo. Antes de avançar para a mudança de bit, devemos ter conhecimento que existem um grande número de registos no microcontrolador. Algumas partes do microcontrolador são controladas por dezenas de registros. A variedade de registos implica haver uma forma de distinguir entre diferentes os diferentes registos o que é feito nomeando-os. Um registo, por exemplo, e denominado PORTB. Na realidade, estes nomes existem apenas para tornar mais simples o desenvolvimento na medida que cada nome corresponde a um endereço numérico. |
| |
| ===== Usage ===== | ===== Utilização ===== |
| |
| 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. | Para escrever num registo ou ler um valor dele, deve ser endereçada a variável em C. O exemplo seguinte demonstra a escrita de um valor binário num registo imaginário REG seguindo-se para a leitura de um valor da variável //reg//. Os valores binários distinguem-se por 0b (zero à esquerda), de forma que o compilador interprete o sistema numérico. |
| |
| <code c> | <code c> |
| </code> | </code> |
| |
| 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. | Não existe nada de difícil em escrever e ler valores de registo, mas pode ser um quanto complicado se se pretende alterar o valor de apenas um dos bits. Para alterar bits, precisamos de saber matemática binária e recorrer a sistemas numéricos diferentes. Não é impossível lidar apenas com sistema binário, mas poderá tornar-se um quanto complicado, uma vez que os números binários podem tornar-se longos, razão pela qual a maioria das pessoas recorre a números hexadecimais. |
| |
| [{{ :images:logic:logic_hexadecimal.png?209|Hexadecimal numbers}}] | [{{ :images:logic:logic_hexadecimal.png?209|Números hexadecimais}}] |
| |
| 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. | No sistema hexadecimal, os números não são apenas 0 e 1 como no sistema binário, ou 0 a 9 no sistema decimal, mas antes de 0 a F. Um número hexadecimal consiste em quatro bits. A tabela ao lado mostra os números binários e os correspondentes hexadecimais. Os números binários são convertidos em hexadecimais lendo os bits ao mesmo tempo, começando pelo de mais baixo nível. Os níveis são lidos da direita para a esquerda e os seus números começam em 0. Por exemplo, o bit de nível mais baixo (nível 0) é 0, e o de nível mais alto é 1. No exemplo anterior, o valor binário do registo é 01100001, o que corresponde a 61 em hexadecimal sendo escrito como 0x61 (zero à esquerda) em C. |
| |
| 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. | Para alterar os bits num número (registo, variável ou noutro local) é necessário realizar operações binárias. As operações binárias é uma operação entre dois números binários, onde cada um dos bits é sujeito à sua operação lógica. Normalmente um microcontrolador suporta quatro operações lógicas, cada qual tendo vários nomes. A secção seguinte descreve as operações lógicas por detrás de cada uma destas operações binárias com um só bit ou com múltiplos bits. |
| |
| [{{ :images:logic:logic_all_4.png?550 |Negation, logical multiplication, logical addition and exclusive disjunction }}] | [{{ :images:logic:logic_all_4.png?550 |Negação, Multiplicação lógica, Adição lógica and disjunção exclusiva }}] |
| |
| ~~PB~~ | <pagebreak> |
| |
| * **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 "~". | * ** Negação / Inversão** \\ A negação altera o valor do bit para o oposto, 0 torna-se 1 e vice-versa. Em C, a negação é representada por “~”. |
| * **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 "&". | * **Multiplicação lógica / Conjugação** \\ Quando a multiplicar dois bits, a resposta é 1 se ambos os bits são 1 e 0 nos casos restantes. Em C, a multiplicação lógica é representada por “&”. |
| * **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 "|". | * **Adição lógica / Disjunção** \\ Quando são adicionados dois bits, a resposta é 1 se pelo menos um dos bits é 1 e 0 quando ambos os bits são 0. Em C, a adição lógica é representada por “|”. |
| * **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 "^". | * **Disjunção exclusiva / OR/OXOR exclusivos** \\ A operação OR exclusiva retornará 1 se os dois bits forem diferentes um do outro (se um for 1 e outro for 0), caso contrário a resposta será 0. Em C, a disjunção exclusiva é representada por “^”. |
| |
| 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. | Isto é tudo que precisamos saber para alterar apenas um bit. A teoria per si poderá não ser suficiente, no entanto, pelo que daremos alguns exemplos a seguir. |
| |
| ~~CL~~ | ~~CL~~ |
| |
| ==== Setting a Single Bit High ==== | ==== Definindo um único bit positivo ==== |
| |
| [{{ :images:logic:op_bit_set.png?230|Setting a single bit high}}] | [{{ :images:logic:op_bit_set.png?230| Definir um único bit como positivo}}] |
| |
| 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: | Para definir apenas um bit num registo para positivo (1) deve ser operada uma adição lógica. Um dos operandos da operação deve ser o registo em conjunto com outro número binário, onde o único bit positivo é aquele que se pretende ver ligado no registo. O número binário é denominado de mascara de bits. Abaixo segue o código em C para a operação em causa: |
| |
| ~~CL~~ | ~~CL~~ |
| |
| <code c> | <code c> |
| // Let's suppose REG = 0x0F | // Vamos supor que REG = 0x0F |
| REG = REG | 0x11; // First method | REG = REG | 0x11; // primeiro método |
| REG |= 0x11; // Second method | REG |= 0x11; // segundo método |
| // Now REG = 0x1F | // Novo REG = 0x1F |
| </code> | </code> |
| |
| ==== Setting a Single Bit Low ==== | ==== Definindo um único bit negativo ==== |
| |
| [{{ :images:logic:op_bit_clear.png?229|Setting a single bit low}}] | [{{ :images:logic:op_bit_clear.png?229|Definir um único bit como baixo}}] |
| |
| 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: | Para definir apenas um bit num registo para negativo (0) deve ser operada uma multiplicação lógica. Um dos operandos da operação deve o registo e outro a mascara de bits, na qual o único bit negativo é o que precisa de ser definido como negativo. A seguir segue o código em C da operação em causa: |
| |
| ~~CL~~ | ~~CL~~ |
| |
| <code c> | <code c> |
| // Let's suppose REG = 0x0F | // Vamos supor que REG = 0x0F |
| REG = REG & 0xFE; // First method | REG = REG & 0xFE; // primeiro método |
| REG &= 0xFE; // Second method | REG &= 0xFE; // segundo método |
| // Now REG = 0x0E | // Novo REG = 0x0E |
| </code> | </code> |
| |
| ~~PB~~ | <pagebreak> |
| |
| ==== Inverting a Single Bit ==== | ==== Inverter um só bit ==== |
| |
| [{{ :images:logic:op_bit_invert.png?229|Inverting a single bit}}] | [{{ :images:logic:op_bit_invert.png?229|Inverter um só bit}}] |
| |
| 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: | Para inverter um ou mais bits num registo é necessário recorrer a uma disjunção exclusiva. Um dos operandos na operação deve ser o registo e outro a mascara de bits, onde o único bit positivo é aquele que precisa de ser invertido no registo. Segue-se o exemplo de código em C: |
| |
| ~~CL~~ | ~~CL~~ |
| |
| <code c> | <code c> |
| // Let's suppose REG = 0x0F | // Vamos supor que REG = 0x0F |
| REG = REG ^ 0x11; // First method | REG = REG ^ 0x11; // primeiro método |
| REG ^= 0x11; // Second method (use only one per inversion) | REG ^= 0x11; // segundo método (usa apenas um por inversão) |
| // Now REG = 0x1E | // Novo REG = 0x1E |
| </code> | </code> |
| |
| ==== Inverting the Whole Register ==== | ==== Invertendo todo o registo ==== |
| |
| [{{ :images:logic:op_reg_invert.png?229|Inverting all bits}}] | [{{ :images:logic:op_reg_invert.png?229|Invertendo todo os bits}}] |
| |
| 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: | Para inverter todos os bits num registo, deve ser usada a negação. Esta operação é unitária, oque significa que recorre apenas um operando. Segue um exemplo de código C para tal operação: |
| |
| ~~CL~~ | ~~CL~~ |
| |
| <code c> | <code c> |
| // Let's suppose REG = 0x0F | // Vamos supor que REG = 0x0F |
| REG = ~REG; | REG = ~REG; |
| // Now REG = 0xF0 | // Novo REG = 0xF0 |
| </code> | </code> |
| |
| ==== Reading the Value of a Single Bit ==== | ==== Ler um valor de um único bit ==== |
| |
| [{{ :images:logic:op_bit_get.png?229|Reading the value of a bit}}] | [{{ :images:logic:op_bit_get.png?229|Ler um valor de um único bit}}] |
| |
| 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: | Para ler um ou mais valores de um registo na mesma operação é necessário recorrer a mesma operação para a definição de um bit positivo – multiplicação logica. Um dos operandos deverá ser o registo e o outro a mascara de bits, onde o único bit positivo é aquele que precisa de ser lido do registo. A seguir apresenta-se um exemplo de código em C para realizar esta operação: |
| |
| ~~CL~~ | ~~CL~~ |
| |
| <code c> | <code c> |
| // Let's suppose REG = 0x0F | // Vamos supor REG = 0x0F |
| unsigned char x = REG & 0x01; | unsigned char x = REG & 0x01; |
| // Now x = 0x01 | // Novo x = 0x01 |
| </code> | </code> |
| |
| ~~PB~~ | <pagebreak> |
| |
| ==== Shifting a Bit ==== | ==== Deslocar um bit ==== |
| |
| 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. | Algumas linguagens de programação tem na verdade umas quantas operações de bits, que tornam mais fácil a programação. Entre estas encontram-se as operações de deslocamento de bits as quais deslocam os bits da esquerda para a direita no seio de um número binário. A maior vantagem das operações de deslocamento no seio de registos é a sua habilidade para converter níveis de bits em mascaras de bits e vice-versa. |
| | A imagem na direita mostra uma operação de deslocamento à esquerda. No entanto o deslocamento de bits não é uma operação lógica e não tem símbolo correspondente, sendo identificada em C por «”. O deslocamento à esquerda é usado para transformar um nível de bits numa mascara de bits. Por exemplo, para obter a mascara do 6º bit (NB! Nível 5), o numero 1 tem que ser deslocado à esquerda 5 vezes. Segue-se um exemplo da operação em C: |
| |
| [{{ :images:logic:op_bit_shift_left.png?241|Shift left}}] | |
| |
| 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: | [{{ :images:logic:op_bit_shift_left.png?241|Deslocar à esquerda}}] |
| | |
| | A imagem na direita mostra uma operação de deslocamento à esquerda. No entanto o deslocamento de bits não é uma operação lógica e não tem símbolo correspondente, sendo identificada em C por «”. O deslocamento à esquerda é usado para transformar um nível de bits numa mascara de bits. Por exemplo, para obter a mascara do 6º bit (NB! Nível 5), o numero 1 tem que ser deslocado à esquerda 5 vezes. Segue-se um exemplo da operação em C: |
| |
| ~~CL~~ | ~~CL~~ |
| <code c> | <code c> |
| REG = 0x01 << 5; | REG = 0x01 << 5; |
| // Now REG = 0x20 | // Novo REG = 0x20 |
| </code> | </code> |
| |
| [{{ :images:logic:op_bit_shift_right.png?241|Shift right}}] | [{{ :images:logic:op_bit_shift_right.png?241|Deslocar à direita}}] |
| |
| 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: | A operação de deslocamento à direita funciona de forma semelhante ao deslocamento à esquerda. É representada em C como “»”. O deslocamento à direita é usado para obter um valor lógico de um único bit. Vamos supor que o bit a ser lido não é o de mais baixo nível, mas por exemplo de nível 5. Neste caso, o resultado poderá ser tanto 0x20 como 0x00, mas por vezes o resultado 1 ou 0 é necessário o que implica deslocamento à direita. Segue-se um exemplo de código em C para o efeito: |
| |
| ~~CL~~ | ~~CL~~ |
| |
| <code c> | <code c> |
| // Let's suppose REG = 0x20 | // Vamos supor que REG = 0x20 |
| unsigned char x = REG >> 5; | unsigned char x = REG >> 5; |
| // Now x = 0x01 (or simply 1) | // Novo x = 0x01 (or simply 1) |
| </code> | </code> |
| |
| 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. | Se um bit for deslocado à direita de uma posição mais baixa ou à esquerda a partir de uma posição mais alta através a operação de deslocamento de bits, este desaparece. Algumas linguagens de programação incluem operações de rotação de bits, nas quais os bits não desaparecem, mas movem-se da posição mais baixa para a mais alta e vice-versa. Em C não existem tais operações, mas o programador poderá desenvolve-las. |
| | Todas as operações com bits funcionam com bits bem como com variáveis e constantes. |
| |
| 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 Registers ===== | ===== Registos AVR ===== |
| |
| 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. | Para na realidade fazer algo nos registos do microcontrolador AVR, precisamos de saber como usar esse microcontrolador em particular. Cada microcontrolador vem dotado de vários folhas de dados (datasheets), as quais descrevem toda a estrutura e funcionalidades do microcontrolador. A folha de dados também escreve os registos. A seguir analisamos um exemplo da descrição dos registos de um microcontrolador AVR. |
| |
| [{{ :images:logic:avr_example_register.png?580 |One of AVRs registers from its datasheet}}] | [{{ :images:logic:avr_example_register.png?580 |Um dos registos AVRs a partir da folha de dados}}] |
| |
| 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. | A imagem mostra o registo UCSRnA do microcontrolador ATmega128, nomenclatura que significa “USART Control and Status Register A”. O registo é usado para configurar o modulo do AVR denominado USART e ler os seus estados. Todos os nomes dos registos do AVR são identificados por caracteres em maiúsculas, mas como poderá verificar, os nomes de registo incluem também algumas letras minúsculas. Uma letra minúscula é usada para denotar o índex do modulo. Uma vez que o ATmega128 tem 2 módulos muito semelhantes, e para evitar descreve-los duas vezes, sendo descritos apenas uma vez devendo neste caso o n ser lido como 0 ou 1. Neste sentido, o ATmega128 tem dois registos UCSR0A e UCSR1A. |
| |
| 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. | O conceito de registo e marcada por uma caixa de 8 retângulos com uma linha espessa a sua volta. Cada retângulo representa um bit. Os níveis dos bits são identificados por debaixo do retângulo – aumentando o numero da direita para a esquerda. Uma vez que o AVR é um microcontrolador de 8 bits, a maioria dos registos também o são. Existem no entanto algumas exceções, alguns registos de 16 bits, mas estes na verdade consistem em dois registos de 8 bits. Tal como cada registo é identificado por um nome, cada bit num registo é identificado por um nome – tal como os botões no equipamento de cassetes. Cada bit descrito na folha de dados. Os nomes de bits também são abreviações devendo o n mais baixo ser substituído pelo índice do modulo, tal como no nome dos registos. Alguns registos não usam todos os 8 bits, caso em que o retângulo de tal bit é identificado por um hífen. |
| |
| 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. | Debaixo dos bits do registo existem duas linhas, que identificam se o bit é possível de ler (R), possível de escrever (W), ou ambos (R/W). Por exemplo, os estados dos bits não podem ser reescritos e mesmo que tal seja tentado num programa, o bit continuara inalterado. Se o bit estiver identificado como possível de escrever (W), a sua leitura resultará sempre num valor especificado na folha de dados. A segunda linha especifica o valor por defeito do bit, o qual é assumido sempre que o microcontrolador é reiniciado. |
| |
| 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. | Enquanto que os registos AVR apontam para espaços de memória reais, os nomes de bits identificam o número de nível do bit correspondente. Pelo que é necessário transformar os nomes em mascaras de bits recorrendo a uma operação de deslocamento, de forma a manipular os bits do registo. O código seguinte demonstra um exemplo que atua sobre o registo do modulo USART 0. |
| |
| <code c> | <code c> |
| // Set TXC0 bit high | // Define bit TXC0 como alto |
| UCSR0A |= (1 << TXC0); | UCSR0A |= (1 << TXC0); |
| |
| // Set U2X0 bit low | // Define o bit U2X0 como baixo |
| UCSR0A &= ~(1 << U2X0); | UCSR0A &= ~(1 << U2X0); |
| |
| // Read the value of UDRE0 bit(mask) | // Lê o valor da mascara de bits UDRE0 |
| unsigned char u = (UCSR0A & (1 << UDRE0)); | unsigned char u = (UCSR0A & (1 << UDRE0)); |
| |
| // At this point u value is either 0 or 32, | // Neste ponto o valor de u é tanto 0 como 32 |
| // which enables using it in a logical operation | // o que permite usa-lo na operação lógica |
| if (u) | if (u) |
| { | { |
| // Invert MPCM0 bit | // Inverte o bit MPCM0 |
| UCSR0A ^= (1 << MPCM0); | UCSR0A ^= (1 << MPCM0); |
| } | } |
| |
| // Sometimes it is necessary to acquire a specific 0 or 1 value, | // Por vezes é necessário adequirir um valor especifico de 0 ou 1 |
| // so the read bit needs to be shifted right | // pelo que a leitura do bit deve ser deslocada para a direita |
| u >>= UDRE0; | u >>= UDRE0; |
| |
| // Now the value of u is either 0 or 1 | // Agora o valor de u é 0 ou 1 |
| </code> | </code> |
| |