Nesta aula, aprenderemos o básico sobre o processo de gravar o código na memória flash do microcontrolador.

Na aula anterior, aprendemos sobre a diferença entre firmware, software e hardware e começamos a mexer nas IDEs do AVR e do PIC.

Informações básicas

Pretendo mostrar o que precisa ser feito para gravar um código dentro da memória flash do microcontrolador (AVR e PIC). Isto é, como transferir um código que foi desenvolvido em um computador para a memória de programa do microcontrolador.

Este pode ser um processo bastante complicado de entender a fundo, mas existem uns dispositivos chamados de “programadores” ou “gravadores” que tornam o procedimento bem fácil de ser feito.

AVR

Modos de gravar o código

O AVR possui 2 principais modos de programação. O primeiro deles é chamado de “Programação Paralela”. Ele recebe este nome, porque são necessários diversos pinos do microcontrolador para fazer a escrita/leitura do programa na memória flash. Veja abaixo a programação paralela no ATmega328p:

Ligação da programação paralela
Fonte: Datasheet do ATmega328p

Caso você tenha interesse em aprender sobre o funcionamento da programação paralela, veja a página 296 do datasheet do ATmega328p.

Por outro lado, o tipo mais comum de programação é a “Programação Serial”. Nela, os sinais utilizados podem ser de baixa tensão (< 5V) e a interface de programação é a SPI. Por conta disto, são necessários apenas 4 pinos além da alimentação. Veja baixo a ligação da programação serial:

Caso você tenha interesse em aprender sobre o funcionamento da programação serial, veja a página 303 do datasheet do ATmega328p.

Existe ainda uma terceira forma de programar o AVR, que é por meio do bootloader. Conforme foi comentado na aula anterior, é possível colocar um código que roda na inicialização do microcontrolador que fica aguardando comandos seriais em dois pinos. Com isto, ele programa a memória flash a partir destes comandos recebidos.

É assim que a programação do Arduino UNO funciona: na inicialização ele aguarda “comandos de programação” nos pinos 0 e 1 (RX e TX). Se nada for recebido, o Arduino segue para o código principal.

AVR USBasp

O que é

Esta forma de programar o AVR é bem tranquila e relativamente barata. O “USBasp” é um dispositivo programador serial com uma interface SPI. Ele está mostrado na imagem abaixo:

Gravador USBasp

Como pode ser visto acima, ele possui um conector USB para ligar no computador e um conector IDC para ligar nos pinos do microcontrolador. Se você reparar bem, vai ver que existe um microcontrolador na placa do USBasp (um ATmega8A no meu caso). Isso, porque o microcontrolador é utilizado para criar a interface SPI da gravação.

Aqui pode entrar um questionamento interessante: como se gravou o microcontrolador utilizado para gravar outros microcontroladores? Não tenho certeza da resposta, mas podem ter utilizado um circuito digital específico para isso. E uma vez gravado o primeiro microcontrolador, ele foi usado para gravar os demais.

Enfim, agora vou explicar como usar o USBasp para gravar um ATtiny13A, mas o procedimento é aplicável a outros microcontroladores.

Circuito

O USBasp possui 10 pinos, mas só vamos usar 6 para gravação: 4 da SPI e 2 de alimentação. Veja a ligação abaixo:

Ligação do USBasp

E a referência dos pinos do conector IDC:

Pinos do conector IDC

Independente do microcontrolador que você esteja utilizando, é importante ligar os pinos do gravador nos pinos correspondentes do microcontrolador (MOSI no MOSI, MISO no MISO, Vcc no Vcc e assim por diante…). Portanto, é preciso conferir o datasheet do microcontrolador para ligar os pinos corretamente.

Instalando drivers do USBasp

Pode ser que o USBasp não funcione corretamente na hora de programar. Se isto acontecer, instalar um driver talvez resolva o problema. No caso, o driver que instalei aqui foi o libusb-win32.

Baixe o arquivo zip, descompacte, abra a pasta bin e execute o arquivo ‘inf-wizard.exe’. Ao termino da execução, ele irá indicar que ele criou um instalador do driver e perguntará se você deseja instalá-lo. Aceite e instale o driver. Por fim, talvez seja necessário ir em “Gerenciador de dispositivos”, localizar o USBasp e alterar o driver dele manualmente para o novo driver instalado.

Ou então, você pode seguir este tutorial para instalar o driver de forma mais fácil.

Criando projeto e código

O primeiro passo é criar um novo projeto no Atmel Studio assim como foi mostrado na aula 4.1.1. Em seguida, usaremos o código abaixo para testar o procedimento de gravação. Não se preocupe em entendê-lo por enquanto, apenas saiba que ele é um código para comutar o estado do pino PB4 a cada 1 segundo. Se você ligar um LED nele, o LED ficará piscando.

