Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Apostila Programando AVR , Notas de estudo de Engenharia Informática

Nesta apostila é feita uma introdução muito boa na linguagem assembly para microcontroladores avr.

Tipologia: Notas de estudo

Antes de 2010

Compartilhado em 10/05/2010

fabio-almeida-31
fabio-almeida-31 🇧🇷

4

(1)

1 documento

1 / 63

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
Introdução para o iniciante à
Linguagem Assembly dos
Microprocessadores ATMEL-AVR
por
Gerhard Schmidt
http://www.avr-asm-tutorial.net
Dezembro de 2003
Versão corrigida em Julho de 2006
Correções adicionais e atualizações em Janeiro de 2008
Traduzido por Guilherme Groke – [email protected]
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34
pf35
pf36
pf37
pf38
pf39
pf3a
pf3b
pf3c
pf3d
pf3e
pf3f

Pré-visualização parcial do texto

Baixe Apostila Programando AVR e outras Notas de estudo em PDF para Engenharia Informática, somente na Docsity!

Introdução para o iniciante à

Linguagem Assembly dos

Microprocessadores ATMELAVR

por

Gerhard Schmidt

http://www.avrasmtutorial.net

Dezembro de 2003

Versão corrigida em Julho de 2006 Correções adicionais e atualizações em Janeiro de 2008 Traduzido por Guilherme Groke – [email protected]

Conteúdo

Porque aprender Assembler?

Assembler ou outras linguagens, esta é a questão. Porque eu deveria aprender mais uma linguagem, se eu já conheço outras linguagens de programação? O melhor argumento: enquanto você viver na França, poderá sobreviver falando Inglês, mas você nunca se sentirá em casa, e a vida fica difícil. Você pode apenas continuar desta forma, mas isto não é apropriado. Se as coisas ficarem complicadas, você deverá usar a linguagem corrente do país Muitas pessoas já experientes em programação de AVRs e que usam linguagens de alto nível em seu trabalho normal, recomendam que os iniciantes comecem aprendendo linguagem assembly. A razão para isto é que, algumas vezes, podem ocorrer certas situações, como: ● se bugs têm que ser analizados, ● se o programa faz coisas diferentes das que foram escritas e são esperadas, ● se linguagens de alto nível não suportam o uso de certas características do hardware, ● se rotinas em que a temporização é crítica requerem porções de linguagem assembly, é necessário entender a linguagem assembly, e.g., entender o que os compiladores de linguagens de alto nível produzem. Sem compreender a linguagem assembly, você não terá chance de ir adiante nestes casos.

Curta e fácil

Os comandos assembler são traduzidos um a um para serem comandos executados pela máquina. O processador necessita apenas executar o que você quer fazer e o necessário para executar a tarefa. Nenhum loop extra ou características desnecessárias poluem o código. Se o espaço para o seu programa é curto e limitado e você terá que otimizar seu programa para caber na memória, assembler é a escolha número um. Programas mais curtos são mais fáceis de depurar (“debugar”), cada passo faz sentido.

Veloz

Como apenas os passos necessários são executados, os programas em assembly são tão rápidos quanto possível. Aplicações onde o tempo é crítico, como medições de tempo que devam ter boa performance, sem que haja um hardware de temporização, devem ser escritas em assembler. Se você tiver mais tempo e não se importar que seu chip permaneça 99% em um estado de espera (wait state) de operação, você pode escolher a linguagem que desejar.

Assembler é de fácil aprendizado

Não é verdade que a linguagem assembly é mais complicada ou não é tão fácil de compreender quanto outras linguagens. Aprender linguagem assembly para qualquer tipo de hardware facilita a compreensão de conceitos de qualquer outro dialeto da linguagem assembly. Aprender outros dialetos depois é mais fácil. Algumas características são dependentes do hardware, e isto requer alguma familiaridade com os conceitos de hardware e seus dialetos. O que faz o assembler parecer complicado algumas vezes é que ele requer uma compreensão das funções do controlador do hardware. Linguagens de alto nível não permitem a utilização de características especiais do hardware, e escondem estas funções. O primeiro código assembly não parece muito interessante, mas depois de 100 linhas adicionais programadas, parecerá melhor. Programas perfeitos requerem apenas alguns milhares de linhas de código de exercício, e otimização requer bastante trabalho. Os primeiros passos são difíceis em qualquer linguagem. Após algumas semanas programando, você dará risada se analisar seu primeiro código. Alguns comandos em assembler requerem meses de experiência.

