Fórum de Electrónica - projectos, cursos, tutoriais, compra e venda, etc. em electrónica
Este fórum migrou para aqui. Se quiser visitar o novo fórum, deverá clicar nesta frase.

Para serviços neste fórum use os botões em baixo.
Últimos assuntos
» Ajuda para mesa de mistura BEHRINGER Eurorack 2442Fx-Pro
Seg 27 Abr 2015 - 13:24 por Jose Manuel Borges

» Microchip MPLAB IDE - PIC16F84A
Sex 8 Ago 2014 - 19:29 por Electromonkeys

» Ajuda sobre curso de electronica
Seg 4 Ago 2014 - 13:57 por Nunes Pereira

» Procuro: Programdores em C, elaborar circuitos electrónicos. Trabalho remunerado
Qua 11 Jun 2014 - 14:07 por ricardo costa1986

» PORTA NOT
Dom 2 Mar 2014 - 13:40 por yoda

» Ajuda com Monitor Philips190tws
Qui 28 Nov 2013 - 1:28 por kagareu

» Estação de Retrabalho não derrete a solda
Sab 12 Out 2013 - 17:10 por itacipri

» Plataforma para cálculo de tempo de voo
Sab 27 Jul 2013 - 4:06 por diogofsousa92

» Prestação serviços projeto eletronica""
Sex 26 Jul 2013 - 15:24 por Mega_Migas

» l7812cv
Seg 15 Jul 2013 - 13:06 por boleiro

Quem está conectado
4 usuários online :: Nenhum usuário registrado, Nenhum Invisível e 4 Visitantes

Nenhum

[ Ver toda a lista ]


O recorde de usuários online foi de 66 em Qui 6 Jan 2011 - 0:00
Buscar
 
 

Resultados por:
 


Rechercher Busca avançada


AVR - Micro tutorial

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

AVR - Micro tutorial

Mensagem  joseflor em Sex 19 Jun 2009 - 11:13

Matéria publicada com autorização do autor Njay a quem eu fica muito grato.
Veja também o "blog do autor"
José Flor

Índice
Introdução
Ferramentas de Desenvolvimento
Hardware
Programador
Circuito de Teste
Teste ao hardware
Software

Introdução


"AVR" é o nome de uma família de microcontroladores de 8 bits comercializada pela ATMEL. A arquitectura do AVR foi desenvolvida por 2 estudantes de doutoramento noruegueses em 1992 e depois proposta à ATMEL para comercialização. Para quem souber inglês, podem ver uma pequeno video sobre os AVR aqui: http://www.avrtv.com/2007/09/09/avrtv-special-005/.
O AVR consiste, tal como um PIC e outros microcontroladores, num processador (o "core"), memórias voláteis e não-voláteis e periféricos. Ao contrário do PIC, o core do AVR foi muito bem pensado e implementado desde o inicio, e o core que é usado nos chips desenhados hoje é o mesmo que saiu no 1º AVR há mais de 10 anos (o PIC teve "dores de crescimento" e o tamanho das instruções aumentou algumas vezes ao longo do tempo de forma a suportar mais funcionalidade).

Assim de uma forma rápida podemos resumir a arquitectura do AVR nos seguintes pontos:


  • Consiste num core de processamento, memória de programa (não volátil, FLASH), memória volátil (RAM estática, SRAM), memória de dados persistentes (não volátil, EEPROM) e bits fuse/lock (permitem configurar alguns parametros especiais do AVR).
  • Arquitectura de memória Harvard (memória de programa e memória de dados separadas)
  • A memória volátil (SRAM) é contínua
  • A maior parte das instruções têm 16 bits de tamanho, e é este o tamanho de cada palavra na memória de programa (FLASH).
  • Execução de 1 instrução por ciclo de relógio para a maior parte das instruções.
  • Existem 32 registos de 8 bits disponiveis e há poucas limitações ao que se pode fazer com cada um.
  • Os registos do processador e os de configuração dos periféricos estão mapeados (são acessiveis) na SRAM.
  • Existe um vector de interrupção diferente por cada fonte de interrupção.
  • Existem instruções com modos de endereçamento complexo, como base + deslocamento seguido de auto-incremento/decremento do endereço.
  • O conjunto de instruções foi pensado para melhorar a conversão de código C em assembly.


