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:
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:
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:
E a referência dos 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:
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:
É 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:
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:
- MCLR/Vpp – Pino ligado ao MCLR do microcontrolador no modo “high-voltage”.
- Vdd – Alimentação positiva.
- Vss – Alimentação negativa.
- PGD – Deve ser ligado no pino PGD do microcontrolador.
- PGC – Deve ser ligado no pino PGC do microcontrolador.
- PGM/ LVP – Utilizado para a programação “low-voltage”.
Com base, nisto, vejamos a ligação típica com o microcontrolador:
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:
Com isto, a seguinte janela aparecerá:
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:
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:
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.
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 uma aula extra com algumas dicas úteis de plataformas para te ajudar a aprender sobre o PIC ou o AVR.
Simulador de microcontrolador e plataformas úteis – Aula 5.1 – MC
Fuses e bits de configuração – Aula 6 – MC
Bom dia.
Preciso ler o conteúdo de um ATTINY13A para fazer uma modificação no código e regravar em um outro ATTINY13A e o problema é que tenho que ler diretamente no CI pois não tenho mais acesso ao programa original.
Boa tarde, Jair. Uma vez já precisei fazer o mesmo que você. O problema é que o código dentro do ATTINY está no formato das instruções que o processador aceita. Para conseguir obter e modificar o código, você vai precisar converter o arquivo que você extrair do ATTINY (acho que é um .hex) em um arquivo assembly. Existem programas para fazer essa conversão. Dê uma olhada neste link, pois parece ter um programa para isso.
Tem como ler o programa de um chip controlador e alterá-lo via arduino conforme mostra no texto da matéria. Estou ensinando meu filho a programar e queria saber se é possível alterar alguns brinquedos dele.
Olá, Misael. Infelizmente não é possível fazer isso diretamente, pois o código dentro do chip está no formato das instruções que o processador aceita (um conjunto de 0s e 1s) e não no formato do código do Arduino. Caso você consiga ler o código dentro do chip (seguindo o que escrevi no comentário do Jair Medeiros), é preciso muito conhecimento e paciência para modificar o código, mesmo que em uma questão pontual. O pior é que muitos fabricantes bloqueiam a leitura do chip, impedindo que você obtenha o código. O que alguns profissionais preferem fazer é recriar o código de um determinado produto do 0. Enfim, recomendo você direcionar seu filho a aprender pouco a pouco com projetos mais simples, que uma hora ele vai ter aprendido o suficiente pra ser capaz de criar o código de um brinquedo do 0. Parabéns por incentivar seu filho nos estudos e sucesso pra vocês!
Olá! sou o Andre e gostaria de saber se consigo copiar a leitura do mc908qy4a? eu tenho um que esta funcionando mas preciso de mais para essa leitura, sera que vc consegue me ajudar?
Olá, Andre. O que você quer dizer com leitura? Seria copiar o assembly do código que está rodando no microcontrolador?
Boa tarde, achei bem interessante suas explicações, estou precisando ler e gravar num MC9S12XDP512, principalmente gravar um programa já salvo, mas não estou conseguindo, comprei varios programadores e nada!!
OBS- Se vocês puderem me ajudar, por favor entre em contato comigo pelo email valdiradc18@gmail.com
Olá, Valdir. Como demorei a responder, imagino que você já deva ter resolvido seu problema. Infelizmente tô bem sem tempo.