AVRs são ideais para se aprender assembler

Programas em assembler são um pouco tolos: o chip executa tudo que você disser a ele para fazer, e não pergunta se você tem certeza se quer sobrescrever isso ou aquilo. Todas as características de proteção devem ser programadas por você, o chip faz exatamente aquilo que lhe é comandado, mesmo que não faça sentido algum. Nenhuma janela o alertará, a menos que você a tenha programado anteriormente. Para corrigir erros de digitação é tão fácil ou complicado como qualquer outra linguagem. Existem erros básicos ou mais complicados. Porém: testar os programas nos chips ATMEL é muito fácil. Se o chip não faz o que você espera, você pode facilmente adicionar algumas linhas de diagnóstico ao código, reprogramá-lo e testá-lo. Adeus, programadores de EPROM, lâmpadas UV usadas para apagar o programa, pinos que não se encaixam mais no soquete após tê-los removido uma dúzia de vezes. As mudanças agora são programadas rapidamente, compiladas imediatamente, ou mesmo simuladas no studio ou checadas no próprio circuito. Nenhum pino tem que ser removido, e nenhuma lâmpada de UV te

deixará na mão justamente no momento em que você teve uma excelente idéia sobre aquele bug.

Teste!

Seja paciente nos seus primeiros passos! Se você tem familiaridade com outra linguagem (alto nível): esqueça-a por enquanto. A maioria das características especiais de outras linguagens de computação não fazem nenhum sentido em assembler. As primeiras cinco instruções não são fáceis de aprender, depois disso sua velocidade de aprendizado aumentará rapidamente. Depois que você escreveu as primeiras linhas: pegue o conjunto de instruções e leia-o deitado em sua banheira, imaginando para que servem todas as outras instruções. Aviso sério: Não tente criar uma mega-máquina logo de início. Isto não faz sentido algum em nenhuma linguagem de programação, e apenas produz frustração. Comece com pequenos exemplos tipo “Olá Mundo”, e.g., ligando e desligando LEDs por algum tempo, e só então comece a explorar as características do hardware mais profundamente. Recomendação: Comente suas subrotinas e armazene-as em um diretório especial, se debugadas: você precisará delas em breve. Sucesso!

(com pequenas mudanças no circuito). Se você utilizar HC, não se esqueça de conectar os pinos não utilizados ao terra ou à tensão de alimentação, caso contrário os buffers podem produzir ruído capacitivo pelo chaveamento. Todo o algoritmo de programação necessário é feito pelo software ISP. Esteja ciente que esta interface paralela não é mais suportada pelo software Atmel Studio. Portanto, se você desejar programar seu AVR diretamente do studio, utilize programadores diferentes. A internet fornece diversas soluções. Se você já tiver uma placa de programação, você não precisará construir este programador, porque você encontrará a interface ISP em alguns pinos. Consulte o manual para localizá-los.

Placas experimentais

Você provavelmente quer fazer seus primeiros programas com uma placa AVR feita em casa. Aqui apresentamos duas versões: ● Uma bem pequena com um ATtiny13, ou ● uma mais complicada com um AT90S2313 ou ATmega2313, incluindo uma interface serial RS232.

Placa experimental com ATtiny

Esta é uma placa bem pequena que permite experimentos com o hardware interno do Attiny13. A figura mostra ● A interface de programação ISP10 à esquerda, com o LED de programação ligado a um resistor de 390 ohms, ● o ATtiny13 com um resistor pull-up de10k no pino RESET (pino 1),

  1. a fonte de alimentação com um retificador em ponte, que aplica de 9 a 15V a partir de uma fonte AC ou DC, e um pequeno regulador de 5V.