Para facilitar a vida a todos, a mim e a voccês, vou centrar o tutorial apenas num modelo específico de AVR, o ATtiny26, e em programação C, já que o assembly é muito hardcore para uma introdução. Mais tarde não será difícil extender o descrito neste tutorial para mais 1 ou 2 modelos de AVR sem grandes alterações. Este ATtiny26 apesar de ser pequeno não é dos modelos mais básicos, e na minha opinião consegue um excelente equilibrio preço/funcionalidade; tem ADC, contadores/timers, hardware que facilita a construção de interfaces SPI/I2C/UART, velocidade de relógio até 16MHz (um PIC para ter a mesma velocidade precisava de ter um clock de 64MHz), entre outras coisas.


Ferramentas de desenvolvimento


Vamos precisar das seguintes ferramentas, todas software de utilização livre:


  • AVRStudio 4.13 (73MB) - Ambiente de desenvolvimento gratuito da ATMEL para toda a linha AVR. Consiste num editor, assembler, programador e simulador. Vamos usá-lo como simulador.
  • WinAVR (23MB) - Ambiente de desenvolvimento OpenSource para AVRs. Consiste num editor, compilador C/C++, linker, debugger, simulador e programador. Vamos usar apenas as aplicações para compilação de C e o programador.


Se a tua ligação à Internet for lenta, podes deixar o download do AVRStudio para mais tarde, eu digo-te quando na altura (na verdade ele não é essencial para desenvolver programas para AVR, mas ajuda imeeeeenso).

Após a instalação do WinAVR, vamos ter que adicionar uma descrição do nosso hardware programador ao ficheiro de configuração do avrdude, que é a aplicação do WinAVR que trata da programação dos AVRs. Portanto abram o ficheiro \WinAVR\bin\avrdude.conf e procurem pelo comentário de texto

# Parallel port programmers.

Este comentário marca o inicio da zona de configuração de programadores de porta paralela, e logo aí vamos inserir a descrição do (hardware) programador que vamos usar e que está descrito na próxima secção:



# AVR Tutorial programmer at www.electronicapt.com
programmer
id = "avrpt";
desc = "AVR Tutorial at ElectronicaPt.com";
type = par;
reset = 6;
sck = 8;
mosi = 7;
miso = 10;
;




O avrdude é um programa muito flexível e não se limita a aceitar apenas um ou alguns tipos de programadores; ele lê do ficheiro avrdude.conf a configuração de programadores e usa-a para utilizar o programador de hardware que estejamos a usar. Assim podemos utilizar muitos tipos diferentes de programadores sem ter que alterar o código do avrdude; inteligente, não ;)? E ele faz o mesmo para os AVRs. Cada AVR tem memórias de tamanhos diferentes e toda essa informação está no ficheiro de configuração. Mas não é preciso mexer em mais nada :).

O programador de AVRs que vamos usar é de ligar à porta paralela do PC, o que quer dizer que o teu PC terá que ter uma LPT. Existem uns conversores de USB para LPT, mas normalmente não funcionam, tem que ser uma porta LPT "pura". Também terás que ter direitos de administração no teu PC para instalar um driver de porta paralela.

Agora vamos tratar do hardware.


Hardware



Programador
Precisamos de ter um circuito programador para gravar os nossos programas no AVR. O AVR tem 2 modos de programação: o paralelo/alta voltagem e o série/baixa voltagem. Estes modos permitem ler e escrever nas suas memórias não voláteis e nos bits fuse/lock. O circuito abaixo é um programador de modo série, que vamos utilizar.



Este circuito tem que ser montado dentro da caixa da ficha que liga à porta paralela do PC, e é essencial que fique ali mesmo à saída da porta paralela (mais perto do que dentro da ficha que lá liga, impossível):




(do outro lado)



Circuito de Teste
Vamos montar numa matriz de contactos o circuito abaixo. Este pode ser alimentado por qualquer tensão entre 4.5V e 5.5V, tipicamente 5V. No entanto a maior parte destes AVR funciona com tensões a partir de 3V, pelo que, para a nossa pequena introdução e com o AVR a baixa velocidade de relógio (1MHz), pode ser usado um par de pilhas AA ou AAA de 1.5V ou uma pilha de lítio tipo "botão" de 3V. Isto facilita para quem não tem uma fonte de 5V. Se o circuito não funcionar (se por exemplo apresentar erros de verificação da programação), então deve-se usar uma tensão maior, por exemplo 3 pilhas AA ou AAA em série.