Vale dizer que está faltando um parâmetro importante no código (“F_CPU”) que acaba atrapalhando a precisão do delay. Porém é só um teste e não precisamos nos preocupar com isto por enquanto.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    // Define pino PB4 como saída
    DDRB = 1 << DDB4;
   
    while (1)
    {
        // Comuta o estado do pino PB4
        PORTB ^= (1 << PORTB4);
        _delay_ms(1000);
    }
}

Depois de colar o código no seu ‘main.c’, compile ele apertando F7 ou indo em ‘Build’.

Como gravar o código

É possível gravar o código dentro do próprio Atmel Studio, mas o procedimento é um pouco chatinho e limitado. Caso tenha interesse de ver como fazer isto, veja este site. Ao invés disto, eu prefiro utilizar um programa à parte chamado AVRDUDESS. Portanto, baixe ele para seguir os passos adiante.

Assim que ele é aberto a seguinte tela aparece:

Configuração do AVRDudess

A partir da imagem acima, faça as seguintes mudanças:

1 – Mude o “Programmer” para o USBasp.

2 – Mude o MCU para microcontrolador que você deseja programar.

3 – Certifique que “Port” esteja configurado como “usb”.

4 – Caso desejar, você pode mandar detectar o microcontrolador para ver se o gravador está funcionando certinho.

5 – Escolha o arquivo do código que você deseja colocar no microcontrolador. Depois que você compila o código, ele gera um arquivo ‘.hex’ no diretório do projeto e é este arquivo que você precisa escolher.

Sendo mais específico, dentro do diretório do projeto, o arquivo ‘.hex’ fica localizado em “NomeDoProjeto/Debug/NomeDoProjeto.hex”.

6 – Após realizar as etapas anteriores, você pode finalmente programar o microcontrolador. E quando isto for feito, aparecerá uma mensagem na região logo abaixo do botão “Program” (no retângulo preto).

Arduino UNO

Arduino UNO como gravador

O Arduino UNO pode ser uma boa ferramenta para programar os microcontroladores. Não pretendo entrar em detalhes sobre este procedimento, mas aqui no site tem um post que mostra como gravar um ATtiny85 utilizando o UNO.

E tem um outro post que mostra como programar um ATmega328p utilizando o UNO também.

Gravar o Arduino UNO

Utilizar o Arduino UNO para aprender a programação ‘baixo nível’ é uma ótima ideia, pois a placa é feita justamente para testar e aprender. Portanto, eu utilizarei o Arduino UNO como base para fazer as próximas aulas.

E para gravar um código nele, o procedimento é quase igual ao que foi mostrado no USBasp. Isto é, você pode utilizar o AVRDUDESS para fazer a programação. A diferença está em algumas configurações:

Gravar Arduino UNO pelo AVRDudess

É preciso fazer duas configurações importantes, conforme a imagem acima mostra:

1 – Selecionar “Arduino” em “Programmer”.

2 – Selecionar, em “Port”, a porta COM a qual o Arduino está ligado.

Com isto, você pode programar o Arduino da mesma forma que foi mostrado anteriormente.

Outros

Este documento contém alguns detalhes sobre a programação dos microcontroladores AVR incluindo um circuito ‘baixo-custo’ de gravação que utiliza a porta serial do computador (dos computadores que ainda tem uma). O circuito está mostrado na página 12.

PIC

Modos de programação

O PIC (8 bits) possui uma interface serial de 2 pinos para fazer a programação do microcontrolador. Além dos dois pinos, utiliza-se também o MCLR (pino de reset) para controle do início da comunicação no modo “high-voltage”. No modo “low-voltage” o MCLR fica constante em nível alto.

Para mais detalhes, você pode ler alguns documentos da Microchip que tratam sobre isto: documento 1 e documento 2.

PICkit

O que é

Esta é uma das principais formas de programar o PIC, embora não seja muito barata. O PICkit é um dispositivo de programação que atualmente está na versão 3 (PICkit 3). Veja a foto dele abaixo:

Fonte: Microchip

Embora não seja possível ver na imagem, o PICkit 3 possui uma entrada mini USB para que ele seja ligado no computador. E, para ligar os pinos do microcontrolador, ele possui uma barra de pinos com 6 conexões que será melhor explicada no tópico adiante.

No circuito do PICkit, existe um PIC responsável por fazer a lógica da gravação. Então, aqui pode entrar um questionamento interessante: como se gravou o microcontrolador utilizado para gravar outros microcontroladores? Não tenho certeza da resposta, mas podem ter utilizado um circuito digital específico para isso. E uma vez gravado o primeiro microcontrolador, ele foi usado para gravar os demais.

Enfim, agora vou explicar como usar o PICkit para gravar um PIC genérico no modo “high-voltage”.

Circuito

Conforme dito, o PICkit possui 6 pinos: 2 de alimentação e 4 para programação. Sendo mais específico:

  1. MCLR/Vpp – Pino ligado ao MCLR do microcontrolador no modo “high-voltage”.
  2. Vdd – Alimentação positiva.
  3. Vss – Alimentação negativa.
  4. PGD – Deve ser ligado no pino PGD do microcontrolador.
  5. PGC – Deve ser ligado no pino PGC do microcontrolador.
  6. PGM/ LVP – Utilizado para a programação “low-voltage”.

Com base, nisto, vejamos a ligação típica com o microcontrolador:

Ligação do PICkit
Fonte: Microchip

O resistor de 4.7-10k não é mandatório e pode ser ignorado. Entretanto, o restante da ligação deve ser obedecida. Para encontrar qual é o pino “PGC” e o “PGD” do microcontrolador que você está programando, é preciso dar uma olhada no datasheet dele.

Enfim, muitas vezes é recomendado utilizar uma alimentação externa (Vdd) para evitar danos ao PICkit. Mas, se você está apenas ligando o microcontrolador sozinho, não tem problemas.

Criando projeto e código

O primeiro passo depois da ligação é criar um novo projeto no MPLAB X assim como foi mostrado na aula 4.1.2. Em seguida, usaremos o código abaixo para testar o procedimento de gravação. Não se preocupe em entendê-lo por enquanto, apenas saiba que ele é um código para comutar o estado do pino PA2 a cada 1 segundo. Se você ligar um LED nele, o LED ficará piscando.

Vale dizer que o delay pode ficar com o tempo errado se o clock do seu microcontrolador for diferente de 8MHz, mas isso é preocupação para as aulas futuras.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define _XTAL_FREQ  8000000

#include <xc.h>

void main(void)
{
    // Define pino A2 como saída
    TRISAbits.TRISA2 = 0;
   
    for(;;)
    {
        // Comuta o estado do pino A2
        PORTAbits.RA2 = !PORTAbits.RA2;
        __delay_ms(1000);
    }
   
    return;
}

Depois de colar o código no seu ‘main.c’, compile ele apertando F11 ou clicando no ‘martelo’.

Configurando PICkit

Antes de poder gravar o código, é preciso configurar o PICkit. Para isso, você precisa clicar no símbolo da chave de boca que fica na parte inferior esquerda da IDE. Veja abaixo:

Botão para entrar na tela de configurar programador

Com isto, a seguinte janela aparecerá:

Tela de configurar programador

Nesta janela, é preciso escolher o PICkit3 na parte de “Hardware Tool” e clicar em aplicar. Se você estiver com o PICkit conectado ao computador, abaixo do escrito “PICkit3” aparecerá o número de série (“SN: …”) do seu PICkit e é só você escolher ele e aplicar.

Em seguida, aparecerá na parte esquerda desta janela a opção “PICkit 3” embaixo de “Conf: [default]”. Clique nesta opção e depois em “Option categories” escolha “Power” para aparecer a seguinte tela:

Tela de configurar o PICkit

Nesta nova tela, você precisa habilitar o “Power target circuit from PICkit3” se você não estiver utilizando uma fonte de alimentação externa para o microcontrolador. Além disto, é preciso configurar o nível de tensão adequado (“Voltage level”). Após finalizar os ajustes, clique em “Apply” e depois em “OK”.

Como gravar o código

Para gravar o código é bem simples e direto uma vez que os passos anteriores foram concluídos sem problemas. Basta clicar no botão de ‘programar’ que fica ao lado direito do botão de “play” verde. E então é só aguardar que o código será gravado.

Programador "caseiro"

O que é

Na época que eu comecei a aprender sobre o PIC, eu não queria gastar muito e evitei de comprar um programador. Mas, para resolver o problema, resolvi fazer um circuitinho caseiro para programar o PIC por meio da porta serial do meu computador. Com isto, achei o seguinte circuito:

É claro que este circuito fica limitado a alguns PICs, mas como eu só tinha um PIC16F628A, ele me atendeu muito bem. E eu cheguei a montar ele numa placa ilhada, que pode ser vista na imagem abaixo:

Gravador de PIC caseiro

Gravação do código

Para gravar o código neste método eu utilizei um programa chamado PICPgm. O programa possui autodetecção do programador e do PIC, então fica fácil utilizá-lo. Veja abaixo a interface dele.

Fonte: PICPgm

Outros

Existe outro gravador chamado K150, que também é comum. Mas eu não pretendo comentar sobre ele, até porque o preço dele é próximo do PICkit e o PICkit já atende bem o propósito de gravação.

Observações finais

O objetivo desta aula foi mostrar como fazer a programação dos microcontroladores para que, nas próximas aulas, possamos apenas nos preocupar com os códigos.

A aula seguinte será sobre os fuses, configurações importantes dos microcontroladores. Mas a aula 5 possui [sairá em breve] uma aula extra com algumas dicas úteis de plataformas para te ajudar a aprender sobre o PIC ou o AVR.