O ATtiny13 não requer cristal externo ou gerador de clock, pois trabalha com o seu gerador RC interno de 9,6 Mcs/s e, por padrão, com um divisor de clock em 8 (freqüência de clock de 1,2 Mcs/s). O hardware pode ser construido em uma pequena placa como a mostrada na figura. Todos os pinos do tiny13 são acessíveis, e componentes externos ao hardware, como o LED mostrado, são facilmente conectados. Esta placa permite o uso dos componentes de hardware do Attiny13, como portas E/S, timers, conversores AD, etc.

Placa experimental com um AT90S2313/ATmega

Para fins de teste, ou se mais pinos de E/S ou comunicação serial forem necessários, podemos utilizar um AT90S2313 ou Atmega2313 em uma placa experimental. O esquema mostra

  • uma pequena fonte de alimenação para conecção a um transformador AC e um regulador de tensão 5V/1A,
  • um gerador de clock a cristal (aqui com um cristal de 10 MHz, qualquer freqüência abaixo do máximo especificado para o AT90S2313 funcionarão), os componentes necessários para um reset seguro durante o momento da partida da alimentação,
  • a interface de programação ISP (com o conector ISP10). É isto que você precisa para iniciar. Conecte os outros periféricos e adicionais aos numerosos pinos livres de E/S ao 2313. O dispositivo de saída mais fácil pode ser um LED, conectado a um resistor à tensão de alimentação. Com isso, você pode escrever o seu primeiro programa em assembler para acender e apagar o LED. Se você ● não precisar da interface de comunicação serial, simplesmente ignore o hardware conectado aos pinos 2/3 e 14/16,

A programação é realizada e controlada pelas versões recentes do AVR studio, que está disponível gratuitamente para download pela página da ATMEL após o registro. Atualizações na lista de dispositivos e algoritmos de programação são fornecidos com as versões do Studio, então o suporte para novos dispositivos é mais provável do que com outras placas e softwares de programação. Os experimentos podem começar com o AVR fornecido (versões antigas: AT90S8515, novas placas incluem tipos diferentes). Este kit cobre todas as necessidades que o iniciante pode ter.

AVR Dragon

O AVR Dragon é uma pequena placa. Ela possui uma interface USB, que alimenta a placa e a interface ISP de 6 pinos. A interface ISP de 6 pinos é acompanhada pela interface de programação HV de 20 pinos. A placa é preparada para receber alguns soquetes, mas não possui soquetes para dispositivos para gravação ou outro hardware. O dragon é suportado pelo software Studio e é atualizado automaticamente. Seu preço e design o torna um excelente presente para o amador de AVR.

Ferramentas para programação assembly

AVR

Quatro ferramentas básicas são necessários para programação em assembly. Estas ferramentas são:

  • o editor,
  • o compilador,
  • a interface para programação do chip, e
  • o simulador. Para realizar estas tarefas, existem dois caminhos:
  1. todos as ferramentas em um só programa,
  2. cada tarefa é realizada por um programa específico, e os resultados são armazenados em arquivos específicos. Normalmente a primeira opção é escolhida. Porém, como isto é um tutorial, e você deve compreencer o mecanismo primeiro, começaremos descrevendo a segunda opção.

De um arquivo texto a palavras de instrução para a

memória flash

O editor