Nesta placa temos apenas 1 LED como dispositivo externo sobre o qual o AVR pode actuar, mas depois deste tutorial vocês irão certamente ser criativos e ligar muitas outras coisas :).
Vou usar um suporte de 2 pilhas AA de 1.5V para alimentar o circuito:



[size=7](clicar para ver em detalhe)


(clicar para ver em detalhe)


Se já tentaste enfiar uma ponte de terminais (as peças dos pinos dourados) numa matriz de contactos, reparaste que eles não prendem lá, porque são demasiado curtos. Para resolver isso pega num alicate e empurra devagar os pinos 1 ou 2mm, usando a base de plástico como apoio para uma das pontas do alicate, assim:



Agora já se conseguem prender as pontes à matriz.

Eu usei pontes de terminais, mas também poderia ter usado fichas macho do tipo das brancas do programador e do suporte de pilhas que podes ver nas fotos. Esses até são um pouco melhores, porque são polarizados, isto é, só permitem que ligues as fichas numa das 2 posições possíveis, o que é importante (especialmente a fichas das pilhas!). Essas fichas são baratas e encontram-se com facilidade cá em Portugal.


Teste ao hardware
Bom, antes de começarmos a fazer programas para o AVR, temos que verificar se o hardware (programador e circuito de teste) estão a funcionar. E vamos fazê-lo verificando se o software programador, o avrdude, é capaz de falar com o nosso AVR.

Para começar tens que instalar um driver no teu PC que irá permitir ao avrdude ter acesso à porta paralela. Para isso vai ao menu Iniciar do Windows e escolhe Executar; aí dá o comando

runas /user:administrador cmd

administrador é o nome de um utilizador no teu PC que tenha direitos de administração, e este comando abre uma Linha de Comando onde os comandos que deres se executarão como se fosses esse utilizador. Se o utilizador que usas habitualmente já tem direitos de administração, então basta-te abrir uma Linha de Comando directamente.
Na Linha de Comando então aberta, vai para a directoria ...\WinAVR\bin\ e corre o ficheiro install_giveio.bat para instalar o driver, como no exemplo:



Verifica se a instalação correu bem, deves ver as mesmas mensagens que na imagem acima. Em princípio só deves precisar de fazer isto uma vez, pois o driver fica instalado como serviço do Windows, de arranque automático. Já podes fechar a Linha de Comando e abrir uma nova, desta vez normal (Iniciar -> Executar -> escrever "cmd" e ENTER). Cria uma directoria de trabalho para este tutorial, por exemplo c:\tutorial e muda-te (cd ...) para lá.

Liga o programador à porta paralela e ao circuito de teste.


(clicar para ver em detalhe)


Tem atenção à posição da ficha branca. Depois liga as pilhas ao circuito de teste e vamos verificar se o avrdude consegue "falar" com o nosso AVR, dando mais um comando:



C:\tutorial> avrdude -c avrpt -p t26 -i 50

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9109

avrdude: safemode: Fuses OK

avrdude done. Thank you.

C:\tutorial>




O texto a laranja (ele não aparece laranja, fui eu que o pintei!) é uma boa indicação de que a conversa foi bem sucedida, uma vez que o avrdude conseguiu ler a assinatura do AVR, que é um código que identifica o modelo de AVR. Se houver mensagens de erro vais perceber... e aí tens que verificar se o cabo está bem montado, bem ligado, o circuito bem montado, se ligaste as pilhas, etc. Enquanto não vires a assinatura do AVR neste pequeno teste, não vais conseguir programá-lo.

Com o hardware a funcionar, vamos então começar a olhar para o software.


Software



Se tiveste a coragem de chegar a este ponto, estás (se não estás, devias estar :)) em pulgas para programar o teu 1º AVR :). Vamos primeiro ver como é que se compila e grava um programa no AVR, e só depois vamos à explicação dos detalhes.

Vamos fazer o programa que é o sonho de qualquer iniciante ;), pôr um LED a piscar. Copia o seguinte para um ficheiro e grava-o com o nome pisca_led.c[].

Código:

#include <avr/io.h>
#include <util/delay.h>

int main (void)
{
    DDRA = 0x01;    // Configurar pino PA0 como output

    do {  // inicio de ciclo
        PORTA = 0x01;      // Acender o LED
        _delay_ms(250);    // Esperar 250ms...
        PORTA = 0x00;      // Apagar o LED
        _delay_ms(250);    // Esperar 250ms...
    }
    while (1);      // Saltar para o inicio do ciclo
}

E para compilar este programa vamos dar os comandos:



