Pour compléter le tuto sur Comment programmer un microcontrôleur ATmega328P avec une carte Arduino, publié récemment, je vous propose de découvrir aujourd’hui un exemple de « carte-support de programmation » (pour ATmega328P au format DIP, 28 broches). Le tout étant ici de pouvoir programmer ce microcontrôleur rapidement, et ce, sans avoir à sortir la breadboard, les fils duponts, et les composants nécessaires à cela (évitant au passage les risques d’erreur de câblage … !).
Le circuit imprimé de ce projet sera au format « Shield pour Arduino Uno » (c’est à dire pouvant s’embrocher dessus), et permettra le gravage de bootloader et/ou de programmes arduino, sur microcontrôleur ATmega328P. Dit autrement, il s’agit en fait d’une « extension arduino fait-maison », créée pour faciliter la programmation de microcontrôleurs AT mega 328P 😉
Remarque : ce projet se veut tout aussi ludique, que pratique. Car il est certes fait pour apprendre (comment créer un shield arduino, comment programmer un microcontrôleur ATmega328P facilement, …), mais pourra également vous servir « au quotidien ». D’ailleurs, perso, je m’en sers pour graver les bootloader des ATmega328P que j’achète neufs, pour ensuite pouvoir y téléverser des programmes arduino simplement, en FTDI.
Qu’est-ce qu’un « shield arduino » ?
Comme évoqué en intro, un « shield arduino » est tout simplement une carte électronique pouvant se fixer sur un arduino, afin d’y adjoindre une ou plusieurs fonctionnalités complémentaires. En fait, c’est quelque chose d’assez commun, même si l’usage en reste rare ou limité.
Voici d’ailleurs quelques exemples de shields arduino :
- carte Ethernet (pour ajouter à votre arduino une connexion au réseau local, puis à internet, via une prise RJ45)
- carte relais (pour contrôler depuis votre carte arduino la mise en marche ou l’arrêt de charges de moyenne à « forte » puissance)
- carte moteur (pour piloter des moteurs électriques, pas à pas ou DC par exemple, dans les projets robotiques)
- carte d’affichage (pour afficher des infos sur un écran LCD, TFT, ou autre)
- carte de prototypage (pour avoir l’équivalent d’une breadboard, montée sur arduino !)
Et ce ne sont là que quelques exemples parmi tant d’autres !
Dans cet article, je vous propose de voir ensemble la réalisation d’une « carte de programmation », de type « shield pour Arduino Uno », permettant de programmer des microcontrôleurs ATmega328P. Cela prendra donc la forme d’un circuit imprimé, embrochable sur carte uno, et qui sera à même d’accueillir les µC à programmer (au format DIP, 28 broches). Ça vous dit ? Alors en avant pour la suite 😉
Comment ce programmateur d’ATmega328P fonctionne t’il ?
En fait, le principe de fonctionnement de cette carte électronique est tout simple. Car il repose simplement sur le câblage typique d’un « programmateur d’ATmega328P via Arduino » (comme spécifié dans une documentation arduino, à cette adresse) :
Câblé de la sorte, ce montage permet de programmer l’ATmega328P en mode série (protocole STK500), en utilisant une carte Arduino Uno comme passerelle de programmation. Petite parenthèse à ce sujet : si vous souhaitez en savoir plus sur la programmation de l’ATmega 328P, de manière générale, n’hésitez pas à faire un saut sur l’article que j’avais fait il y a peu, vous expliquant comment programmer l’ATmega328P avec un Arduino Uno (via montages sur breadboard).
Maintenant, d’un point de vue pratique, voici comment se présente le projet que je vous présente ici, et son raccordement à l’Arduino Uno (on ne peut plus simple, avouez-le !) :
En clair : vous mettez l’un sur l’autre, et le tour est joué (le « reste » se passant de manière logicielle, en fait !).
Et côté utilisation, voici les étapes à suivre (tout cela sera détaillé au niveau des exemples #1 et #2 plus bas, ne vous inquiétez pas !) :
- préalablement transformer sa carte Arduino Uno en passerelle « Arduino as ISP » ; pour cela, il faudra :
- utiliser une carte Arduino Uno sans rien de branché dessus (ni shield, ni le moindre câble dupont ou autre)
- brancher cette carte arduino, seule, à son ordi
- ouvrir l’IDE Arduino
- téléverser le programme « Arduino ISP » dedans
- une fois fait, il faudra, pour préparer l’ensemble (carte uno + shield + microcontrôleur à graver) :
- débrancher sa carte Arduino Uno de toute alim ou liaison PC (la mettre totalement hors tension, donc)
- embrocher le shield dessus
- mettre un microcontrôleur ATmega328P sur le support amovible du shield
- enfin, programmer l’ATmega328P au travers de la carte arduino, en suivant les étapes suivantes :
- brancher l’ensemble Arduino Uno + shield + ATmega328P sur votre PC
- ouvrir l’IDE Arduino (ou le programme arduino que vous souhaitez graver)
- graver les données dans l’ATmega 328P
- et mettre le tout hors tension, puis sortir l’ATmega 328P à présent programmé, de son support !
Nota : il faudra toujours respecter toujours ces étapes à la lettre, afin de ne pas risquer d’endommager sa carte arduino ou son microcontrôleur ATmega 328P ! C’est très important, donc restez toujours très vigilant !
Remarque : il n’est pas nécessaire de répéter la 1ère étape (transformation de sa carte arduino en « passerelle ISP »), si vous dédiez cette carte arduino-là uniquement à la programmation d’ATmega328P (c’est à dire si vous prévoyez de toujours l’utiliser à cet usage). Par contre, il faudra impérativement refaire cette étape, si jamais votre carte Arduino Uno reçoit entre-temps un autre programme (autre que « Arduino ISP », j’entends). Sinon, vous risquez d’endommager l’ATmega 328 à programmer, attention !
Schéma électronique
Au niveau du schéma électronique de ce shield programmateur d’ATmega328P, on retrouve essentiellement le montage présenté au paragraphe précédent (dépourvu d’Arduino Uno ici, bien évidemment, car il s’agit seulement du shield qui va s’emboîter dessus !) :
À noter que j’ai rajouté 2 leds sur ce montage, pour indiquer la présence de tension sur le shield, et l’état de la ligne D13. Ceci est purement additionnel et optionnel, non nécessaire au bon fonctionnement du projet ! En fait, cela sert juste à vérifier que tout va bien 😉
On retrouve sur ce schéma électronique :
- le microcontrôleur ATmega 328P qu’on doit programmer (ou son support physique, pour être plus précis)
- l’horloge externe pour ATmega328P (composée d’un quartz de 16 MHz et de deux condensateurs de 22pF)
- une résistance de pull-up pour l’entrée RESET (broche 1) du microcontrôleur (cette broche est en fait pilotée par l’Arduino Uno)
- et un condensateur de découplage de 100nF, sur l’alim de l’AT mega 328P, comme préconisé par le fabricant
Liste des composants
Pour ceux que ça intéresse, voici la liste des composants et connecteurs mis en œuvre dans ce projet :
En dehors de ça, vous aurez également besoin d’au moins :
- 1 x microcontrôleur ATmega328P (format DIP / 28 broches), pour faire vos essais, si vous n’en n’avez pas
- 1 x carte Arduino Uno (sur laquelle viendra s’embrocher le shield / ce projet)
- 1 x câble USB, pour la liaison entre votre carte arduino et votre ordi (faisant office de câble d’alim et de programmation, pour l’ensemble)
Remarque : afin de ne pas risquer d’endommager tout ATmega328P à programmer en l’insérant/retirant, un support à zéro force d’insertion (« ZIF ») a été mis en œuvre. Ainsi, pas de risque de tordre des pattes au passage, à ce niveau 😉
Circuit imprimé (photos PCB + soudage)
Au niveau du circuit imprimé de ce programmateur d’ATmega328P monté sur Arduino Uno, on retrouve quelque chose d’assez simple et compact, au final :
En fait, il s’agit là d’une simple plaquette PCB double face, avec tous les composants soudés du même côté. À noter qu’il n’y a aucun CMS ici, tous les composants étant de type « traversant ».
Au passage, pour vous faire une meilleure idée de comment cette platine va venir s’insérer dans une carte Arduino Uno, voici la partie « soudage des headers » (connecteurs mâles venant s’emboîter dans les connecteurs femelles de la carte Arduino) :
Nota : cela n’apparaît pas sur les photos ici, mais en fait, j’ai soudé ces connecteurs mâles (headers) alors qu’ils étaient encore emboîtés dans la carte Uno. En fait, c’est une « astuce de soudeur », pour ainsi dire, afin de permettre une tenue bien verticale/perpendiculaire des connecteurs, pendant la phase de soudage. Ainsi, on obtient des connecteurs bien droits, bien alignés, bien d’équerre, … une fois soudés !
Du reste, voici quelques photos prises au moment du soudage des composants électroniques, pour bien visualiser chaque étape du montage de l’ensemble :
Ici, comme à l’accoutumée, j’ai soudé les composants dans l’ordre suivant : du plus petit (ou plus bas), au plus encombrant (ou plus haut). Rien de bien sorcier, en somme !
Tests préliminaires, avant usage
La première chose à faire, avant mise sous tension de ce shield, est une inspection visuelle des soudures réalisées (car un court-circuit ou mauvais contact est vite arrivé !). Au passage, je vous recommande de toujours retirer au possible la résine (flux) présente autour des soudures, afin de bien pouvoir visualiser ces dernières (et que ça fasse plus propre, par la même occasion !).
Ensuite, si tout est bon, vous pourrez passer à la mise sous-tension du shield, en l’emboîtant sur une carte Arduino Uno hors-tension, puis en mettant ce dernier sous-tension. Attention : ceci doit, pour l’instant, se faire SANS AUCUN microcontrôleur inséré dans le support ZIF du shield (sinon vous risquez de l’endommager, suivant le programme contenu dans la carte Arduino Uno !).
Si tout se passe bien, voici ce que vous devriez constater, au niveau des leds du shield :
- la led verte (« sous-tension ») doit être allumée, de manière fixe
- la led orange (« D13 ») doit clignoter 3 fois puis s’éteindre (à la mise sous tension, et à chaque RESET de la carte Arduino Uno) ; en fait, cela indique simplement la présence d’un bootloader, dans le µC de la carte Arduino Uno (ce qui est normal et on y touchera pas, bien entendu, car seul l’ATmega328P que nous mettrons dans le support amovible ZIF sera impacté/gravé/programmé !)
En image, voici ce que ça donne (led « sous tension » allumée, et led « D13 » éteinte au bout d’une seconde environ) :
Important : ne mettez jamais le moindre microcontrôleur ATmega328P dans le support amovible bleu (ZIF), tant que ces 2 conditions ne sont pas réunies :
– la carte Arduino Uno devra impérativement contenir le programme « Arduino as ISP » (comme nous le verrons dans les deux exemples qui suivent)
– et toute insertion/retrait de µC (ou du shield en entier) devra se faire hors tension (pour éviter tout risque d’endommagement)
Utilisation #1 : graver un bootloader dans un ATmega328P
Pour graver un bootloader dans un microcontrôleur ATmega328P via une carte Arduino Uno, il faut avant tout que la carte Arduino Uno soit configurée en programmateur ISP, pour ensuite pouvoir graver tout bootloader dans votre ATmega 328P. Ceci repose donc sur 2 étapes, que je vais vous détailler ici.
Bien sûr, une fois qu’une carte Arduino Uno est configurée en tant que « programmateur ISP », ce n’est pas nécessaire de la reprogrammer à chaque fois, si vous souhaitez programmer plusieurs ATmega328P. Dans ce cas, vous n’aurez donc qu’à répéter la 2ème opération ! Cela étant dit, dans le doute, n’hésitez pas à refaire l’étape 1 (ça ne fait pas de mal, pour ainsi dire !).
Important : certaines parties se font hors-tension. Prêtez y attention comme il se doit, afin de ne pas commettre d’impair !
Transformation de la carte Arduino Uno en « programmateur ISP »
Alors, avant de tenter toute opération de gravure de bootloader dans votre ATmega328P, il faut que votre carte Arduino Uno soit transformée en « programmateur ISP ». Cela se fait extrêmement simplement, rassurez-vous ! Car il suffit simplement de téléverser le « bon » programme dans votre carte Uno (nommé « ArduinoISP » et disponible de base dans l’IDE Arduino), et le tour est joué 🙂
Pour ce faire, il y a tout d’abord 2 conditions à respecter :
- votre carte Arduino Uno doit être utilisée seule, c’est à dire sans rien de branché dessus (hormis votre cordon Arduino ↔ PC, bien entendu !)
- l’IDE Arduino doit être installée sur votre PC (perso, j’utilise la version 1.8.18)
Si ces conditions sont remplies, vous pouvez donc respecter la procédure suivante, pour convertir votre carte Uno en « Arduino as ISP » (ce qui revient simplement à téléverser un programme particulier, pour tout dire) :
- ouvrez l’IDE Arduino sur votre ordi
- cliquez sur le menu Fichier > Exemples > 11.ArduinoISP > ArduinoISP, afin que le code du « programmateur ISP » s’ouvre à l’écran, devant vous
- branchez votre Arduino Uno sur votre PC (important: votre carte arduino ne doit être reliée à rien d’autre que votre ordi)
- cliquez sur le menu Outils > Type de carte > et vérifiez que « Arduino Uno » est bien sélectionné
- cliquez sur le menu Outils > Port > et sélectionnez le port COM de votre carte Arduino Uno (si cela ne s’est pas fait, automatiquement)
- cliquez sur le menu Outils > Programmateur > et vérifiez que « AVRISP mkII » est bien sélectionné (ce qui doit être le cas, par défaut, sinon changez le !)
- cliquez sur l’icône « Téléverser » (ou allez dans le menu Croquis > Téléverser), pour envoyer ce programme dans la carte Arduino Uno (c’est à ce moment là qu’elle deviendra un « programmateur ISP »)
- et débranchez la carte Arduino Uno de votre PC (très important, car le passage à l’étape suivante doit se faire « hors tension »)
Félicitation, vous avez transformé votre carte Arduino Uno en programmateur ISP (« Arduino as ISP », comme ils disent !).
Nota : comme évoqué précédemment, vous n’avez pas besoin de répéter cette étape, si vous prévoyez de graver plusieurs bootloader. En fait, il faudra uniquement répéter cette étape si vous avez téléversé un autre programme dans votre carte Uno, entre-temps !
Graver le bootloader dans l’ATmega328P
À présent, nous allons mettre en œuvre le shield, pour programmer notre (ou nos) ATmega328P !
Pour ce faire, il faut d’abord disposer des 3 éléments suivants :
- une carte Arduino Uno transformée en carte « Arduino as ISP » (comme vu ensemble, dans le paragraphe précédent)
- le shield arduino, objet du présent article !
- un microcontrôleur ATmega 328P (ou plusieurs), à graver
Une fois en main, il faudra emboîter ces trois éléments ensembles (implanter le µC sur le shield, et emboîter le shield sur la carte uno), en veillant à être hors tension, pendant cette opération. En image, voici à quoi doit ressembler cet ensemble :
Ensuite, vous n’aurez plus qu’à brancher votre carte Arduino Uno à votre PC, ce qui va alimenter le tout, et permettre la programmation du bootloader en suivant. D’ailleurs, à ce sujet, voici les étapes à suivre :
- ouvrez l’IDE Arduino (ce qui ouvre un programme arduino vierge à l’écran, ce qui est parfait ici)
- cliquez sur le menu Fichier > Préférences > et cochez la case « téléversement » (figurant à droite du texte « Afficher les résultats détaillés pendant ») ; cela vous permettra d’avoir tout plein d’infos détaillées au moment de la gravure du bootloader, facilitant ainsi le débuggage, en cas de problème (nota : ceci n’est pas indispensable)
- cliquez sur le menu Outils > Type de carte > et vérifiez que « Arduino Uno » est bien sélectionné
- cliquez sur le menu Outils > Port > et sélectionnez le port COM de votre carte Arduino Uno (si ce n’est pas déjà fait)
- cliquez sur le menu Outils > Programmateur > et sélectionnez « Arduino as ISP » (TRÈS IMPORTANT : ne vous trompez pas au milieu de tous les différents noms de programmateurs qui apparaissent à l’écran, dans le menu ! Ici, c’est « Arduino as ISP » qu’il nous faut, et aucun autre ! Ne vous trompez pas !)
- puis cliquez sur Outils > Graver la séquence d’initialisation (pour que la procédure de gravure du bootloader soit initiée)
Si tout s’est bien passé, voici ce que vous devriez voir apparaître à l’écran (au passage, je vous montre ici le « bon » programmateur à sélectionner, parmi toutes les options présentes, avec des noms très ressemblant !) :
Du reste, au niveau de la zone de log (détaillant toute l’opération), voici ce qui ressort de mon côté (le nom des répertoires pouvant varier d’un PC, utilisateur, et système d’exploitation à l’autre) :
C:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -cstk500v1 -PCOM4 -b19200 -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDE:m -Ulfuse:w:0xFF:m
avrdude: Version 6.3-20190619
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "C:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"
Using Port : COM4
Using Programmer : stk500v1
Overriding Baud Rate : 19200
AVR Part : ATmega328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
Programmer Type : STK500
Description : Atmel STK500 Version 1.x firmware
Hardware Version: 2
Firmware Version: 1.18
Topcard : Unknown
Vtarget : 0.0 V
Varef : 0.0 V
Oscillator : Off
SCK period : 0.1 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: erasing chip
avrdude: reading input file "0x3F"
avrdude: writing lock (1 bytes):
Writing | ################################################## | 100% 0.01s
avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x3F:
avrdude: load data lock data from input file 0x3F:
avrdude: input file 0x3F contains 1 bytes
avrdude: reading on-chip lock data:
Reading | ################################################## | 100% 0.01s
avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude: reading input file "0xFD"
avrdude: writing efuse (1 bytes):
Writing | ################################################## | 100% 0.02s
avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0xFD:
avrdude: load data efuse data from input file 0xFD:
avrdude: input file 0xFD contains 1 bytes
avrdude: reading on-chip efuse data:
Reading | ################################################## | 100% 0.01s
avrdude: verifying ...
avrdude: 1 bytes of efuse verified
avrdude: reading input file "0xDE"
avrdude: writing hfuse (1 bytes):
C:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -cstk500v1 -PCOM4 -b19200 -Uflash:w:C:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6/bootloaders/optiboot/optiboot_atmega328.hex:i -Ulock:w:0x0F:m
Writing | ################################################## | 100% 0.02s
avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xDE:
avrdude: Version 6.3-20190619
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
avrdude: load data hfuse data from input file 0xDE:
avrdude: input file 0xDE contains 1 bytes
avrdude: reading on-chip hfuse data:
Copyright (c) 2007-2014 Joerg Wunsch
Reading | ################################################## | 100% 0.01s
System wide configuration file is "C:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"
avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xFF"
avrdude: writing lfuse (1 bytes):
Writing | ################################################## | 100% 0.02s
avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xFF:
avrdude: load data lfuse data from input file 0xFF:
avrdude: input file 0xFF contains 1 bytes
avrdude: reading on-chip lfuse data:
Reading | ################################################## | 100% 0.01s
avrdude: verifying ...
avrdude: 1 bytes of lfuse verified
avrdude done. Thank you.
Using Port : COM4
Using Programmer : stk500v1
Overriding Baud Rate : 19200
AVR Part : ATmega328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
Programmer Type : STK500
Description : Atmel STK500 Version 1.x firmware
Hardware Version: 2
Firmware Version: 1.18
Topcard : Unknown
Vtarget : 0.0 V
Varef : 0.0 V
Oscillator : Off
SCK period : 0.1 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02s
avrdude: Device signature = 0x1e950f (probably m328p)
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 "C:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6/bootloaders/optiboot/optiboot_atmega328.hex"
avrdude: writing flash (32768 bytes):
Writing | ################################################## | 100% 0.00s
avrdude: 32768 bytes of flash written
avrdude: verifying flash memory against C:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6/bootloaders/optiboot/optiboot_atmega328.hex:
avrdude: load data flash data from input file C:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6/bootloaders/optiboot/optiboot_atmega328.hex:
avrdude: input file C:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6/bootloaders/optiboot/optiboot_atmega328.hex contains 32768 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: 32768 bytes of flash verified
avrdude: reading input file "0x0F"
avrdude: writing lock (1 bytes):
Writing | ################################################## | 100% 0.02s
avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x0F:
avrdude: load data lock data from input file 0x0F:
avrdude: input file 0x0F contains 1 bytes
avrdude: reading on-chip lock data:
Reading | ################################################## | 100% 0.01s
avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude done. Thank you.
Bravo, votre ATmega328P est à présent doté d’un bootloader, ce qui vous permettra ensuite de pouvoir le programmer en FTDI ou autre !
Utilisation #2 : graver un programme arduino dans l’ATmega328P
Ici, nous allons voir comment graver un programme arduino dans l’ATmega328P, c’est à dire comment enregistrer un programme directement dans la mémoire flash du microcontrôleur (avec ou sans bootloader, peu importe, car toute la mémoire sera effacée !).
À noter que cette « gravure » n’est pas évidemment définitive, car vous pourrez bien entendu enregistrer d’autres programmes par dessus / à la place. Par contre, du fait de l’absence de bootloader ici, cette méthode sera la « seule » possible, pour modifier/changer le programme de votre µC (ce qui là encore peut être modifié à l’avenir, en gravant un bootloader à la place du programme, ce qui permettra ensuite le téléversement « classique » de programmes arduino via FTDI ou autre).
Cela étant dit, passons à la pratique !
Alors, pour commencer, il faut avant tout transformer sa carte Arduino Uno en « programmateur ISP » (c’est d’ailleurs exactement la procédure que nous avons suivi, au paragraphe §7.1). Ainsi, votre carte Arduino Uno sera prête à accueillir le shield par dessus (contenant l’ATmega328P à programmer), et prête pour graver le programme qu’on souhaite dans l’ATmega 328P. Il y a donc 2 étapes à suivre, que je vais vous détailler l’une après l’autre ici.
Nota : bien évidemment, une fois que votre carte Uno est transformée en « programmateur ISP », il n’est pas nécessaire de le refaire à chaque fois (si vous souhaitez programmer plusieurs ATmega328P, j’entends). Dans ce cas, vous n’aurez donc qu’à répéter la 2ème étape. Par contre, si vous changez votre programme dans l’Arduino Uno entretemps, ou si vous avez un doute sur le programme contenu dedans, alors il faudra répéter la 1ère étape, pour éviter tout risque d’endommager votre µC !
Important : certaines manips se font « hors tension ». Prêtez donc bien attention à tout ce que je vous décris ici, afin de ne pas commettre d’impair !
Transformer sa carte Arduino Uno en « programmateur as ISP »
Alors, avant de tenter toute opération de gravure dans la mémoire flash de votre ATmega328P, vous devrez toujours vous assurer que votre carte Arduino Uno soit préalablement transformée en « programmateur ISP ». Mais ne vous inquiétez pas, cela est vraiment simple à faire ! Car il suffit tout bonnement de téléverser le programme prévu à cet effet (« ArduinoISP »), dans votre carte Uno, et le tour est joué 🙂
Pour faire cela, il y a tout d’abord 2 préalables à respecter :
- votre carte Arduino Uno doit être nue, c’est à dire sans rien de branché dessus (hormis votre cordon d’alimentation/programmation USB, bien entendu !)
- le logiciel Arduino IDE doit être installé sur votre PC (perso, j’utilise la version 1.8.18)
Si ces deux conditions sont remplies, vous pouvez alors poursuivre, suivant la procédure suivante (qui revient à téléverser un programme arduino particulier, pour faire simple) :
- ouvrir votre IDE Arduino, au niveau de votre PC
- brancher votre carte Uno sur votre ordi (rappel: votre carte arduino ne doit être reliée à rien d’autre que votre PC)
- cliquer dans le menu Fichier > Exemples > 11.ArduinoISP > ArduinoISP, pour que le code du « programmateur ISP » s’ouvre à l’écran devant vous
- cliquer dans le menu Outils > Type de carte > et vérifier que « Arduino Uno » est bien sélectionné
- cliquer dans le menu Outils > Port > et sélectionner le port COM de votre carte Uno (si ceci ne s’est pas automatiquement fait)
- cliquer dans le menu Outils > Programmateur > et vérifier que « AVRISP mkII » est bien sélectionné (sinon changez le, en faisant bien attention de ne pas vous tromper, avec les autres noms « ressemblant » !)
- cliquer dans le menu Croquis > Téléverser (ou cliquer sur l’icône « Téléverser »), pour envoyer ce programme dans votre carte Arduino Uno (au passage, c’est à ce moment là qu’elle deviendra un « programmateur as ISP », à proprement parler)
- et débrancher le câble USB entre votre carte Arduino Uno et votre PC (ce qui est très important pour la suite, car l’étape suivante doit se faire hors-tension)
Bravo, vous venez de transformer votre carte Arduino Uno en programmateur ISP (ou « Arduino as ISP », comme ils disent !).
Remarque : comme indiqué précédemment, vous n’aurez pas besoin de répéter cette étape, si vous prévoyez de graver plusieurs programmes dans votre ATmega328P (quand bien même ceux-ci seraient différents). Car votre carte uno sera juste utilisée comme « passerelle de programmation », d’où le programme spécifique téléversé dedans (« Arduino ISP »). En fait, vous devrez uniquement répéter cette première étape si vous avez modifié le programme de votre carte Uno entretemps, ou si vous n’êtes pas sûr du programme qu’il contient !
Graver le programme arduino dans l’ATmega328P
À présent, nous allons utiliser notre shield, pour programmer notre (nos) ATmega 328P !
Pour cela, il nous faudra tout d’abord disposer des éléments suivants :
- notre carte Arduino Uno, précédemment transformée en carte « Arduino as ISP » (comme nous venons juste de le voir ensemble, au paragraphe précédent)
- notre shield arduino, objet du présent article !
- et un (ou plusieurs) microcontrôleurs ATmega328P à programmer
Physiquement parlant, nous allons empiler tous ces éléments les uns sur les autres (hors tension), c’est à dire mettre l’ATmega328P dans le support prévu à cet effet sur le shield, et embrocher le shield sur l’Arduino Uno.
Rappel : rien ne doit être alimenté, lorsque vous faites cet empilement. Tout doit se faire hors-tension.
Et une fois fait, l’ensemble devra ressembler à quelque chose comme ça :
À présent, vous pouvez brancher votre carte Arduino Uno sur votre ordi. Ainsi, l’ensemble sera alimenté, et la gravure d’un programme sur l’ATmega 328P pourra se faire. D’ailleurs, à ce sujet, voici les étapes à suivre :
- dans l’IDE Arduino, ouvrir le programme arduino que vous souhaitez graver dans votre ATmega328P (ou prendre le programme « Blink » pour faire des essais, si vous préférez ; nota : celui-ci est accessible en cliquant dans le menu Fichier > Exemples > 01.Basics > Blink)
- au besoin, cliquer dans le menu Fichier > Préférences > et cocher la case « téléversement », pour afficher les détails de programmation, dans la partie log (nota : cette case figure à droite du texte « Afficher les résultats détaillés pendant », dans la fenêtre des préférences)
- cliquer dans le menu Outils > Type de carte > et vérifier que « Arduino Uno » est bien sélectionné
- cliquer dans le menu Outils > Port > et sélectionner le port COM correspondant à votre carte Arduino Uno (si cela ne s’est pas fait automatiquement)
- cliquer dans le menu Outils > Programmateur > et sélectionner « Arduino as ISP » (ATTENTION : faites bien attention à ne pas vous tromper ici, tant il y a de noms qui se ressemblent ; le « bon » programmateur s’appelle « Arduino as ISP », et rien d’autre !)
- puis cliquer sur Croquis > « Téléverser avec un programmateur » (TRÈS IMPORTANT : ne faites surtout pas un simple « TELEVERSER », sans quoi c’est votre carte Arduino Uno et non votre ATmega328P qui sera ciblée, pour le téléversement ! Au passage, si jamais vous faites cette erreur, vous devrez refaire l’étape précédente, à savoir retransformer votre carte Arduino Uno en « programmateur ISP », avant de répéter cette étape)
Si tout s’est bien passé, vous devriez voir quelque chose comme ça, apparaître à l’écran (au passage, je vous montre ici la « bonne » option à sélectionner dans le menu, à savoir « Téléverser avec programmateur », parmi toutes les choix possibles !) :
Et au niveau de la zone de log, détaillant toute les opérations effectuées par l’IDE, vous devriez vous retrouver avec quelque chose comme ce qui suit (les noms de répertoires pouvant changer d’un ordi, utilisateur, et système d’exploitation à l’autre) :
Le croquis utilise 924 octets (2%) de l'espace de stockage de programmes. Le maximum est de 32256 octets.
Les variables globales utilisent 9 octets (0%) de mémoire dynamique, ce qui laisse 2039 octets pour les variables locales. Le maximum est de 2048 octets.
C:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -cstk500v1 -PCOM4 -b19200 -Uflash:w:C:\Users\JEROME\AppData\Local\Temp\arduino_build_960507/Blink.ino.hex:i
avrdude: Version 6.3-20190619
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "C:\Users\JEROME\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"
Using Port : COM4
Using Programmer : stk500v1
Overriding Baud Rate : 19200
AVR Part : ATmega328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
Programmer Type : STK500
Description : Atmel STK500 Version 1.x firmware
Hardware Version: 2
Firmware Version: 1.18
Topcard : Unknown
Vtarget : 0.0 V
Varef : 0.0 V
Oscillator : Off
SCK period : 0.1 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02s
avrdude: Device signature = 0x1e950f (probably m328p)
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 "C:\Users\JEROME\AppData\Local\Temp\arduino_build_960507/Blink.ino.hex"
avrdude: writing flash (924 bytes):
Writing | ################################################## | 100% 1.11s
avrdude: 924 bytes of flash written
avrdude: verifying flash memory against C:\Users\JEROME\AppData\Local\Temp\arduino_build_960507/Blink.ino.hex:
avrdude: load data flash data from input file C:\Users\JEROME\AppData\Local\Temp\arduino_build_960507/Blink.ino.hex:
avrdude: input file C:\Users\JEROME\AppData\Local\Temp\arduino_build_960507/Blink.ino.hex contains 924 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.62s
avrdude: verifying ...
avrdude: 924 bytes of flash verified
avrdude done. Thank you.
Félicitation, votre ATmega328P est à présent programmé, avec le programme arduino que vous souhaitiez !
Remarque importante : si vous programmez un ATmega328P « tout juste sorti d’usine », il se peut qu’il tourne à 1MHz au lieu de 16 MHz. Cela est dû au fait que, de base, un 328P est programmé d’usine pour tourner à 8 MHz sur oscillateur interne, avec diviseur d’horloge par 8 activé (d’où les 1 MHz). Si jamais ce problème vous arrive, ne vous inquiétez pas ! Car il suffit simplement de reprogrammer les fusibles en conséquence, pour fonctionner à 16MHz sur oscillateur à quartz externe. Pour cela, le plus simple est selon moi d’exécuter la procédure de gravage de bootloader (comme vu ensemble au paragraphe §7, car cela va « initialiser » les fusibles comme on souhaite), puis de graver votre programme par dessus, comme détaillé ici, dans le présent paragraphe (car cela va effacer le bootloader précédemment gravé, tout en gardant la nouvelle configuration de fusibles !).
Liens et téléchargements
Outre la liste des composants électroniques détaillée plus haut, voici les fichiers ayant servi à la conception du circuit imprimé, à savoir :
- le schéma électronique du projet (format PDF)
- le fichier Gerber permettant de faire reproduire le PCB à l’identique, si souhaité (format ZIP)
Du reste, si vous avez des questions, n’hésitez pas à m’en faire part en zone commentaire, tout en bas de cet article ! J’y répondrai dès que je le pourrais, mais comme toujours, selon le temps que j’ai et dans la mesure du possible !
Nota : si vous souhaitez faire reproduire le circuit imprimé présenté ici à l’identique, il vous suffit de transmettre le fichier ZIP ci-dessus (le fichier Gerber) à un fabricant (tel que JLCPCB, par exemple), pour qu’il le réalise pour vous (moyennant finances, bien entendu !).
Programmateur ATmega328P : conclusion !
Voilà ! En espérant que ce petit montage puisse vous servir à l’avenir, autant qu’il me sert au quotidien ! Vous pourrez ainsi programmer vos propres ATmega328P via Arduino Uno depuis l’IDE Arduino, que ce soit pour y graver un simple bootloader, ou un programme tout entier sans bootloader !
Perso, de mon côté, je m’en sers uniquement pour graver des bootloader dans mes ATmega 328P, qu’ensuite je programme via FTDI (comme détaillé ici). Mais libre à vous de faire comme vous l’entendez, et comme vous êtes le plus à l’aise 😉
Sur ce, je vous dis à bientôt !
Jérôme.
À découvrir aussi : un voltmètre 0-25 volts fait maison, à base de microcontrôleur ATmega328 !
(*) Mis à jour le 20/03/2024
Comme d’habitude c’est trop cool ce que vous faites !
Merci merci !
Merci Jérôme pour tout ce travail acharné. C’est super bien expliqué.
De rien, avec plaisir 🙂
Tuto parfait !
C’est très intéressant, il y a pas mal de circuits qui utilisent encore cette version de l’ATmega328. Il y aurait peut-être moyen de rendre le montage plus universel en lui permettant d’accepter aussi des ATtiny 45 ou 85
Oui oui, tu as parfaitement raison !
Mais là, à la base, il s’agissait de réaliser un montage didactique. C’est pourquoi j’ai essayé de ne pas m’écarter du sujet (l’ATmega328P), afin d’éviter de perdre du monde en route 😉
Encore merci pour ton retour, et excellente journée à toi !
Un énorme bravo et un grand merci pour cette étude si complète ! J’ai vraiment hâte de m’y mettre.
Quel boulot !!!
Je dis … Chapeau Monsieur Jérome
Merci beaucoup 🙂
Bjr à tous !!! Je ne rajoute pas de félicitation, tout est dit plus haut …. Mais bon courage !!!
Génial merci !!! Tout est clair !
Un article très intéressant, bien structuré et bien expliqué.
Un grand merci à toi Jérôme !
De rien, et merci à toi pour ce retour !
Afin de filtrer au maximum les messages de type "spam" ou "inappropriés", chaque commentaire est soumis à modération, et validé manuellement. Du coup, il se peut que certains commentaires ne soient pas publiés, ou sinon, avec un peu de retard. Par ailleurs, j'ai malheureusement plus de messages à traiter que de temps pour y répondre ; c'est pourquoi je ne pourrais pas répondre à tout le monde. Désolé …