Nous étudions les contrôleurs avr. Microcontrôleurs Atmega8. Programmation Atmega8 pour les débutants. Résultats vers les indicateurs

Les microcontrôleurs (ci-après dénommés MK) sont fermement entrés dans nos vies ; sur Internet, vous pouvez trouver de nombreux circuits intéressants exécutés sur MK. Ce qu'on ne peut pas assembler sur un MK : indicateurs divers, voltmètres, appareils électroménagers (dispositifs de protection, interrupteurs, thermomètres...), détecteurs de métaux, jouets divers, robots, etc. La liste pourrait prendre beaucoup de temps. J'ai vu le premier circuit d'un microcontrôleur il y a 5 ou 6 ans dans un magazine radio, et j'ai presque immédiatement tourné la page en me disant : « Je ne pourrai toujours pas l'assembler ». En effet, à cette époque, les MK étaient pour moi un appareil très complexe et incompris ; je n'avais aucune idée de comment ils fonctionnaient, comment les flasher et quoi en faire en cas de firmware incorrect. Mais il y a environ un an, j'ai assemblé pour la première fois mon premier circuit sur un MK : il s'agissait d'un circuit de voltmètre numérique basé sur des indicateurs à 7 segments et un microcontrôleur ATmega8. Il se trouve que j'ai acheté un microcontrôleur par accident, alors que j'étais dans le département des composants radio, le gars en face de moi achetait un MK, et j'ai aussi décidé de l'acheter et d'essayer d'assembler quelque chose. Dans mes articles je vais vous parler Microcontrôleurs AVR , je vais vous apprendre à travailler avec eux, nous examinerons les programmes pour le firmware, nous créerons un programmeur simple et fiable, nous examinerons le processus du firmware et, surtout, les problèmes qui peuvent survenir. uniquement pour les débutants.

Paramètres de base de certains microcontrôleurs de la famille AVR :

Microcontrôleur

Mémoire flash

Mémoire RAM

Mémoire EEPROM

Ports E/S

U puissance

Paramètres supplémentaires du méga microcontrôleur AVR :

Température de fonctionnement : -55…+125*С
Température de stockage : -65…+150*С
Tension à la broche RESET par rapport à GND : max 13 V
Tension d'alimentation maximale : 6,0 V
Courant maximum de ligne d'E/S : 40 mA
Courant d'alimentation maximum VCC et GND : 200 mA

Brochage du modèle ATmega 8X

Brochages pour les modèles ATmega48x, 88x, 168x

Disposition des broches pour les modèles ATmega8515x

Disposition des broches pour les modèles ATmega8535x

Disposition des broches pour les modèles ATmega16, 32x

Disposition des broches pour les modèles ATtiny2313

Une archive avec les fiches techniques de certains microcontrôleurs est jointe à la fin de l'article.

Embouts FUSE d'installation MK AVR

N'oubliez pas qu'un fusible programmé est 0, un fusible non programmé est 1. Vous devez être prudent lors du réglage des fusibles : un fusible mal programmé peut bloquer le microcontrôleur. Si vous n'êtes pas sûr du fusible à programmer, il est préférable de flasher le MK sans fusible pour la première fois.

Les microcontrôleurs les plus populaires parmi les radioamateurs sont ATmega8, suivis des ATmega48, 16, 32, ATtiny2313 et autres. Les microcontrôleurs sont vendus en packages TQFP et DIP ; pour les débutants, je recommande d'acheter en DIP. Si vous achetez des TQFP, il sera plus problématique de les flasher ; vous devrez acheter ou souder la carte car leurs jambes sont très proches les unes des autres. Je vous conseille d'installer des microcontrôleurs en boîtiers DIP sur des sockets spéciaux, c'est pratique et pratique, vous n'avez pas besoin de dessouder le MK si vous souhaitez le reflasher, ou l'utiliser pour une autre conception.

Presque tous les MK modernes ont la capacité de programmer des FAI en circuit, c'est-à-dire Si votre microcontrôleur est soudé à la carte, nous n'aurons pas besoin de le dessouder de la carte pour modifier le firmware.

6 broches sont utilisées pour la programmation :
RÉINITIALISER- Connexion MK
VCC- Alimentation plus, 3-5V, dépend du MK
GND- Fil commun, moins l'alimentation.
MOSI- Entrée MK (signal d'information en MK)
MISO- Sortie MK (signal d'information de MK)
SCK- Entrée MK (signal d'horloge en MK)

Parfois, ils utilisent également les broches XTAL 1 et XTAL2 ; le quartz est attaché à ces broches si le MK est alimenté par un oscillateur externe ; dans les ATmega 64 et 128, les broches MOSI et MISO ne sont pas utilisées pour la programmation du FAI ; à la place, les broches MOSI sont connecté à la broche PE0 et MISO à la broche PE1. Lors de la connexion du microcontrôleur au programmateur, les fils de connexion doivent être aussi courts que possible et le câble allant du programmateur au port LPT ne doit pas non plus être trop long.

Le marquage du microcontrôleur peut contenir des lettres étranges avec des chiffres, par exemple Atmega 8L 16PU, 8 16AU, 8A PU, etc. La lettre L signifie que le MK fonctionne à une tension inférieure à celle du MK sans la lettre L, généralement 2,7 V. Les chiffres après le trait d'union ou l'espace 16PU ou 8AU indiquent la fréquence interne du générateur qui se trouve dans le MK. Si les fusibles sont réglés pour fonctionner à partir d'un quartz externe, le quartz doit être réglé sur une fréquence ne dépassant pas le maximum selon la fiche technique, soit 20 MHz pour les ATmega48/88/168 et 16 MHz pour les autres atmegas.

D'une manière ou d'une autre, je me suis immédiatement senti obligé de donner des conseils sur le choix d'un environnement de programmation pour les contrôleurs AVR. Ne me lance pas de pantoufles. Je suis juste un petit peu :)

Il existe de nombreux langages de programmation pour les microcontrôleurs. Il existe également de nombreux environnements de programmation et il est incorrect de les comparer entre eux. Il n’existe pas de meilleurs langages de programmation. Cela signifie que vous devrez choisir le langage et l’environnement de programmation les plus adaptés à vos besoins.

Si vous êtes actuellement confronté à un choix sur quoi commencer à travailler, voici quelques recommandations pour vous.

Expérience antérieure en programmation. Ne négligez pas votre expérience antérieure en programmation. Même si c'était BASIC. Même si c'était il y a longtemps à l'école. Programmer, c’est comme faire du vélo : une fois que vous commencez, vous vous souvenez rapidement de tout ce que vous avez oublié. Commencez par BASIC - maîtrisez-le - plus tard, il sera plus facile de choisir quelque chose de plus adapté à vos besoins.

Aide de l'environnement. Vos amis écrivent-ils en Pascal ? Le problème est résolu pour vous – écrivez en Pascal ! Ils vous aideront toujours avec des conseils, vous donneront des bibliothèques et vous donneront des projets prêts à l'emploi à étudier. En général, ils seront heureux de vous accueillir dans leur communauté. Si vous faites le contraire, vous obtiendrez le résultat inverse. Les amis de l'industrie de la CEI vous picoreront si vous décidez d'étudier l'assembleur. N'attendez pas d'aide.

Bon livre sur la programmation AVR aidera beaucoup. Malheureusement, ils sont très peu nombreux. Si vous tombez sur un livre et pensez que tout est expliqué de manière très accessible, essayez-le. Je ne recommande pas d'étudier livres électroniques Au minimum, imprimez-le. Il est très gênant de basculer entre l'environnement et le texte du fichier livre. Il est bien plus agréable de lire un livre et de l’essayer tout de suite, sans se laisser distraire par les changements ; en plus, on peut prendre des notes dans les marges et noter les idées qui surgissent.

L'environnement de programmation est plus simple. S'il existe plusieurs environnements de programmation parmi lesquels choisir pour votre langage, n'hésitez pas, choisissez celui qui est le plus simple. Que ce soit moins fonctionnel. Laissez-la compiler du code horriblement volumineux. L'essentiel est de commencer à travailler. Une fois que vous serez à l’aise dans un environnement simple, vous pourrez facilement passer à un environnement plus avancé et « correct ». Et n’écoutez pas ceux qui disent que vous perdrez encore du temps : ils ont tort. On ne demande pas aux élèves du primaire de lire "Guerre et Paix", on leur donne des livres plus simples - avec des images.

Bibliothèques. La disponibilité des bibliothèques est controversée pour l'apprentissage des langues. Bien sûr, plus tard, ils rendront la vie beaucoup plus facile, mais au début, les bibliothèques « Black Box » sont incompréhensibles et ne contribuent pas vraiment à la compréhension du langage. D'un autre côté, ils rendent le programme plus facile à lire et permettent à un débutant de construire sans trop d'effort. programmes complexes. Alors ne vous souciez pas trop de leur présence. Au moins au début.

Code efficace. Choisir un environnement de programmation pour apprendre la programmation uniquement en fonction de l’efficacité du code compilé est une mauvaise idée. L’essentiel est que vous vous sentiez à l’aise lorsque vous commencez à étudier – ce qui en ressort est la dixième chose. Bien sûr, vous pourrez y travailler plus tard.

Sorciers. Tout périphérique intégré à la puce doit être configuré à l'aide de ports. La procédure est assez fastidieuse et des fiches techniques sont nécessaires. De plus, il existe des nuances qui ne sont pas faciles à saisir pour un débutant. Par conséquent, il est très souhaitable d’avoir des assistants dans l’environnement. Les Vyzards sont des tuners automatiques pour SPI, I2C, USART, etc. Plus il y a d’appareils pris en charge, mieux c’est. Vous définissez les paramètres périphériques nécessaires et l'assistant lui-même génère du code qui fournira paramètres donnés. Rend la vie beaucoup plus facile.


Recommandations générales tel - la programmation au stade initial doit être aussi simple que possible (même primitive). L'environnement de programmation doit être facile à apprendre (puisqu'il faut d'abord maîtriser la programmation et ne pas perdre de temps à bidouiller les réglages). De préférence russifié. Un manuel en russe et des exemples de programmes seraient également utiles. La capacité de faire sortir le cristal de l’environnement est souhaitable. Ensuite, à mesure que vous maîtriserez les bases de la programmation, vous pourrez passer à des shells plus complexes.


Une dernière recommandation : travailler avec un vrai cristal. N'ayez pas peur de le brûler. Acquérir une expérience pratique. Travailler avec des émulateurs (par exemple Proteus), même si cela vous évitera de vous soucier d'un fer à souder, ne pourra jamais vous donner la satisfaction que vous obtiendrez du programme de travail et du premier clignotement de la LED ! Comprendre que vous avez réalisé un véritable diagramme de travail de vos propres mains vous donne confiance et vous incite à passer à autre chose !

(Visité 7 554 fois, 2 visites aujourd'hui)

Il existe différents langages de programmation pour les microcontrôleurs AVR, mais les plus appropriés sont peut-être l'assembleur et le C, car ces langages implémentent au mieux toutes les capacités nécessaires à la gestion du matériel du microcontrôleur.

Le langage assembleur est un langage de programmation de bas niveau qui utilise le jeu d’instructions direct du microcontrôleur. Créer un programme dans ce langage nécessite une bonne connaissance du système de commande de la puce programmable et suffisamment de temps pour développer le programme. Le langage assembleur est inférieur au C en termes de vitesse et de facilité de développement du programme, mais présente des avantages notables dans la taille du code exécutable final et, par conséquent, dans la rapidité de son exécution.

C permet de créer des programmes avec beaucoup plus de confort, offrant au développeur tous les avantages d'un langage de haut niveau.
Il convient de noter encore une fois que l'architecture et le système de commande d'AVR ont été créés avec la participation directe des développeurs du compilateur du langage C et qu'il prend en compte les fonctionnalités de ce langage. La compilation du code source C est rapide et produit un code compact et efficace.

Les principaux avantages du C par rapport à l'assembleur : grande vitesse de développement du programme ; universalité qui ne nécessite pas une étude approfondie de l'architecture du microcontrôleur ; une meilleure documentabilité et lisibilité de l'algorithme ; disponibilité de bibliothèques de fonctions ; prise en charge des calculs en virgule flottante.

Le langage C combine harmonieusement les capacités de programmation de bas niveau avec les propriétés d'un langage de haut niveau. La capacité de programmation de bas niveau vous permet d'opérer facilement directement sur le matériel, et les propriétés du langage de haut niveau vous permettent de créer un code de programme facilement lisible et modifiable. De plus, presque tous les compilateurs C ont la possibilité d'utiliser des insertions assembleur pour écrire des sections de programme critiques en termes de temps d'exécution et de consommation de ressources.

En un mot, C est le langage le plus pratique aussi bien pour les débutants qui se familiarisent avec les microcontrôleurs AVR que pour les développeurs sérieux.

Les compilateurs sont utilisés pour convertir le code source d'un programme en un fichier de micrologiciel de microcontrôleur.

Atmel fournit un puissant compilateur d'assembly inclus dans l'environnement de développement Atmel Studio fonctionnant sous Windows. Outre le compilateur, l'environnement de développement contient un débogueur et un émulateur.
Atmel Studio est entièrement gratuit et disponible sur le site Atmel.

Actuellement, il existe de nombreux compilateurs C pour AVR. Le plus puissant d'entre eux est considéré comme le compilateur d'IAR Systems de Stockholm. Ce sont ses employés qui ont participé au développement du système de commande AVR au milieu des années 90. IAR C Compiler possède des capacités étendues d'optimisation de code et fait partie de l'environnement de développement intégré IAR Embedded Workbench (EWB), qui comprend également un compilateur assembleur, un éditeur de liens, un gestionnaire de projet et de bibliothèque et un débogueur. Prix version complète le forfait est de 2820 EUR. Sur le site Web de l'entreprise, vous pouvez télécharger une version d'évaluation gratuite pendant 30 jours ou une version illimitée avec une limite de taille de code de 4 Ko.

La société américaine Image Craft de Palo Alto, en Californie, produit un compilateur en langage C qui a acquis une assez grande popularité. JumpStart C pour AVR a une optimisation raisonnable du code et ne l'est pas trop prix élevé(50 $ à 499 $ selon la version). La version démo de JumpStart C pour AVR est entièrement fonctionnelle pendant 45 jours.

Le compilateur roumain Code Vision AVR C n'a pas gagné moins de popularité, le prix de la version complète de ce compilateur est relativement bas et s'élève à 150 EUR. Le compilateur est livré avec un environnement de développement intégré qui, en plus des fonctionnalités standard, comprend un nombre suffisant de fonctionnalité intéressante- Générateur de programme automatique CodeWizardAVR. La présence d'un terminal série dans l'environnement de développement vous permet de déboguer des programmes à l'aide port série microcontrôleur. Vous pouvez télécharger une version d'évaluation gratuite auprès des développeurs avec une limite de taille de code de 4 Ko et une sauvegarde désactivée du code source généré en C.

La société MikroElektronika, située dans la ville serbe de Belgrade, produit toute une famille de compilateurs pour microcontrôleurs AVR. Un compilateur pour le langage C appelé mikroC PRO pour AVR coûte 249 $. Il existe également mikroBasic et mikroPascal pour le même prix. Il existe des versions de démonstration sur le site Web des développeurs avec une limite de taille de code de 4 096 octets. L'avantage de cette famille de compilateurs est une plate-forme unique et une idéologie unique, qui peuvent assurer une transition facile non seulement entre les langages, mais aussi entre les microcontrôleurs (il existe des versions de compilateurs pour PIC, STM32, 8051...).

L’environnement de développement intégré est devenu véritablement emblématique. Il comprend de puissants compilateurs C et assembleur, le programmeur AVRDUDE, un débogueur, un simulateur et de nombreux autres programmes et utilitaires de support. WinAVR s'intègre parfaitement à l'environnement de développement AVR Studio d'Atmel. L'assembleur est identique en code d'entrée à l'assembleur AVR Studio. Les compilateurs C et assembleur ont la possibilité de créer des fichiers de débogage au format COFF, ce qui vous permet d'utiliser non seulement les outils intégrés, mais également le puissant simulateur AVR Studio. Un autre avantage important est que WinAVR est distribué gratuitement et sans restrictions (les fabricants prennent en charge la licence publique générale GNU).

En résumé, il faut dire que WinAVR est un choix idéal pour ceux qui commencent à maîtriser les microcontrôleurs AVR. C'est cet environnement de développement qui est considéré comme principal dans ce cours.

Kiselev Roman, mai 2007 Article mis à jour le 26 mai 2014

Alors, qu'est-ce qu'un microcontrôleur (ci-après dénommé MK) ? Il s'agit, relativement parlant, d'un petit ordinateur logé dans un seul circuit intégré. Il dispose d'un processeur (unité arithmétique et logique ou ALU), d'une mémoire flash, d'une mémoire EEPROM, de nombreux registres, de ports d'E/S, ainsi que de fonctionnalités supplémentaires telles que des minuteries, des compteurs, des comparateurs, des USART, etc. Après la mise sous tension , le microcontrôleur démarre et commence à exécuter le programme stocké dans sa mémoire flash. En même temps, il peut contrôler une grande variété de périphériques externes via les ports E/S.

Qu'est-ce que cela signifie? Cela signifie que dans le MK, vous pouvez implémenter n'importe quel circuit logique qui remplira certaines fonctions. Cela signifie que le MK est un microcircuit dont nous créons en fait le contenu interne nous-mêmes. Ce qui permet, après avoir acheté plusieurs MK totalement identiques, de les assembler complètement différents schémas et appareils. Si vous souhaitez apporter des modifications au travail appareil électronique, vous n'aurez alors pas besoin d'utiliser de fer à souder, il suffira simplement de reprogrammer le MK. Dans ce cas, vous n'avez même pas besoin de le supprimer de votre appareil si vous utilisez un AVR, puisque ces MK prennent en charge la programmation en circuit. Ainsi, les microcontrôleurs comblent le fossé entre la programmation et l’électronique.

Les AVR sont des microcontrôleurs 8 bits, c'est-à-dire que leur ALU peut effectuer des opérations simples avec seulement des nombres 8 bits en un cycle d'horloge. Il est maintenant temps de parler du MK que nous utiliserons. Je travaille avec un ATMega16 MK. Il est très courant et peut être acheté dans presque tous les magasins de pièces détachées radio pour environ 100 roubles. Si vous ne le trouvez pas, vous pouvez acheter n'importe quel autre MK de la série MEGA, mais dans ce cas, vous devrez rechercher de la documentation, car les mêmes « jambes » de différents MK peuvent fonctionner. différentes fonctions, et après avoir connecté tous les terminaux apparemment correctement, vous pourriez obtenir un appareil fonctionnel, ou peut-être juste un nuage de fumée puante. Lors de l'achat d'un ATMega16, assurez-vous qu'il est livré dans un grand boîtier DIP à 40 broches et achetez également une prise dans laquelle il peut être inséré. Pour travailler avec, vous aurez également besoin appareils supplémentaires: LEDs, boutons, connecteurs, etc.

ATMega16 a très gros montant une grande variété de fonctions. Voici quelques-unes de ses caractéristiques :

  • Maximum fréquence d'horloge– 16 MHz (8 MHz pour ATMega16L)
  • La plupart des commandes sont exécutées en un seul cycle d'horloge
  • 32 registres de travail 8 bits
  • 4 ports E/S complets 8 bits
  • deux minuteries/compteurs 8 bits et un 16 bits
  • Convertisseur analogique-numérique (ADC) 10 bits
  • générateur d'horloge interne à 1 MHz
  • comparateur analogique
  • interfaces SPI, I2C, TWI, RS-232, JTAG
  • programmation en circuit et auto-programmation
  • module modulation de largeur d'impulsion(MLI)

Les caractéristiques complètes de cet appareil, ainsi que les instructions pour leur utilisation, peuvent être trouvées dans l'ouvrage de référence (Fiche technique) de ce MK. C'est vrai, il est sur langue anglaise. Si vous connaissez l'anglais, assurez-vous de télécharger cette fiche technique, elle contient de nombreuses informations utiles.

Passons enfin aux choses sérieuses. Je recommande de créer une carte de développement et de débogage spéciale pour le microcontrôleur, sur laquelle vous pouvez assembler n'importe quel schéma électrique avec un microcontrôleur. L'utilisation d'une telle carte facilitera grandement le travail avec le MK et accélérera le processus d'apprentissage de sa programmation. Cela ressemble à ceci :

De quoi aurez-vous besoin pour cela ?

Tout d’abord, vous aurez besoin du tableau lui-même. J'en ai acheté un tout fait dans un magasin de pièces détachées radio pour 115 roubles. Ensuite, j'y ai soudé toutes les pièces nécessaires. Le résultat est une chose incroyablement pratique sur laquelle vous pouvez assembler n'importe quel circuit électrique en quelques minutes en connectant des câbles et en installant des microcircuits et des indicateurs.

Pour connecter les éléments du circuit, il est très pratique d'utiliser des câbles avec des connecteurs aux extrémités. Ces connecteurs sont placés sur les « pattes » dépassant à côté de chaque port du MK. Le microcontrôleur doit être installé dans le support et non soudé à la carte, sinon il sera très difficile de le retirer si vous le brûlez accidentellement. Vous trouverez ci-dessous le brochage de l'ATMEGA16 MK :

Expliquons quelles jambes nous intéressent maintenant.

  • VCC - l'alimentation est fournie ici (4,5 - 5,5 V) à partir d'une source stabilisée
  • GND – masse
  • RESET – réinitialisation (à faible niveau de tension)
  • XTAL1, XTAL2 – un résonateur à quartz est connecté ici
  • PA, PB, PC, PD – ports d'entrée/sortie (A, B, C et D, respectivement).

Tout ce qui produit du 7 à 11 V CC peut être utilisé comme source d'alimentation. Pour un fonctionnement stable du MK, une alimentation électrique stabilisée est nécessaire. En tant que stabilisateur, vous pouvez utiliser des microcircuits de la série 7805. Ce sont des stabilisateurs linéaires intégrés dont l'entrée est alimentée en 7-11 V de courant continu non stabilisé et la sortie est de 5 V de courant stabilisé. Avant et après 7805, vous devez installer des condensateurs de filtrage (électrolytiques pour filtrer les interférences basse fréquence et céramique pour les hautes fréquences). Si vous ne trouvez pas de stabilisateur, vous pouvez utiliser comme source d'alimentation une batterie de 4,5 V. Le MK doit être alimenté directement par celle-ci.

Ci-dessous un schéma de la connexion MK :

Voyons maintenant ce qui se passe ici.

BQ1 est un résonateur à quartz qui règle la fréquence de fonctionnement du MK. Vous pouvez en définir jusqu'à 16 MHz, mais comme nous prévoyons de travailler à l'avenir avec un port COM, je recommande d'utiliser des résonateurs pour les fréquences suivantes : 14,7456 MHz, 11,0592 MHz, 7,3725 MHz, 3,6864 MHz ou 1,8432 MHz (plus tard on comprendra pourquoi). J'ai utilisé 11,0592 MHz. Il est clair que plus la fréquence est élevée, plus la vitesse de l'appareil est élevée.

R1 est une résistance pull-up qui maintient une tension de 5 V à l'entrée RESET. Un niveau de tension faible sur cette entrée indique une réinitialisation. Après la réinitialisation, le MK démarre (10 à 15 ms) et recommence à exécuter le programme. Puisqu'il s'agit d'une entrée à haute impédance, vous ne pouvez pas la laisser "pendre dans les airs" - un petit micro dessus entraînera une réinitialisation inattendue du MK. C'est exactement à cela que sert R1. Pour plus de fiabilité, je recommande également d'installer le condensateur C6 (pas plus de 20 µF).

SB1 – bouton de réinitialisation.

Le résonateur à quartz et le condensateur de filtrage C3 doivent être situés aussi près que possible du MK (pas plus de 5 à 7 cm), sinon des interférences pourraient se produire dans les fils, entraînant des dysfonctionnements du MK.

Le rectangle bleu dans le diagramme décrit le programmeur lui-même. Il est pratique de le réaliser sous la forme d'un fil dont une extrémité est branchée sur le port LPT et l'autre sur un certain connecteur à côté du MK. Le fil ne doit pas être trop long. Si des problèmes surviennent avec ce câble (généralement non, mais tout peut arriver), vous devrez souder l'adaptateur Altera ByteBlaster. Comment procéder est écrit dans la description du programmeur AVReal.

Maintenant que nous avons traité du matériel, il est temps de passer au logiciel.

Il existe plusieurs environnements de développement pour la programmation AVR. Tout d'abord, il s'agit d'AVR Studio - le système de programmation officiel d'Atmel. Il permet d'écrire en assembleur et de déboguer des programmes écrits en assembleur, C et C++. IAR est un système de programmation commercial en langage C, C++ et assembleur. WinAVR est un compilateur open source. AtmanAVR est un système de programmation pour AVR avec une interface presque exactement la même que celle de Visual C++ 6. AtmanAVR vous permet également de déboguer des programmes et contient de nombreuses fonctions d'assistance qui facilitent l'écriture de code. Ce système de programmation est commercial, mais, selon la licence, vous pouvez l'utiliser gratuitement pendant un mois.

Je suggère de commencer à travailler avec IAR comme environnement de développement le plus transparent. Dans IAR, un projet est créé entièrement à la main ; donc, après avoir réalisé plusieurs projets, vous saurez déjà clairement ce que signifie chaque ligne de code et ce qui se passera si vous la modifiez. Lorsque vous travaillez avec AtmanAVR, vous devrez soit utiliser un modèle pré-créé, très lourd et difficile à comprendre pour une personne sans expérience, soit avoir beaucoup de problèmes avec les fichiers d'en-tête lors de l'assemblage du projet à partir de zéro. Après avoir traité d'IAR, nous examinerons ensuite d'autres compilateurs.

Alors, d’abord, procurez-vous de l’IAR. C’est très courant et le trouver ne devrait pas poser de problème. Après avoir téléchargé IAR 3.20 quelque part, installez le compilateur/environnement de travail et lancez-le. Après cela, vous pouvez commencer à travailler.

Après avoir lancé IAR, sélectionnez fichier/nouveau/espace de travail, sélectionnez le chemin d'accès à notre projet, créez un dossier pour celui-ci et donnez-lui un nom, par exemple « Prog1 ». Créons maintenant un projet : Projet / Créer un nouveau projet… Appelons-le également « Prog1 ». Faites un clic droit sur le titre du projet dans l'arborescence du projet et sélectionnez « Options »

Ici, nous allons configurer le compilateur pour un MK spécifique. Tout d'abord, vous devez sélectionner le type de processeur ATMega16 dans l'onglet Cible, cocher la case Activer les définitions de bits dans les fichiers d'inclusion/sortie dans l'onglet Configuration de la bibliothèque (afin que vous puissiez utiliser les noms de bits de différents registres MK dans le code du programme. ), et sélectionnez-y le type de bibliothèque C /EU++. Dans la catégorie ICCAVR, vous devez cocher la case Activer la prise en charge multi-octets dans l'onglet Langue et désactiver l'optimisation dans l'onglet Optimisation (sinon cela ruinera notre premier programme).

Ensuite, sélectionnez la catégorie XLINK. Ici, vous devez déterminer le format du fichier compilé. Puisque nous définissons maintenant les options pour le mode Debug, comme décrit dans le titre, nous devons obtenir un fichier de débogage en sortie. Plus tard, nous l'ouvrirons dans AVR Studio. Pour ce faire, vous devez sélectionner l'extension.cof et le type de fichier est ubrof 7.

Cliquez maintenant sur OK, puis remplacez Debug par Release.

Accédez à nouveau aux Options, où tous les paramètres, à l'exception de XLINK, sont définis de la même manière. Dans XLINK, remplacez l'extension par .hex et le format de fichier par Intel-Standart.

C'est tout. Vous pouvez maintenant commencer à écrire votre premier programme. Créez une nouvelle source/texte et entrez-y le code suivant :

#inclure"iom16.h" court int non signé i ; vide principal( vide) (DDRB = 255 ; PORTB = 0 ; alors que(1) { si(PORTB == 255) PORTB = 0 ; autre PORTB++; pour(je=0; je

Le fichier "iom16.h" se trouve dans le dossier (C:\Program Files)\IAR Systems\Embedded Workbench 3.2\avr\inc. Si vous utilisez un autre MK, par exemple ATMega64, sélectionnez le fichier « iom64.h ». Ces fichiers d'en-tête stockent des informations sur le MK : les noms des registres, les bits des registres et les noms des interruptions. Chaque broche individuelle du port A, B, C ou D peut agir comme une entrée ou une sortie. Ceci est déterminé par le registre de direction des données (DDR). 1 fait de la jambe une sortie, 0 une entrée. Ainsi, en réglant par exemple DDRA = 13, on fait les "jambes" sorties PB0, PB2, PB3, le reste - entrées, car 13 en binaire vaut 00001101.

PORTB est un registre qui détermine l'état des broches du port. Après y avoir écrit 0, nous réglons la tension à toutes les sorties sur 0 V. Ensuite, il y a une boucle sans fin. Lors de la programmation du MK, ils effectuent toujours une boucle sans fin dans laquelle le MK effectue une action jusqu'à ce qu'il soit réinitialisé ou jusqu'à ce qu'une interruption se produise. Dans ce cycle, ils écrivent pour ainsi dire un « code de fond », que le MK exécute en dernier lieu. Il peut s'agir par exemple d'afficher des informations sur un écran. Dans notre cas, le contenu du registre PORTB est augmenté jusqu'à ce qu'il soit plein. Après cela, tout recommence. Enfin, dix mille cycles pour une boucle. Il est nécessaire de former un retard visible dans la commutation de l'état du port B.



Maintenant, nous enregistrons ce fichier dans le dossier du projet sous le nom Prog1.c, copions le fichier iom16.h dans le dossier du projet, sélectionnons Projet/Ajouter des fichiers et ajoutons « iom16.h » et « Prog1.c ». Sélectionnez Release, appuyez sur F7, le programme se compile et le message devrait apparaître :


Nombre total d'erreurs : 0
Nombre total d'avertissements : 0

Voici une photo de mon programmateur :

Téléchargez le programmeur AVReal. Copiez-le (AVReal32.exe) dans le dossier Release/exe, où doit se trouver le fichier Prog1.hex. Nous alimentons le MK, connectons le câble de programmation. Ouverture Gestionnaire lointain(c'est plus pratique de flasher MK), allez dans ce dossier, appuyez sur Ctrl+O. Puisque nous avons un tout nouveau MK, on ​​bourre

avreal32.exe +MEGA16 -o11.0592MHZ -p1 -fblev=0,jtagen=1,cksel=F,sut=1 –w

N'oubliez pas de saisir la bonne fréquence si vous n'utilisez pas 11059200 Hz ! Dans le même temps, ce qu'on appelle fusibles – registres qui contrôlent son fonctionnement (utilisation d’un générateur interne, Jtag, etc.). Après cela, il est prêt à recevoir le premier programme. Le programmeur reçoit le port LPT utilisé, la fréquence, le nom de fichier et d'autres comme paramètres (tous sont répertoriés dans la description d'AVReal). Nous composons :

Avreal32.exe + Mega16 -o11.0592MHz -p1 -e -w -az -% Prog1.hex

Si la connexion est correcte, le programmateur signalera une programmation réussie. Il n'y a aucune garantie que cela fonctionnera du premier coup (la première fois que vous appelez le programme). Il m'arrive moi-même de me faire programmer une deuxième fois. Peut-être que le port LPT est défectueux ou qu'il y a des interférences dans le câble. Si des problèmes surviennent, vérifiez soigneusement votre câble. D'après ma propre expérience, je sais que 60 % des dysfonctionnements sont associés à un manque de contact au bon endroit, 20 % à la présence d'un contact inutile et 15 % supplémentaires à une soudure erronée du mauvais élément au mauvais élément. Si tout le reste échoue, lisez la description du programmeur et essayez de créer Byte Blaster.

Supposons que tout fonctionne pour vous. Si vous connectez maintenant huit LED au port B du MK (faites-le avec le MK éteint et il est conseillé d'inclure des résistances de 300 à 400 Ohm en série avec les LED) et appliquez l'alimentation, un petit miracle se produira - un " vague » les traversera !

© Kiselev Roman
mai 2007

Bonjour, cher Habrazhitel!

Dans cet article, je veux parler de la façon dont j'ai décidé de commencer à programmer des microcontrôleurs, de ce qui était nécessaire pour cela et de ce qui a fini par se produire.

Le sujet des microcontrôleurs m'a intéressé il y a longtemps, en 2001. Mais il s'est ensuite avéré problématique d'avoir un programmeur sur mon lieu de résidence, et il n'était pas question de l'acheter via Internet. J'ai dû reporter cette affaire jusqu'à des temps meilleurs. Et puis un jour j'ai découvert que des temps meilleurs je suis venu sans quitter la maison, vous pouvez acheter tout ce dont j'avais besoin. J'ai décidé de l'essayer. Alors ce dont nous avons besoin :

1. Programmeur
Il existe de nombreuses options sur le marché - depuis les programmeurs ISP (In-System Programming) les moins chers pour quelques dollars jusqu'aux puissants programmeurs-débogueurs pour quelques centaines. N'ayant pas beaucoup d'expérience en la matière, j'ai d'abord décidé d'essayer l'un des plus simples et des moins chers - USBasp. Je l'ai acheté sur eBay à un moment donné pour 12 $, maintenant vous pouvez le trouver pour 3 à 4 $. Il s'agit en fait d'une version chinoise du programmeur de Thomas Fischl. Que puis-je dire de lui ? Une seule chose : ça marche. De plus, il prend en charge de nombreux contrôleurs AVR des séries ATmega et ATtiny. Sous Linux ne nécessite pas de pilote.

Pour flasher le firmware, vous devez connecter les sorties du programmateur VCC, GND, RESET, SCK, MOSI, MISO avec les sorties correspondantes du microcontrôleur. Pour plus de simplicité, j'ai assemblé le circuit auxiliaire directement sur la breadboard :

A gauche sur la carte se trouve le même microcontrôleur que nous allons flasher.

2. Microcontrôleur
Je ne me suis pas trop soucié du choix du microcontrôleur et j'ai pris l'ATmega8 d'Atmel - 23 broches d'E/S, deux timers 8 bits, un 16 bits, fréquence jusqu'à 16 MHz, faible consommation (1-3,6 mA) , pas cher (2$). En général, pour commencer, c'est plus que suffisant.

Sous Linux, la combinaison avr-gcc + avrdude fonctionne bien pour compiler et charger le firmware sur le contrôleur. L'installation est triviale. En suivant les instructions, vous pourrez installer tous les logiciels nécessaires en quelques minutes. La seule nuance à laquelle vous devez prêter attention est qu'avrdude (logiciel d'enregistrement sur le contrôleur) peut nécessiter des droits de super-utilisateur pour accéder au programmeur. La solution est de l'exécuter via sudo (pas une très bonne idée) ou d'enregistrer des droits udev spéciaux. La syntaxe peut varier selon différentes versions OS, mais dans mon cas ( Linux Menthe 15) l'ajout de la règle suivante au fichier /etc/udev/rules.d/41-atmega.rules a fonctionné :

# Programmeur USBasp SUBSYSTEM=="usb", ATTR(idVendor)=="16c0", ATTR(idProduct)=="05dc", GROUP="plugdev", MODE="0666"

Après cela, bien sûr, vous devez redémarrer le service
redémarrage du service udev
Vous pouvez compiler et flasher sans problème directement depuis ligne de commande(qui en douterait), mais s'il y a beaucoup de projets, alors il est plus pratique d'installer un plugin et de tout faire directement depuis l'environnement Eclipse.

Pour Windows, vous devrez installer un pilote. Sinon, il n'y a aucun problème. Par souci d'intérêt scientifique, j'ai essayé la combinaison AVR Studio + eXtreme Burner sous Windows. Encore une fois, tout fonctionne très bien.

Commençons la programmation

Les contrôleurs AVR peuvent être programmés aussi bien en assembleur (assembleur AVR) qu'en C. Ici, je pense que chacun devrait faire son propre choix en fonction de la tâche spécifique et de ses préférences. Personnellement, j'ai d'abord commencé à bricoler avec l'assembleur. Lors de la programmation en assembleur, l'architecture de l'appareil devient plus claire et on a l'impression de plonger directement dans l'intérieur du contrôleur. De plus, je crois que dans les programmes particulièrement critiques en termes de taille et de performances, la connaissance de l'assembleur peut être très utile. Après m'être familiarisé avec l'assembleur AVR, j'ai rampé vers C.

Après m'être familiarisé avec l'architecture et les principes de base, j'ai décidé de créer quelque chose d'utile et d'intéressant. Ici, ma fille m'a aidé, elle joue aux échecs et un beau soir elle m'a dit qu'elle voulait avoir une minuterie pour les parties chronométrées. BOUM ! La voici - l'idée du premier projet ! Bien sûr, on pouvait les commander sur eBay, mais je voulais fabriquer ma propre montre, avec des... euh... indicateurs et boutons noirs. À peine dit que c'était fait!

Il a été décidé d'utiliser deux indicateurs à diodes à 7 segments comme affichage. Pour le contrôle, 5 boutons suffisaient - "Joueur 1", "Joueur 2", "Réinitialiser", "Paramètres" et "Pause". Eh bien, n’oubliez pas l’indication sonore de la fin du jeu. On dirait que c'est ça. La figure ci-dessous montre un schéma général de connexion du microcontrôleur aux indicateurs et aux boutons. Nous en aurons besoin lors de l'analyse du code source du programme :

Compte rendu

Commençons, comme prévu, par le point d'entrée du programme - la fonction principale. En fait, cela n'a rien de remarquable : configuration des ports, initialisation des données et une boucle sans fin de pressions sur les boutons de traitement. Eh bien, en appelant sei() - permettant le traitement des interruptions, nous en parlerons un peu plus tard.

Int main(void) ( init_io(); init_data(); sound_off(); sei(); while(1) ( handle_buttons(); ) return 0; )
Examinons chaque fonction séparément.

Void init_io() ( // définir la sortie DDRB = 0xFF; DDRD = 0xFF; // définir l'entrée DDRC = 0b11100000; // résistances de rappel PORTC |= 0b00011111; // interruptions de minuterie TIMSK = (1<

La configuration des ports d'E/S est très simple : un nombre est écrit dans le registre DDRx (où x est la lettre désignant le port), dont chaque bit signifie si la broche correspondante sera un périphérique d'entrée (correspond à 0) ou un périphérique de sortie (correspond à 1). Ainsi, en envoyant le numéro 0xFF aux DDRB et DDRD, nous avons réalisé des ports de sortie B et D. En conséquence, la commande DDRC = 0b11100000 ; transforme les 5 premières broches du port C en broches d'entrée et les autres en broches de sortie. Commande PORTC |= 0b00011111 ; comprend des résistances de rappel internes sur 5 entrées du contrôleur. Selon le schéma, des boutons sont connectés à ces entrées qui, lorsqu'ils sont enfoncés, les court-circuitent à la masse. De cette façon, le contrôleur comprend que le bouton est enfoncé.

Vient ensuite la configuration de deux timers, Timer0 et Timer1. Nous utilisons le premier pour mettre à jour les indicateurs et le second pour décompter le temps, après l'avoir préalablement configuré pour se déclencher toutes les secondes. Une description détaillée de toutes les constantes et de la méthode de réglage de la minuterie sur un intervalle spécifique peut être trouvée dans la documentation ATmega8.

Gestion des interruptions

ISR (TIMER0_OVF_vect) ( display(); if (_buzzer > 0) ( _buzzer--; if (_buzzer == 0) sound_off(); ) ) ISR(TIMER1_COMPA_vect) ( if (ActiveTimer == 1 && Timer1 > 0) ( Minuterie1--; si (Timer1 == 0) process_timeoff(); ) if (ActiveTimer == 2 && Timer2 > 0) ( Timer2--; if (Timer2 == 0) process_timeoff(); ) )

Lorsque la minuterie se déclenche, le contrôle est transféré au gestionnaire d'interruption approprié. Dans notre cas, il s'agit du gestionnaire TIMER0_OVF_vect, qui appelle la procédure d'affichage de l'heure sur les indicateurs, et TIMER1_COMPA_vect, qui traite le compte à rebours.

Résultats vers les indicateurs

Void display() ( display_number((Timer1/60)/10, 0b00001000); _delay_ms(0.25); display_number((Timer1/60)%10, 0b00000100); _delay_ms(0.25); display_number((Timer1%60)/10 , 0b00000010); _delay_ms(0,25); display_number((Timer1%60)%10, 0b00000001); _delay_ms(0,25); display_number((Timer2/60)/10, 0b10000000); _delay_ms(0,25); display_number((Timer2/ 60)%10, 0b01000000); _delay_ms(0.25); display_number((Timer2%60)/10, 0b00100000); _delay_ms(0.25); display_number((Timer2%60)%10, 0b00010000); _delay_ms(0.25); PORTD = 0; ) void display_number(int number, int masque) ( ​​PORTB = number_mask(number); PORTD = masque; )

La fonction d'affichage utilise une méthode d'affichage dynamique. Le fait est que chaque indicateur individuel dispose de 9 contacts (7 pour le contrôle des segments, 1 pour le point et 1 pour l'alimentation). Pour contrôler 4 chiffres, 36 contacts seraient nécessaires. Trop de gaspillage. Ainsi, la sortie des chiffres vers un indicateur à plusieurs chiffres est organisée selon le principe suivant :

La tension est fournie alternativement à chacun des contacts communs, ce qui permet de mettre en évidence le numéro souhaité sur l'indicateur correspondant à l'aide des mêmes 8 contacts de commande. À une fréquence de sortie suffisamment élevée, cela ressemble à une image statique à l’œil nu. C'est pourquoi les 8 contacts d'alimentation des deux indicateurs du schéma sont connectés à 8 sorties du port D, et les 16 contacts de contrôle de segment sont connectés par paires et connectés aux 8 sorties du port B. Ainsi, la fonction d'affichage avec un retard de 0,25 ms affiche alternativement le numéro souhaité sur chacun des indicateurs. Enfin, toutes les sorties qui alimentent les indicateurs en tension sont désactivées (commande PORTD = 0;). Si cela n'est pas fait, le dernier chiffre affiché continuera à être allumé jusqu'au prochain appel à la fonction d'affichage, ce qui entraînera sa lueur plus brillante que les autres.

Gestion des clics

Void handle_buttons() ( handle_button(KEY_SETUP); handle_button(KEY_RESET); handle_button(KEY_PAUSE); handle_button(KEY_PLAYER1); handle_button(KEY_PLAYER2); ) void handle_button(int key) ( int bit; switch (key) ( case KEY_SETUP: bit = SETUP_BIT; pause; cas KEY_RESET: bit = RESET_BIT; pause; cas KEY_PAUSE: bit = PAUSE_BIT; pause; cas KEY_PLAYER1: bit = PLAYER1_BIT; pause; cas KEY_PLAYER2: bit = PLAYER2_BIT; pause; par défaut: retour; ) si (bit_is_clear( BUTTON_PIN, bit)) ( if (_pressed == 0) ( _delay_ms(DEBOUNCE_TIME); if (bit_is_clear(BUTTON_PIN, bit)) ( _pressed |= key; // commutateur d'action de touche (touche) ( case KEY_SETUP: process_setup(); pause; cas KEY_RESET: process_reset(); pause; cas KEY_PAUSE: processus_pause(); pause; cas KEY_PLAYER1: processus_player1(); pause; cas KEY_PLAYER2: processus_player2(); pause; ) sound_on(15); ) ) ) autre ( _pressed &= ~clé; ) )

Cette fonction interroge tour à tour les 5 boutons et traite le clic, le cas échéant. Le clic est enregistré en vérifiant bit_is_clear(BUTTON_PIN, bit) , c'est-à-dire le bouton est enfoncé si l'entrée correspondante est connectée à la masse, ce qui se produira, selon le schéma, lorsque le bouton est enfoncé. Un délai d'une durée DEBOUNCE_TIME et des vérifications répétées sont nécessaires pour éviter plusieurs opérations inutiles dues au rebond de contact. La sauvegarde de l'état enfoncé dans les bits correspondants de la variable _pressed permet d'éviter des déclenchements répétés lors d'un appui prolongé sur le bouton.
Les fonctions de traitement des clics sont assez triviales et je pense qu'elles ne nécessitent pas de commentaires supplémentaires.

Texte intégral du programme

#définir F_CPU 4000000UL #inclure #inclure #inclure #define DEBOUNCE_TIME 20 #define BUTTON_PIN PINC #define SETUP_BIT PC0 #define RESET_BIT PC1 #define PAUSE_BIT PC2 #define PLAYER1_BIT PC3 #define PLAYER2_BIT PC4 #define KEY_SETUP 0b00000001 #define KEY_RESET 0b00000010 #define KEY_PAUSE 0b0000 0100 #define KEY_PLAYER1 0b00001000 #define KEY_PLAYER2 0b00010000 int volatile ActiveTimer = 0 ; volatile int Minuterie1 = 0 ; volatile int Minuterie2 = 0 ; volatile int _buzzer = 0 ; volatile int _pressed = 0; // déclarations de fonctions void init_io(); void init_data(); int numéro_masque(int num); void handle_buttons(); void handle_button (clé int); void process_setup(); void process_reset(); void process_pause(); void process_timeoff(); void process_player1(); void process_player2(); affichage vide (); void display_number (masque int, numéro int); void sound_on (intervalle int); void sound_off(); // interrompt ISR (TIMER0_OVF_vect) ( display(); if (_buzzer > 0) ( _buzzer--; if (_buzzer == 0) sound_off(); ) ) ISR(TIMER1_COMPA_vect) ( if (ActiveTimer == 1 && Timer1 > 0) ( Timer1--; if (Timer1 == 0) process_timeoff(); ) if (ActiveTimer == 2 && Timer2 > 0) ( Timer2--; if (Timer2 == 0) process_timeoff(); ) ) int main (void) ( init_io(); init_data(); sound_off(); sei(); while(1) ( handle_buttons(); ) return 0; ) void init_io() ( // définit la sortie DDRB = 0xFF; DDRD = 0xFF ; // définir l'entrée DDRC = 0b11100000; // résistances de rappel PORTC |= 0b00011111; // interruptions de minuterie TIMSK = (1<5940 || Timer2 > 5940) ( Timer1 = 0; Timer2 = 0; ) ) void process_reset() ( init_data(); ) void process_timeoff() ( init_data(); sound_on(30); ) void process_pause() ( ActiveTimer = 0; ) void process_player1() ( ActiveTimer = 2; ) void process_player2() ( ActiveTimer = 1; ) void handle_button(int key) ( int bit; switch (key) ( case KEY_SETUP : bit = SETUP_BIT ; break ; case KEY_RESET : bit = RESET_BIT ; pause; cas KEY_PAUSE : bit = PAUSE_BIT ; pause ; cas KEY_PLAYER1 : bit = PLAYER1_BIT ; pause ; cas KEY_PLAYER2 : bit = PLAYER2_BIT ; pause ; par défaut : retour ; ) if (bit_is_clear(BUTTON_PIN, bit)) ( if (_pressed == 0) ( _delay_ms(DEBOUNCE_TIME); if (bit_is_clear(BUTTON_PIN, bit)) ( _pressed |= key; // commutateur d'action de touche (touche) ( case KEY_SETUP: process_setup(); break; case KEY_RESET: process_reset(); break; case KEY_PAUSE : process_pause(); break; case KEY_PLAYER1 : process_player1(); break; case KEY_PLAYER2 : process_player2(); break; ) sound_on(15); ) ) ) else ( _pressed &= ~key; ) ) void handle_buttons() ( handle_button(KEY_SETUP); handle_button(KEY_RESET); handle_button(KEY_PAUSE); handle_button(KEY_PLAYER1); handle_button(KEY_PLAYER2); ) void display() ( display_number((Timer1/60)/10, 0b00001000) ; _delay_ms(0,25); display_number((Timer1/60)%10, 0b00000100); _delay_ms(0,25); display_number((Timer1%60)/10, 0b00000010); _delay_ms(0,25); display_number((Timer1%60)% 10, 0b00000001); _delay_ms(0,25); display_number((Timer2/60)/10, 0b10000000); _delay_ms(0,25); display_number((Timer2/60)%10, 0b01000000); _delay_ms(0,25); display_number((Timer2 %60)/10, 0b00100000); _delay_ms(0.25); display_number((Timer2%60)%10, 0b00010000); _delay_ms(0.25); PORTD = 0; ) void display_number(int number, int masque) ( ​​PORTB = number_mask (nombre); PORTD = masque; ) void sound_on(int intervalle) ( _buzzer = intervalle; // mettre la broche du buzzer haut PORTC |= 0b00100000; ) void sound_off() ( // mettre la broche du buzzer bas PORTC &= ~0b00100000; )

Le prototype a été assemblé sur une maquette.

gastrogourou 2017