C:\tutorial> avr-gcc -mmcu=attiny26 -DF_CPU=1000000UL -g -O1 -o pisca_led.elf pisca_led.c

C:\tutorial> avr-objcopy -j .text -j .data -O binary pisca_led.elf pisca_led.bin

C:\tutorial>[/font]



Finalmente, para programar o AVR damos agora o último comando e observamos, com espanto :), o AVR ser programado:



C:\tutorial> avrdude -c avrpt -p t26 -i 50 -U flash:w:pisca_led.bin:r

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9109
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "pisca_led.bin"
avrdude: writing flash (108 bytes):

Writing | ################################################## | 100% 0.38s

avrdude: 108 bytes of flash written
avrdude: verifying flash memory against pisca_led.bin:
avrdude: load data flash data from input file pisca_led.bin:
avrdude: input file pisca_led.bin contains 108 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.35s

avrdude: verifying ...
avrdude: 108 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done. Thank you.

C:\tutorial>[/font]



Assim que termina a execução deste comando, e se for bem sucedido tal como no exemplo acima, terás diante dos teus olhos um LED a piscar :). Parabéns :)!!!
avatar
joseflor
Nível 3
Nível 3

Mensagens : 273
Pontos : 3448
Reputação : 7
Data de inscrição : 08/11/2008
Idade : 53
Localização : Mangerton, NSW, Austrália

Ver perfil do usuário http://www.ozflor.com/eletrokit/

Voltar ao Topo Ir em baixo

Re: AVR - Micro tutorial

Mensagem  joseflor em Dom 28 Jun 2009 - 10:13

Neste novo micro-artigo, a juntar ao micro-tutorial, vou falar-vos de GPIOs - General Purpose Input/Output (entrada/saída de uso geral). Quando estiver completo vou juntar ao 1º post, mas assim podem ir já comentando e eu posso ir melhorando enquanto não termino.
Vou tentar explicar-vos de uma forma genérica o que é e como se usa um GPIO, pois um GPIO é um conceito, e que se encontra em todos os microcontroladores e SoC que vos poderão passar pelas mãos. Quem entender o conceito, consegue pegar num novo tipo de microcontrolador e rapidamente percebe como é que se usam os seus pinos para as funções mais básicas. No final do artigo vou então explicar como se fazem estas configurações num AVR.

Neste artigo traduzo os termos para Português mas vou usar os termos em inglês, pois é o que vocês vão ver normalmente. Basta pensar que as datasheets estão sempre em inglês.

Então comecemos...

GPIO - General Purpose Input/Output

O conceito de GPIO surge como uma forma de se tornar um chip mais flexível, e deve ter surgido com os chips programáveis. Este conceito consiste em podermos configurar um pino de um chip para poder ter uma de entre várias funções, como por exemplo uma entrada ou uma saída. Isto tem vantagens óbvias na flexibilidade de um chip, pois o fabricante dá-vos um chip com N pinos em que vocês escolhem a função de cada um conforme as necessidades da vossa aplicação. Se a função de cada pino fosse sempre fixa, os chips seriam muito menos úteis, e provavelmente teriamos chips maiores, com muito mais pinos, numa tentativa de colmatar essa limitação, e não poderiamos alterar a função do pino durante o funcionamento do chip.

A função de base que podemos escolher para um GPIO é se o pino é uma entrada ou saída, mas não é a única. Existem outras funções que podem ser escolhidas, embora nem todos os chips suportem todas. As funções possíveis mais comuns são:




Normalmente dizemos apenas "GPIO" quando nos estamos a referir a um "pino GPIO" e eu assim farei daqui para a frente. Vamos ver com mais detalhe cada função, a que às vezes também chamamos "tipo de pino".

Entrada digital normal

Esta é talvez a configuração mais simples que podemos ter. O pino funciona como uma entrada digital, ou seja, só podemos ler (em software) um de 2 valores: 0 ou 1. Na prática os valores 0 e 1 representam uma certa tensão que é aplicada ao pino, resultando numa leitura de 0 ou 1 por parte do software. As tensões mais comuns são 0V para representar um 0 e 5V para representar um 1, mas podem ser outras como por exemplo 3.3V ou 1.8V para representar um 1, dependendo da tensão de alimentação do chip (refiro apenas "chip" porque não são apenas os microcontroladores que têm GPIOs; por exemplo as FPGA, outro tipo de chip programável, também têm).