Os programas assembler são escritos com um editor. O editor simplesmente tem que criar e editar texto ASCII. Então, basicamente, qualquer editor simples serve. Algumas características do editor podem ter efeitos positivos: ● Erros, que o assembler detecta depois, são reportados juntamente com o número da linha do arquivo texto. Números de linha são também uma poderosa invenção da era do computador com respeito a discussões no seu código com alguém. Então o seu editor deve ser capaz de mostrar o número da linha. Infelizmente, quase todos os editores que uma poderosa empresa de software fornece como parte dos seus sistemas operacionais, não possuem esta característica. Provavelmente o Windows 2019 reinvente esta característica, e venda melhor entre os malucos por assembler. ● Erros de digitação são muito reduzidos, se estes erros forem marcados com cores. É uma ótima caracteristica de um editor, destacar os componentes de uma linha em diferentes cores. Reconhecimento inteligente dos erros facilita a escrita. Mas é uma característica que eu não sinto falta. ● Se seu editor permite a seleção de fonte, escolha uma fonte com espaço fixo, como Courier. Os cabeçalhos ficam melhor assim. ● Seu editor deve ser capaz de reconhecer fim de linhas com qualquer combinação de caracteres (carriage return, line feed, ambos) sem produzir telas inaceitáveis. Outro item na lista de desejos para o Windows 2013. Se você prefere matar moscas com canhão, você pode usar um software processador de texto poderodo para escrever os seus programas em assembler. Pode parecer mais bonito, com cabeçalhos em fonte grande e negritos, comentários em cinza, avisos em vermelho, mudanças destacadas, e lembretes e to- dos em campos extra destacados. Algumas desvantagens, contudo: você terá que converter o seu texto em texto simples no final, perdendo todo o seu trabalho de design, e o seu arquivo texto resultante não poderá ter um único byte de controle faltando. Caso contrário, este único byte gerará uma mensagem de erro, quando você tentar processar o texto. E lembre-se: Números de linha estarão apenas corretos na página do seu código-fonte.

caso, porque não programamos nada para a EEPROM. O compilador, conseqüentemente deletou este arquivo quando terminou a montagem, pois era vazio. O segundo arquivo, TEST.HEX, é mais relevante pois ele guarda os comandos que serão posteriormente gravados no chip AVR. Este arquivo se apresenta assim. Os números hexadecimais estão escritos em um formato ASCII especial, juntamente com as informações de endereço e checksum para cada linha. Este formato é chamado Intel-hex, é muito antigo e remonta para os primórdios da computação. Este formato é bem compreendido pelo software de programação. O terceiro arquivo, TEST.OBJ, será explicado depois, este arquivo é necessário para simular um AVR. Seu formato é hexadecimal e definido pela ATMEL. Usando um editor hexa, seu conteúdo é assim. Atenção: Este formato de arquivo não é compatível com o software de programação, não use este arquivo para programar um AVR (um erro muito comum no início). Arquivos OBJ são produzidos apenas por alguns assemblers ATMEL, não os espere de outros assemblers. O quarto arquivo, TEST.LST, é um arquivo texto. Abra- o com um editor simples. Será visto uma tela como a mostrada aqui. O programa com todos os seus endereços, comandos e mensagens de erro são mostrados em uma forma legível. Você precisará deste arquivo em alguns casos para depurar erros. Arquivos de lista são gerados apenas se a opção é especificada na linha de comando e se a diretiva .NOLIST não suprimir a listagem.

Programando os chips

Para programar nosso código hexa, como codificado no arquivo .HEX, no AVR, um software programador é necessário. Este software lê o arquivo .HEX e transfere o seu conteúdo, seja bit a bit (programação serial), seja byte a byte (programação paralela) para a memória flash do AVR. Iniciamos o software de programação e carregamos o arquivos hex que acabamos de gerar. Em nosso exemplo, a tela seria semelhante a esta. Note: a janela apresentada mostra a tela do ISP.exe, um programa histórico não mais distribuído pela ATMEL. Outros softwares programadores são semelhantes. Este software gravará nosso código no local designado no chip. Há algumas precondições necessárias para fazer isto, e várias razões possíveis para uma falta. Consulte a ajuda do software programador, se ocorrerem problemas. Hardware de programação e alternativas de software apropriadas para diferentes sistemas operacionais estão disponíveis na Internet. Como exemplo de um programador pela porta paralela ou serial, menciono o PonyProg2000.

Simulação no studio

Às vezes, o código escrito em assembly, mesmo que seja compilado sem erros, não faz exatamente o que deveria depois de gravado no chip. Testar o software no chip pode ser complicado, especialmente se você tem um hardware mínimo e não tem oportunidade de visualizar resultados intermediários ou sinais de debug. Nestes casos, o pacote de software Studio da ATMEL fornece oportunidades perfeitas para depuração. Testar o software ou somente partes é possível, e o código do programa pode ser testado passo a passo mostrando os resultados. As imagens mostradas aqui são tiradas da Versão 3 do Studio. A Versão 4 atual é visualmente diferente, mas faz praticamente a mesma coisa. Primeiramente abriremos um arquivo (menu FILE – OPEN). Demonstraremos utilizando o arquivo tutorial test1.asm, pois nele há mais alguns comandos e ações do que em nosso programa de um único comando acima. Abra o arquivo TEST1.OBJ, que resultou da compilação do TEST1.asm. Lhe é perguntado que opções você gostaria de usar (se não você pode alterar através do menu SIMULATOR – OPTIONS). Selecione as seguintes opções: ● Dispositivo é um AT90S8515, ● Freqüência do clock é 4 MHz. Na seção de seleção de dispositivos, selecionamos o tipo de chip desejado. A frequência correta deve ser selecionada, se você deseja simular temporização correta. Para podermos ver o conteúdo de alguns registradores e o que o status atual do processador, selecionamos VIEW PROCESSOR e REGISTERS. Agora a imagem deve ser a seguinte. A janela do processador mostra vários valores, como onde o contador de comando está, os registradores de flag de status, e a informação sobre temporização (aqui a um clock de 1 MHz). O cronômetro por ser usado para fazer uma medida exata do tempo necessário para executar rotinas etc. Agoa iniciaremos a execução do programa. Usaremos o modo de passo a passo (TRACE INTO ou F11). Usando GO resultaria em uma execução contínua e nada seria visto devido à alta velocidade da simulação.

Registrador

O que é um registrador?

Registradores são locais especiais de armazenagem com capacidade de 8 bits e são da seguinte forma: Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Note a numeração destes bits: o bit menos significativo inicia com zero (2^0 = 1). Um registrador pode tanto armazenar números de 0 a 255 (somente números positivos), ou números de - 128 a +127 (número inteiro com o bit 7 indicando o sinal), ou o valor que representa um caractere ASCII (e.g. 'A'), ou apenas oito bits que não têm nada a ver um com outro (e.g., para oita flags usados para sinalizar oito decisões sim/não diferentes). A característica especial dos registradores, comparada a outros locais de armazenagem, é que

  • eles podem ser usados diretamente por comandos assembler,
  • operações com o seu conteúdo requerem somente uma palavra de comando,
  • eles são conectados diretamente à unidade central de processamento chamada acumulador,
  • eles são origem e destino para cálculos. Há 32 registradores em um AVR. Eles são originalmente chamados R0 a R31, mas você pode escolher nomeá-los com nomes que façam sentido em uma diretiva assembler. Um exemplo: .DEF MeuRegistradorPreferido = R As diretivas de assembler sempre iniciam com um ponto na coluna 1 do texto. Instruções NUNCA iniciam na coluna 1, eles sempre serão precedidos por um caractere vazio ou de tabulação! Note que as diretivas de assembler como esta significam alguma coisa apenas para o compilador assembler mas não produzem nenhum código executável no chip destino AVR. No lugar de utilizar o registrador com nome R16, podemos utilizar nosso próprio nome MeuRegistradorPreferido, quando quisermos usar R16 com algum comando. Então escrevemos um pouco mais cada vez que queremos utilizar este registrador, mas temos uma associação ao que pode ser o conteúdo deste registrador. Usando a linha de comando LDI MeuRegistradorPreferido, 150 significa: carregue o número 150 imediatamente para o registrador R16, LoaD Immediate, carregar imediato_._ Isto carrega um valor fixo ou uma constante neste registrador. Se observarmos a tradução deste código no programa escrito no AVR, veremos o seguinte: 000000 E O comando load, bem como o registrador destino (R16), assim como o valor da constante (150) é parte do valor hexa E906, mesmo que você não os veja diretamente. Não tenha medo: você não tem que lembrar esta codificação porque o compilador sabe traduzir tudo isto para o esquisito E906. Dentro de um único comando, dois diferentes registradores podem desempenhar um papel. O comando mis fácil teste tipo é o comando de cópia MOV. Ele copia o conteúdo de um registrador em outro. Assim: .DEF MeuRegistradorPreferido = R .DEF OutroRegistrador = R LDI MeuRegistradorPreferido, 150 MOV OutroRegistrador, MeuRegistradorPreferido As duas primeiras linhas deste programa monstruoso são diretivas que definem os novos nomes dos registradores R16 e R15 para o compilador assembler. Novamente, estas linhas não produzem nenhum código para o AVR. As linhas de comando com LDI e MOV produzem o código: 000000 E 000001 2F Os comandos escrevem 150 no registrador R16 e copiam o seu conteúdo para o registrador destino R15. NOTA IMPORTANTE: O primeiro registrador é sempre o registrador destino onde o resultado será escrito! (Isto infelizmente é diferente da forma normalmente esperada ou de como falamos. É uma convenção simples que foi definida certa vez para confundir os iniciantes aprendendo assembler. É por isso que assembler é tão complicado.)

Registradores diferentes

O iniciante pode querer escrever os comandos acima assim: .DEF OutroRegistrador = R LDI OutroRegistrador, 150 E: você falha. Apenas os registradores de R16 a R31 carregam uma constante imediamente com o comando LDI, R0 a R15 não fazem isso. Esta restrição não é muito interessante, mas não pôde ser evitada durante a construção do conjunto de comandos dos AVRs. Há uma exceção a esta regra: escrever Zero em um registrador. O comando CLR MeuRegistradorPreferido é válido para todos os registradores. Além do comando LDI, você descobrirá que esta restrição de classes de registradores ocorre também com os seguintes comandos:

  • ANDI Rx,K ; Operação And dos bits do registrador Rx com os bits do valor constante K,
  • CBR Rx,M ; zera todos os bits no registrador Rx que estão em um dentro do valor de máscara constante M.
  • CPI Rx,K ; Compara o conteúdo do registrador Rx com o valor constante K,
  • SBCI Rx,K ; Subtrai a constante K e o valor atual da flag de carry (transporte) do registrador Rx e armazena o resultado no registrador Rx,
  • SBR Rx,M ; Seta todos os bits no registrador Rx para um, que são um na máscara constante M,
  • SER Rx ; Seta todos os bits no registrador Rx para um (igual a LDI Rx,255),
  • SUBI Rx,K ; Subtrai a constante K do conteúdo do registrador Rx e armazena o resultado no registrador Rx. Em todos estes comandos o registrador deve ser entre R16 e R31! Se você planeja utilizar estes comandos, você deve selecionar um destes registradores para a operação. É mais fácil de programar. Há uma razão adicional pela qual você deve definir o nome dos registradores, é porque você pode facilmente alterar a localização dos registradores posteriormente.

Registradores ponteiros

Um papel muito especial é desempenhado pelos pares de registradores R27:R26, R29:R28 e R31:R32. Este papel é tão importante que estes pares têm nomes extra curtos em AVR assembler: X, Y e Z. Estes nomes curtos são compreendidos pelo compilador. Estes pares são registradores ponteiros de 16 bits, capazes de apontar endereços da SRAM com até 16 bits (X, Y ou Z) ou localizações na memória do programa (Z). O byte menor do endereço de 16 bits está localizado no registrador inferior, o byte superior na registrador superior. Ambas partes têm seu próprio nome, e.g., o byte mais alto de Z é chamado de ZH (=R31), e o byte mais baixo é ZL (=R30). Estes nomes são definidos no arquivo de cabeçalho padrão para os chips. Dividir estes dois ponteiros de 16 bits em dois bytes diferentes é feito da seguinte forma: .EQU endereco = RAMEND ; RAMEND é o endereço de 16 bits mais alto da SRAM (fim da memória) LDI YH,HIGH(endereco) ; Seta o MSB LDI YL,LOW(endereco) ; Set the LSB Acessos via ponteiros são feitos com comandos especialmente designados. A leitura é feita pelo comando chamado LD ( LoaD , carregar), e a escrita pelo comando chamado ST ( STore , armazenar), e.g. Com o ponteiro X: Ponteiro Seqüência Exemplos X Lê/Escreve do endereço X, não altera o ponteiro LD R1,X ou ST X,R X+ Lê/Escreve de/para endereço X e incrementa o ponteiro por um LD R1,X+ ou ST X+,R -X Decrementa o ponteiro em um e lê/escreve de/para o novo endereço LD R1,-X ou ST -X,R De forma similar, você pode usar Y e Z para este propósito. Há somente um comando para acesso à leitura dos dados do programa. Ele é definido pelo par de ponteiros Z e é chamado LPM ( Load from Program Memory, carregar da memória do programa). O comando copia o byte no endereço Z da memória do programa para o registrador R0. Como a memória do programa é organizada na forma de palavras (um comando em um endereço consiste de 16 bits ou dois bytes ou uma palavra), o bit menos significativo seleciona o byte inferior ou superior (0=inferior, 1=superior). Por causa disto, o endereço original deve ser multiplicado por 2 e o acesso é limitado a 15 bits ou 32kb da memória do programa. Desta forma:

Portas

O que é uma Porta?

As portas do AVR são caminhos entre a unidade central de processamento e os componentes externos de hardware e software. A CPU se comunica com estes componentes, lendo deles ou escrevendo neles, e.g. timers ou portas paralelas. A porta mais utilizada é o registrador de flag, onde os resultados das operações anteriores são escritos e de onde as árvores de condições (decisões) são lidas. Há 64 portas diferenentes, que não estão disponíveis em todos tipos de AVR. Dependendo do espaço de armazenamento e outros hardwares internos, as portas podem estar disponíveis e acessíveis ou não. A lista de portas que podem ser usadas está listada nos data sheets do processador. As portas têm endereço fixo, pelo qual a CPU se comunica. O endereço é independente do tipo de AVR. Assim, por exemplo, o endereço da porta B é sempre 0x18 (0x indica notação hexadecimal). Você não tem que lembrar destes endereços das portas, elas têm apelidos convenientes. Estes nomes são definidos nos arquivos include (cabeçalhos) para os diferentes tipos de AVR, fornecidos pelo fabricante. Os arquivos include têm uma linha definindo o endereço da porta B como a seguir: .EQU PORTB, 0x Então temos que lembrar apenas o nome da porta B, não sua localização no espaço de E/S do chip. O arquivo de inclde 8515def.inc está envolvido através da diretiva do assembler .INCLUDE "C:\Somewhere\8515def.inc" e todos os registradores de 8515 estarão definidos e facilmente acessíveis. As portas normalmente são organizadas como números de 8 bits, mas podem manipular 8 bits individuais que não têm a ver uns com os outros. Se estes bits têm um significado, eles podem ter seu próprio nome associado no arquivo include, para permitir a manipulação deste bit. Graças à convenção dos nomes, você não tem que lembrar a posição destes bits. Estes nomes são definidos nos data sheets e estão incluídos nos arquivos include, também. Eles são fornecidos aqui nas tabelas das portas. Como exemplo, o registrador de controle geral MCU, chamado MCUCR, consiste de um número de bits de controle individuais que controlam algumas características gerais do chip (veja a descrição em MCUCR para maiores detalhes). É uma porta, com 8 bits de controle e seus próprios nomes (ISC00, ISC01, ...). Quem quiser mandar o seu AVR para um sono mortal precisa saber pelo data sheet como setar os bits respectivos. Assim: .DEF MeuRegistradorPreferido = R LDI MeuRegistradorPreferido, 0b OUT MCUCR, MeuRegistradorPreferido SLEEP O comando Out envia o conteúdo do meu registrador preferido, um bit Sleep-Enable chamado SE, para a porta MCUCR e seta o AVR imediatamente para entrar em repouso, se houver uma instrução SLEEP sendo executada. Como todos os outros bits do MCUCR foram setados pelas instruções acima, e o bit SM (Sleep Mode) ficou zero, ocorrerá um modo chamado meio-repouso: não haverá execução de nenhum outro comando, mas o chip ainda reage a timers e outras interrupções de hardware. Estes eventos externos interromperão o sono da CPU se eles acharem que devem notificá-la. Ler o conteúdo de uma porta é possível na maioria dos casos utilizando o comando IN. A sequência .DEF MeuRegistradorPreferido = R IN MeuRegistradorPreferido, MCUCR lê os dados da porta MCUCR para o registrador. Como muitas portas são usadas parcialmente ou não utilizadas, normalmente os dados lidos são zeros. Mais freqüentemente do que ler todos os 8 bits de uma porta, deve-se reagir a certos status de uma porta. Neste caso, não precisamos ler a porta toda e isolar o bit de interesse. Certos comandos permitem executar comandos dependendo do estado de certo bit (veja a seção JUMP). Setar ou zerar certos bits também é possível sem ter que ler e escrever os outros bits da porta. Os dois comandos são SBI (Set Bit I/o, setar bit E/S) e CBI (Clear Bit I/o, zerar bit E/S). A execução é assim: .EQU BitAtivo=0 ; O bit que será mudado SBI PortB, BitAtivo ; O bit será setado para um CBI PortB, BitAtivo ; O bit será setado para zero Estas duas instruções têm uma limitação: somente portas com endereço inferior a 0x20 podem ser manipuladas desta forma. Para programadores mais exóticos: as portas podem ser acessadas utilizando comandos de acesso à SRAM, como ST e LD. Apenas some 0x20 ao endereço da porta (os primeiros 32 endereços são os registradores) e acesse a porta desta forma. Vamos demonstrar aqui: .DEF MeuRegistradorPreferido = R LDI ZH,HIGH(PORTB+32) LDI ZL,LOW(PORTB+32)

LD MeuRegistradorPreferido,Z Isto faz sentido apenas em certos casos, mas é possível. É por esta razão que o primeiro endereço da SRAM é sempre 0x60.

Deatlhes de portas relevantes do AVR

A tabela a seguir mostra as portas mais usadas. Nem todas portas estão listadas aqui, algumas do MEGA e AT90S4434/8535 foram omitidas. Se houver dúvida, verifique as referências originais. Componente Nome da porta Registrador da Porta Acumulador SREG Registrador de Status Pilha ( stack) SPL/SPH Stackpointer (apontador de pilha) SRAM Externa/Interrupção Externa MCUCR Registrador de Controle Geral MCU Interrupção Externa GIMSK Registrador de Interrupção Mascarado GIFR Registrador de Flag de Interrupção Interrupção de Timer TIMSK Registrador de Interrupção de Timer Mascarada TIFR Registrador de Interrupção de Flag de Timer Timer 0 TCCR0 Registrador controle de de Timer/Contador 0 TCNT0 Timer/Contador 0 Timer 1 TCCR1A Registrador controle de de Timer/Contador 1 A TCCR1B Registrador controle de de Timer/Contador 1 B TCNT1 Timer/Contador 1 OCR1A Registrador Comparador de Saída 1 A OCR1B Registrador Comparador de Saída 1 B ICR1L/H Registrador de Captura de Entrada Timer Watchdog WDTCR Registrador de Controle do Timer Watchdog EEPROM EEAR Registrador de endereço da EEPROM EEDR Registrador de dados da EEPROM EECR Registrador de controle da EEPROM SPI SPCR Registrador de controle de periféricos Seriais SPSR Registrador de status de periféricos Seriais SPDR Registrador de dados de periféricos Seriais UART UDR Registrador de dados da UART USR Registrador de status da UART UCR Registrador de controle da UART UBRR Registrador de velocidade (baud rate) da UART Comparador analógico ACSR Registrador de status e controle do comparador analógico Portas de E/S PORTx Registrador de porta de saída DDRx Registrador de direção da porta PINx Registrador de porta de entrada

O registrador de status como a porta mais utilizada

De longe, a porta mais freqüentemente usada é o registrador de status com seus 8 bits. Normalmente o acesso a esta porta é feito somente por alteração dos bits pela CPU ou acumulador, alguns acessos são por leitura ou alteração dos bits na porta, e em raros casos é possível manipular estes bits diretamente (utilizando os comandos assembler SEx ou CLx, onde x é a abreviação do bit). A maioria destes bits é alterada por operações de teste de bit, comparação ou cálculos. A seguinte lista tem todos os comandos em assembler que podem alterar os bits de status, dependendo do resultado da execução.