====== Arquitetura ======
O AVR tem um bus de 8-bits, através do qual os dados são movidos entre unidades lógicas aritméticas (ALU), registos de estados (SREG), controladores de programa (PC), memória de acesso aleatório (SRAM) e periféricos. O programa, uma matriz de comandos, é executado na ALU, vindo de um endereço na memória de acesso rápido, especificado no controlador do programa. A ALU tem 32 registos de finalidade genérica de 8 bits, os quais são usados como operandos na realização das operações.
[{{ :images:avr:avr_atmega128_block_diagram.png?580 |Diagrama de blocos de um ATmega128}}]
===== Pipeline de Instruções =====
O AVR tem um //pipelines// (canalizador) de instruções de duas fases. Enquanto algumas instruções é executada, a próxima é movida da memória do programa. Razão pela qual as instruções de transposição demoram dois ciclos para realizar uma condição de transposição. Uma vez que a próxima instrução é sempre movida do próximo endereço de memória, é necessário descartar a instrução movida anteriormente, e mover uma nova.
===== Registo de uso geral =====
Os registos de uso geral R0-R31 funcionam como //buffers// (contentores temporários) para guardar e operar com os dados da memória e dos periféricos. Simplificam a arquitetura do processador, uma vez que são acessíveis rapidamente pela ALU, e usam os dados do //bus// para ler os operandos na memória, o que não é necessário para todas as operações. Os registos de uso geral usam-se para realizar todas as operações lógicas e aritméticas relacionadas com dados.
Na programação em assembler é possível guardar os dados urgentes nos registos de uso geral. Na programação em C, e existindo a necessidade de guardar uma variável no registo de uso geral, esta variável tem que definida como “register”. Por exemplo:
Por exemplo:
register char x;
===== Conjunto de instruções =====
O conjunto de instruções definido na maioria dos AVRs consistem em 90-133 instruções diferentes. O ATmega128 tem 133 instruções. As instruções tem um, dois ou nenhum operando. A maioria das instruções realizam-se em apenas uma instrução, mas as mais complexas podem usar até 5 ciclos. Para o XMega, o sucessor do AVR, foram modificadas várias instruções de forma a usar menos ciclos. A maioria das instruções no AVR são usadas para realizar transposições, mover e comparar dados e executar cálculos aritméticos. Para fazer comparações e cálculos é usado o registo de estado. Este guarda o resultado do estado na ALU – quer o resultado seja negativo, positivo, zero, excedendo o valor máximo permitido (8 bits), quando existe a necessidade de transferir um bit para o operador seguinte (existem operações mais complexas).
Este é um pedaço de código escrito em Assembler e consiste em instruções puras, que adicionam 5 ao byte na memória de acesso aleatório no endereço $100 (256 em decimal). Estas instruções existem em todos os AVRs.
ldi r1, 5 ; lê a constante 5 para o registo de uso geral r1
lds r2, $100 ; lê o byte do registo de memória r2
add r2, r1 ; adiciona o valor de r1 ao do r2
sts $100, r2 ; escreve o valor de r2 na memória
===== Stack do programa =====
Uma //stack// é uma estrutura, onde a os últimos dados escritos na memória são lidos em primeiro lugar. As //stacks// dos AVR podem ser usados na operação de sub-rotinas, interrupções e dados temporários. Antes de executar uma sub-rotina ou interrupção, este endereço é lido a partir da //stack// de forma que o programe continue a partir da localização que havia deixado para tal fim. Normalmente recorre-se ao armazenamento de dados na //stack// quando se pretende lidar com pequenos blocos de dados, que não carecem de memória reservada durante a execução do programa. Os programas em assembler mais simples são escritos de forma a não usar o //stack//, mas se o programa usar muitas variáveis e funções, o compilador faz uso desta automaticamente.
O //stack// da série de microcontroladores AVR encontra-se localizada fisicamente na memória de acesso aleatório. Algumas séries de dispositivos AVR não dispõem de memória de acesso aleatório sendo a //stack// efetuada por uma unidade de memória pequena separada. É difícil encontrar compiladores para dispositivos sem memória de acesso aleatório.
Para programar numa linguagem de alto nível (por exemplo em Pascal, C, ou C++), pode dispensar conhecimento aprofundado sobre o funcionamento interno de um microcontrolador, uma vez que o compilador tem a capacidade de selecionar os registos de uso geral e as instruções, no entanto ter conhecimento do que se passa no seio do controlador pode trazer benefícios. Torna-se importante conhecer as instruções de um microcontrolador quando se pretende desenvolver aplicações o tempo é crítico, quando as operações devem ser realizadas num número limitado de ciclos.