Portanto, num sistema que funcione com uma tensão de alimentação de 5V, se aplicarmos 5V a um pino configurado como "entrada digital normal", o software irá ler um valor 1 desse pino. Se aplicarmos 0V, o software irá ler um 0. A leitura do "estado do pino" é habitualmente efectuada lendo-se um registo do chip. Falaremos mais sobre isto no final.

Configurar um GPIO como entrada digital normal também serve como forma de desligar o pino do circuito. Neste caso não estamos interessados em ler valores. Ao configurá-lo como entrada, ele não afecta electricamente (de um ponto de vista digital) o circuito exterior ao chip e portanto é como se tivessemos cortado o pino do chip. Diz-se que o pino está em "alta impedancia" ("high-Z" em inglês, pois o "Z" é muito usado para designar "impedancia"), "no ar", ou simplesmente "desligado do circuito".

Normalmente dizemos apenas que um pino está "configurado como entrada" ou como input.

Entrada com pull-up ("puxa para cima")

Então se tivermos um pino configurado como input mas não lhe aplicarmos nenhuma tensão, que valor lemos no software?... A resposta é: não podemos prever. Tomem bem atenção a isto, vou repetir: não podemos prever. Quando temos uma entrada que está no ar, não podemos prever que valor vamos ler; o valor pode estar estável em 0 ou 1 ou pode estar sempre a variar, ou mudar de vez em quando consoante é dia ou noite ou Marte está alinhado com Júpiter ou o vizinho deitar-se 2 minutos mais cedo ou mais tarde. Ele pode até mudar só de lhe tocarem com o dedo.

Em algumas situações queremos ter sempre um valor estável na entrada. Um caso tipico é um interruptor (que pode ser um botão). Conectamos o interruptor entre a massa (o negativo da tensão de alimentação, "0V") e o pino. Aí, quando ligamos o interruptor (posição "ON"), o pino fica ligado aos 0V e portanto o chip lê um 0. Mas, e quando o interruptor está desligado? Aí o pino está no ar pois o interruptor desligado é um circuito aberto, e já sabemos que ler um input que está no ar dá-nos um valor aleatório e portanto nunca vamos saber se o interruptor está mesmo ON ou OFF. É aqui que o pull-up entra; ao configurarmos o pino com pull-up, o chip liga internamente uma resistência entre o pino e a tensão de alimentação, e portanto, quando não há nada electricamente ligado ao pino, o pino "vê" um 1. No caso do interruptor, quando este está OFF, o pull-up coloca um 1 estável à entrada do pino e fica resolvido o problema. Quando o interruptor está ON, o próprio interruptor força um 0 no pino, ligando-o à massa.

Então mas... se o pull-up puxa o pino "para cima" e o interruptor (quando está ON) puxa para baixo, não há aqui uma espécie de conflito? Não há, por uma simples razão: o valor da resistência de pull-up é alto (tipicamente mais de 100 KOhms) e portanto tem "pouca força". Como o interruptor liga o pino directamente à massa, é esta que "ganha". Diz-se até que o pull-up é um "pull-up fraco", ou "weak pull-up" em inglês.

Esta expressão pull-up ("puxa para cima") vem de estarmos a ligar à tensão de alimentação positiva, que é mais "alta" do que a massa, os 0V. Para este termo contribui ainda o facto de geralmente se desenhar a linha de alimentação positiva no topo dos esquemas, e a massa em baixo. Também podemos falar em pull-down ("puxa para baixo") quando nos referimos a ligar à massa. Podemos criar pull-downs ligando resistências à massa, mas tipicamente os chips não suportam este tipo de pull, por razões que fogem ao âmbito deste artigo que se quer simples.

Entrada controlada por um periférico

Neste caso deixamos de ter controlo sobre o GPIO, passando esse controle para um periférico interno do chip. Por exemplo a linha Rx (receive) de uma porta série (UART). Aqui o pino funciona como uma entrada mas quem a controla é o periférico.

Saída digital normal

_________________
Happy soldering!
José Flor - OzFlor
Venda de componentes de electrónica
Loja EBR (Eletrônica BRasil)
Fórum oficial de electrónica de José Flor - OzFlor
avatar
joseflor
Nível 3
Nível 3

Mensagens : 273
Pontos : 3448
Reputação : 7
Data de inscrição : 08/11/2008
Idade : 53
Localização : Mangerton, NSW, Austrália

Ver perfil do usuário http://www.ozflor.com/eletrokit/

Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo

- Tópicos similares

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum