SimulIDE


Grabar fichero *.HEX en Atmega328

mediante Arduino utilizando avrdude


En anteriores artículos de SimulIDE había realizado una serie de proyectos con el Atmega328.
Había utilizado para programar el ensamblador, C, y Basic.
En el simulador funcionaba perfectamente, pero a los electrónicos nos gusta probar los circuitos físicamente, el ver parpadear un LED físico nos alegra.
El fichero generado es un fichero con extensión  .HEX , que es el código máquina que se carga en el microcontrolador.
En este artículo explico como cargar este código en el Atmega328 mediante un arduino.

Hace unos años cuando empezaba a utilizar los microcontroladores Atmega*** realicé un artículo de como realizar grabadores PROGRAMADOR.
El mas utilizado al final fue el USBASP , se conectaba directamente al puerto USB.
El que quiera puede realizarlo, es fácil, y el que quiera puede comprarlo por internet, es bastante barato.

En este proyecto enseño como programar un microcontrolador tipo Atmega328 mediante un arduino nano, aunque sirve cualquier  arduino.
Para este proyecto he utilizado el entorno Arduino IDE 1.0.5 , es el que viene de serie en Linux Debian 10.

Lo primero es transformarlo en un grabador mediante un programa que viene de ejemplo llamado:  ArduinoISP.


Compilamos el programa y lo cargamos en nuestro arduino.

Conectamos nuestro arduino al Atmega328 que queramos programar, y añadir una serie de componentes.

Esquema eléctrico.


Gráfico de componentes.


Circuito montado.

Para esta demostración he elegido el parpadeo de un LED colocado en la patilla 9 del Atmega328, que corresponde al puerto de salida B1.

hola.c

/*

* blink

* Juan Galaz

* seta43.duckdns.org

* seta43.blogspot.com

* 2021

*/


#define F_CPU 16000000L


#include <avr/io.h>

#include <util/delay.h>



int main (void)

{

DDRB = 0xff;

PORTB = 0x03;


while(1)

{

PORTB = 0x03;

_delay_ms(400);

PORTB = 0x00;

_delay_ms(500);

}

return 0;

}


Makefile

MCU=atmega328

F_CPU=16000000

CC=avr-gcc

OBJCOPY=avr-objcopy

CFLAGS=-std=c99 -Wall -g -Os -mmcu=${MCU} -DF_CPU=${F_CPU} -I.

TARGET=hola

SRCS=hola.c

all:
 ${CC} ${CFLAGS} -o ${TARGET}.bin ${SRCS}

${OBJCOPY} -j .text -j .data -O ihex ${TARGET}.bin ${TARGET}.hex

flash:

avrdude -C/usr/share/arduino/hardware/tools/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -b19200 -Uflash:w:${TARGET}.hex:i

flash2:

avrdude -C/usr/share/arduino/hardware/tools/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -b19200 -U flash:w:${TARGET}.hex:i -U lfuse:w:0xff:m -U hfuse:w:0xd9:m -U efuse:w:0xff:m

clean:

rm -f *.bin *.hex


Podemos observar que he creado dos tipos de grabaciones, flash y flash2.
El flash no modifica los FUSES del Atmega328, si estamos seguros de como están los fuses utiliza esta opción.
El flash2 coloca los fuses para que funcione con el el crystal de cuarzo externo. Esta opción solo es necesaria la primera vez que programemos el Atmega328.
También hemos supuesto que el arduino se encuentra en: /dev/ttyUSB0 , debiís estar seguro que este es vuestro caso.
Después de haber compilado el programa con el simuIDE, pasamos a consola y nos colocamos en el directorio donde se encuentra el fichero hola.hex.
Ahora solo nos queda teclear make flash , o make flash2 dependiendo del caso.

Consola
make flash

avrdude -C/usr/share/arduino/hardware/tools/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -b19200 -Uflash:w:hola.hex:i
.....
....

Writing | ################################################## | 100% 0.31s

avrdude: 182 bytes of flash written
avrdude: verifying flash memory against hola.hex:
avrdude: load data flash data from input file hola.hex:
avrdude: input file hola.hex contains 182 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.20s

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

avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as FF
avrdude: safemode: Fuses OK (E:FF, H:D9, L:FF)

avrdude done.  Thank you.


Si todo fue bien veremos como comienza a parpadear el LED.

Como podemos observar para programar un ATmega328 mediante un arduino con la conexión ISP debemos unir pines entre dos ATmega328. Esto como podéis entender es altamente peligroso, un pin puede estar en estado alto y otro en estado bajo, esto puede generar una avería en alguno de los chip.
Para solucionar este tema he añadido resistencias de 330 ohmios en las líneas de comunicaciones ISP, con lo cual se soluciona este problema.
Para probar está modificación, he realizado un simple semáforo.


He comprobado que al programar con el programa arduinoISP , en la primera programación funciona bien, pero cuando se desconecta físicamente el arduino, y se vuelve a conectar nos daba error.
Solución:
Antes de mandar el fichero HEX , pulsar el botón reset en el arduino, y mientras está pulsado el reset mandar el programa a grabar.
Se suelta el reset, y vemos que se carga correctamente el programa en el ATmega328.
Este problema me ocurre en Linux, no he probado en Windows.


Espero que les guste esta serie de montajes.
Todos estos pasos se pueden ver bien en el vídeo demostrativo.

VIDEO DEMOSTRATIVO.

SOURCE

Saludos.
Juan Galaz