(3e édition). Programmation pratique des microcontrôleurs Atmel AVR en langage assembleur

Une fois, j'ai vu une vidéo intéressante sur Internet, elle montrait un jeu de serpent implémenté sur un microcontrôleur et une matrice LED 8x8, puis j'ai trouvé plusieurs autres vidéos similaires qui m'intéressaient. Parmi eux, il y avait aussi une vidéo où le jeu Tetris était assemblé sur un microcontrôleur « puissant ». Après avoir regardé, j'ai décidé de développer ma propre version de l'appareil, qui combine les deux jeux, en utilisant un microcontrôleur PIC16F688 et deux matrices LED qui affichent le terrain de jeu avec une résolution de 8x16 pixels.

Le schéma de l'appareil est présenté ci-dessous. Les informations sont sorties vers les matrices H1, H2 en mode dynamique à l'aide des registres à décalage DD2, DD3, DD4. Les sorties des microcircuits DD2, DD3 sont connectées aux anodes des matrices. Les cathodes des deux matrices sont connectées aux collecteurs des transistors VT1-VT8 dont les signaux de commande sont générés par le microcircuit DD4. Le microcontrôleur charge les données dans le registre DD4, lorsqu'il déborde, les informations de la broche 9 sont transférées à l'entrée du registre DD3, puis de la même manière les données sont transférées vers le registre DD2. Les résistances R1-R16 limitent le courant traversant les LED matricielles. Les résistances R17-R23 règlent le courant de base des transistors VT1-VT8. Le microcontrôleur fonctionne à 8 MHz à partir d'un oscillateur interne. Le taux de rafraîchissement de l'image est de 100 Hz.


Après la mise sous tension, l'économiseur d'écran du jeu « Snake » s'affiche sur le terrain de jeu. Le chiffre 1 est affiché en haut du champ et en bas se trouve une image d'un fragment du jeu. Lorsque vous appuyez sur le bouton SB5 « Start/Pause », vous accédez au menu du jeu, en haut duquel le niveau de jeu est affiché sous forme de chiffres de 1 à 9. Le niveau de jeu est réglé par le SB1 « Up » bouton, à chaque pression, le numéro de niveau augmente séquentiellement par unité. Après le chiffre 9, le chiffre 1 s'affiche à nouveau. La longueur initiale du serpent dépend du niveau défini du jeu, donc pour le 1er niveau la longueur est de 3 points, pour le 9ème niveau elle est de 11 points. Au bas du menu, des informations sur la vitesse de déplacement du serpent sont affichées. Le numéro 1 correspond à la vitesse minimale et le numéro 9 correspond au maximum. La valeur de la vitesse est définie par le bouton SB4 « Down », similaire au réglage du niveau de jeu. La lueur des LED autour du périmètre du terrain dans le menu signifie que le mode de jeu avec présence de limites autour du périmètre du terrain est sélectionné. Dans ce mode, lorsque le serpent quitte le terrain de jeu, une perte se produit. Si dans le menu les LED autour du périmètre du champ sont éteintes, alors le mode sans limites est sélectionné. Dans ce cas, en quittant le terrain de jeu, la tête du serpent apparaît du côté opposé du terrain. Utilisez les boutons SB2 « Droite » et SB3 « Gauche » pour définir le mode de jeu requis. Lorsque vous entrez pour la première fois dans le menu du jeu, les valeurs de longueur et de vitesse sont définies sur un et le mode avec limites est sélectionné.

Après avoir appuyé sur le bouton « Démarrer/Pause » dans le menu du jeu, un serpent dans sa position de base et un point libre aléatoire s'affichent sur le terrain de jeu. En appuyant sur l'un des boutons « Haut », « Gauche », « Droite », le serpent se déplace dans la direction correspondante. Une fois le mouvement commencé, le bouton « Down » devient également disponible pour contrôler le serpent. En frappant un point lumineux, la longueur du serpent augmente. Après avoir collecté 14 points, vous passez au niveau suivant du jeu. Après le 9ème niveau, il y a une transition vers le premier niveau. Si le serpent heurte son propre corps ou dépasse le terrain de jeu en mode frontière, une perte se produit. Après 3 défaites, vous revenez au menu du jeu, où sont indiqués le niveau de jeu et la vitesse actuels. Une fois que le serpent commence à bouger, vous pouvez mettre en pause et reprendre le jeu en appuyant sur les boutons « Démarrer/Pause ».

Pour quitter le menu du jeu, vous devez maintenir enfoncé le bouton « Démarrer/Pause » pendant 1 seconde, après quoi l'écran de démarrage du jeu apparaîtra sur le terrain de jeu. La commutation entre les jeux se fait en appuyant sur l'un des boutons « Haut », « Bas », « Gauche », « Droite ». En même temps, l'écran de démarrage du jeu correspondant s'affiche.

En haut de l'économiseur d'écran du jeu Tetris, le chiffre 2 est affiché, en bas se trouve l'image d'un fragment du jeu. Accédez au menu du jeu en appuyant sur le bouton « Démarrer/Pause ». Le nombre de points marqués par le joueur est affiché en haut du menu. Des points sont attribués pour chaque ligne supprimée. Le compteur de points compte jusqu'à 99, puis se remet à zéro et recommence. Au début de chaque nouvelle partie, le compteur est également remis à zéro. Au bas du menu, des informations sur la vitesse de déplacement des personnages sont affichées, qui sont définies respectivement à l'aide des boutons « Haut » et « Bas ». Après avoir appuyé sur le bouton « Démarrer/Pause » du menu, le jeu commence, des figures aléatoires apparaissent en haut du champ, qui peuvent être déplacées avec les boutons « Gauche » et « Droite » dans la direction appropriée. Le bouton Haut fait pivoter la forme de 90 degrés dans le sens des aiguilles d'une montre à chaque pression. En maintenant enfoncé le bouton Bas, vous pouvez accélérer le mouvement de la figurine. Le bouton « Démarrer/Pause » vous permet de mettre en pause et de reprendre le jeu. Le jeu se termine lorsque la nouvelle figurine ne peut pas tenir sur le terrain de jeu, après quoi elle passe au menu où vous pouvez voir le nombre de points que le joueur a marqués. La sortie du menu s'effectue de la même manière que dans le jeu « Snake ».

Si aucun bouton n'est enfoncé dans les 4 minutes, l'appareil passe en mode basse consommation, le microcontrôleur éteint les réseaux de LED et passe en mode veille. L'appareil « se réveille » après avoir appuyé sur le bouton « Démarrer » et revient à son état précédent.

L'appareil utilise des résistances de taille 1206 pour le montage en surface. Les condensateurs C2, C3 sont en céramique de taille 1206. Les matrices LED H1, H2 sont de couleur verte TOM-1088BG-B avec un diamètre de LED de 3 mm et une résolution de 8x8 pixels. Les boutons sont tactiles standards.

La source d'alimentation est une alimentation stabilisée avec une tension de 3,7-5V, vous pouvez également utiliser des piles ou des piles galvaniques, par exemple 3 piles 1,5V AA ou AAA connectées en série, par exemple j'utilise 3 piles AA. L'appareil reste opérationnel lorsque la tension d'alimentation est réduite à 3,3 V, tandis que la luminosité des matrices LED diminue.

INTRODUCTION. Microcontrôleurs, leur origine et leur application
Contexte des microcontrôleurs
Electronique de style grec
Pourquoi AVR ?
Et après?

PARTIE I. PRINCIPES GÉNÉRAUX DE CONCEPTION ET DE FONCTIONNEMENT D'ATMEL AVR

Chapitre 1. Présentation des microcontrôleurs Atmel AVR

Familles AVR
Caractéristiques d'utilisation pratique de l'AVR MK

Chapitre 2. Structure générale, organisation mémoire, synchronisation, réinitialisation

Mémoire de programme
Mémoire de données (RAM, SRAM)
Mémoire de données non volatile (EEPROM)
Méthodes d'horloge
Réinitialiser
Caractéristiques de connexion d'une mémoire de données externe supplémentaire

Chapitre 3 : Introduction aux périphériques

Ports d'E/S
Minuteries-compteurs
Convertisseur analogique-numérique
Ports série
UART
Interface SPI
Interface TWI (12C)
Interface série universelle USI

Chapitre 4. Interruptions et modes d'économie d'énergie

Interruptions
Types d'interruptions
Modes d'économie d'énergie
Consommation de MK AVR
Consommation AYR MK et modes d'économie d'énergie

DEUXIEME PARTIE. PROGRAMMATION DES MICROCONTRÔLEURS ATMEL AVR

Chapitre 5. Principes généraux de programmation des MCU de la famille AVR

Assemblage ou C ?
Méthodes et outils de programmation AVR
Éditeur de codes
À propos de AVR Studio
Disposition de l'assembleur
Programmeurs
À propos des fichiers hexadécimaux
Commandes, instructions et notation de l'assembleur AVR
Nombres et expressions
Directives et fonctions
Structure générale d'un programme AVR
Gestion des interruptions
RÉINITIALISER
Le programme le plus simple
Retard
Programme de compteur
Utiliser les interruptions
Temporisation
Programme de compteur utilisant des interruptions
À propos des bits de configuration

Chapitre 6. Système de commande AVR

Instructions de transfert de contrôle et registre SREG
Commandes de vérification et de saut
Commandes d'opération logique
Instructions de décalage et opérations sur bits
Instructions arithmétiques
Commandes de transfert de données
Commandes de contrôle du système
Exécution de procédures standard en assembleur
À propos de la pile, des variables locales et globales

Chapitre 7. Opérations arithmétiques

Opérations arithmétiques standard
Multiplier des nombres à plusieurs chiffres
Division de nombres à plusieurs chiffres
Opérations avec des nombres fractionnaires
Générateur de nombres aléatoires
Opérations avec des nombres au format BCD
Nombres négatifs en MK

Chapitre 8. Programmation des minuteries

Minuteries 8 et 16 bits
Formation d'une valeur de fréquence donnée
Compte à rebours
Correction précise de l'heure
Fréquencemètre et périodemètre
Fréquencemètre
Périodomètre
Contrôle d'affichage dynamique
Indicateurs LED et leur connexion
Programmation de l'affichage dynamique
Minuteries en mode PWM

Chapitre 9. Utilisation de l'EEPROM

Encore une fois sur la sécurité des données dans l'EEPROM
Écrire et lire l'EEPROM
Stockage des constantes dans l'EEPROM

Chapitre 10. Comparateur analogique et CAN

Opérations analogiques-numériques et leurs erreurs
Travailler avec un comparateur analogique
Intégration de l'ADC sur le comparateur
Principe de fonctionnement et formules de calcul
Intégration du programme ADC
CAN intégré
Exemple d'utilisation de l'ADC
Programme

Chapitre 11 : Programmation SPI

Opérations de base via SPI
Options matérielles
Options logicielles
À propos des types de mémoire non volatile
Écrire et lire la mémoire flash via SPI
Programme d'échange avec mémoire 45DB011B via SPI
Écrire et lire des cartes flash
Connecter des cartes MMS
Soumission des commandes et initialisation de MMC
Écrire et lire des MMS

Chapitre 12. Interface TWI (12C) et son utilisation pratique

Protocole 12C de base
Émulation logicielle du protocole 12C
Écriture de données sur une mémoire non volatile externe
Modes d'échange avec la mémoire AT24
Programme
Horloge avec interface 12C
Enregistrement des données
Lecture de données

Chapitre 13. Programmation UART/USART

Initialisation UART
Transmission et réception de données
Exemple de réglage de l'horloge DS1307 à l'aide d'UART
Techniques de protection contre les pannes de communication
Contrôle de parité
Comment organiser un échange correct
Fonctionnalités USART supplémentaires
Implémentation des interfaces RS-232 et RS-485
Convertisseurs de niveau pour RS-232
RS-485

Chapitre 14. Modes d'économie d'énergie et minuterie de surveillance

Programmation du mode d'économie d'énergie
Exemple d'appareil alimenté par batterie
Finalisation du programme
Utiliser une minuterie de surveillance

APPLICATIONS

Annexe 1. Paramètres de base des microcontrôleurs Atmel AVR

Annexe 2. Commandes Atmel AVR
Instructions arithmétiques et logiques
Instructions d'utilisation des bits
Commandes de comparaison
Commandes de transfert de contrôle
Commandes de saut inconditionnel et d'appel de sous-programme
Instructions de vérification/saut et instructions de branchement conditionnel
Commandes de transfert de données
Commandes de contrôle du système

Annexe 3. Textes du programme
Programme de démonstration pour l'échange de données avec la mémoire flash 45DB011B via l'interface SPI
Procédures d'échange via l'interface 12C

Annexe 4. Échange de données avec un ordinateur personnel et débogage du programme via UART
Travailler avec le port COM dans Delphi
Port COM et API Windows
Travailler avec COM via des composants prêts à l'emploi
Installation d'une ligne RTS sous DOS et Windows
Programme COM2000
Débogage de programmes à l'aide d'un programme de terminal

Annexe 5. Glossaire des abréviations et termes courants
Correspondance des termes en russe avec leur traduction en anglais
Correspondance des termes en anglais avec leur traduction en russe

Littérature
Index des sujets

Bonsoir à tous! J'émets depuis un monde cosy appelé « assembleur ». Je précise immédiatement que le sujet concerne les microcontrôleurs AVR - et je ne sais pas encore si cet article sera utile à ceux qui souhaitent utiliser l'assembleur pour toute autre tâche. Le fait est qu'il y a littéralement quelques jours, j'ai commencé à apprendre l'assembleur à partir de zéro - je dois créer un appareil - et j'ai décidé de tout faire moi-même. Alors, un beau jour, j'ai réalisé que Apprendre l'assembleur ne sert absolument à rien ! Le langage d'assemblage ne peut être compris que ! Autrement dit, à tous ceux qui souhaitent programmer en langage assembleur, je vous recommande fortement d'approfondir en détail le fonctionnement PHYSIQUEMENT du microcontrôleur, puis d'étudier les subtilités des commandes.
Alors, je vais probablement commencer une petite série d’articles dans lesquels je vous raconterai dès le début de quelle façon précisément J'ai compris certaines choses dans la programmation en langage assembleur - je pense que pour ceux qui ne comprennent pas du tout ce qu'est l'ASM, je serai juste un tel "traducteur" du langage de ceux qui sont très bons dans ce domaine.

Je dirai tout de suite que je suis plus ou moins entré dans ce sujet à l'instigation de DIHALT - ces articles seront donc une sorte de traduction d'un langage d'assemblage-microcontrôleur super-duper vers un langage compréhensible pour la plupart des gens. Eh bien, j'espère que les gourous me corrigeront au fur et à mesure que la pièce progresse, et si soudainement j'explique quelque chose de manière incorrecte, ils me corrigeront.
Ainsi, les premières conclusions sur l'assembleur que j'ai faites il y a quelques jours m'ont profondément choqué - et je suis resté assis à lire les articles de DI HALT de 23 heures à 5 heures du matin - après quoi je me suis couché satisfait et heureux. J'ai compris l'essence de Programmation en langage assembleur pour microcontrôleurs.
Comment expliquer cela encore plus simplement ? Je pense qu'il faut partir de l'essence même.
***
Dans un premier temps, nous n'entrerons pas dans les détails techniques (nous en parlerons dans le prochain article) - juste imaginez qu'il y ait 3 personnages:
1. Microcontrôleur - Il s'agit de l'Anglais Steve, venu chez le Russe. Il connaît parfaitement l’anglais, mais il ne comprend pas du tout le russe – pas un seul mot. Que l'anglais. Il a perdu la discussion et s’est engagé à faire tout ce que le Russe lui demanderait de faire sans poser de questions.
2. Assembleur - Il s'agit du traducteur Vasya, dont la mère est anglaise et le père russe. Il connaît parfaitement l'anglais et le russe.
3.Nous - C'est un Russe chez qui un Anglais est venu. Eh bien, c'est-à-dire que nous sommes nous =) En même temps, nous connaissons parfaitement le russe et (!!!) un peu l'anglais - juste un peu, avec un dictionnaire.
***
Imaginez cette situation : un Anglais est assis sur une chaise dans votre chambre. Et vous êtes assis devant votre ordinateur et lisez cet article, quand soudain votre fenêtre s’est ouverte ! C'est de la malchance! Le vent souffle, le rideau s'est transformé en voile... Ce serait bien de le fermer ! Mais c'est trop paresseux pour se lever de sa chaise, retirer ses pieds de l'unité centrale, les enfiler dans des pantoufles, poser sa tasse de café (bière) et aller combattre les éléments. Et puis on se rend compte soudain qu’on a un Anglais dans la salle qui a perdu son pari et qu’il est temps de le poursuivre ! Et tu lui dis si gentiment : « Mec ! S'il vous plaît, fermez la fenêtre, et vous pourrez ensuite vous asseoir à nouveau sur la chaise ! et il s'assoit, vous regarde avec perplexité et ne fait rien ! Vous pouvez, bien sûr, manger de la soupe aux choux - mais il ne vous comprendra toujours pas ! Ensuite, vous appelez votre ami traducteur Vasily - il vient et s'assoit à côté de l'Anglais sur une chaise. Et vous dites - Traduisez : « Steve, va fermer la fenêtre, puis assieds-toi sur la chaise ! » Le traducteur traduit vers l'anglais - l'Anglais comprend et va fermer la fenêtre, puis vient s'asseoir sur une chaise.
Il suffit à ce stade de comprendre le rôle de l’assembleur dans cette chaîne « Nous-Assembleur-Contrôleur ».
Autrement dit, comment tout le monde comprendrait-il ce qu'est l'assembleur ? Alors lisez la suite.
***

Alors imaginons cette situation. Vous dites à Vasya - "Écoutez, eh bien, en bref, c'est le cas - j'ai oublié la calculatrice à la maison, divisez 56983 par 2 et dites à Steve de faire autant de pompes avec vos poings" et Vasya compte sur la calculatrice et dit à Steve en anglais "Faites des pompes avec vos poings 28491 fois" Cela s'appelle "DIRECTIF"- en d'autres termes, une directive est une tâche pour Vasya, dont le résultat est l'action de Steve.

Il existe une autre situation : vous dites à Vasya « Dites à Steve de faire 28 491 pompes » et Vasya traduit simplement vos mots en anglais. On l'appelle OPÉRATEUR

C'est simple : il y a une directive et il y a un opérateur. L'opérateur vous donne des instructions directes à Steve sur ce qu'il doit faire - Vasya traduit ici uniquement votre demande en anglais. Et la Directive est une tâche pour Vasya lui-même - et Vasya fait d'abord ce que vous lui avez dit, puis, en fonction du résultat, il dit quelque chose à Steve.

Désormais, nous allons torturer régulièrement l'Anglais ! Mais nous devons d’abord mieux connaître notre traducteur Vasya. Vous devez savoir ce qui suit - Vasya vous obéit toujours sans aucun doute - ce qu'on lui a dit, il le fait. La calculatrice de Vasya n'a pas de décimales - si vous regardez l'exemple avec des pompes, alors 56983 \ 2 = 28491,5 - mais tout ce qui suit Vasya après la virgule décimale est coupé - et il ne voit qu'un entier - et cela n'a pas d'importance qu'il y ait 28491.000001 ou 28491.9999999 - pour Vasya, c'est une grosse affaire, ce sera 28491 dans les deux cas. Rien n'est arrondi. Informations plus importantes sur Vasya. Vasya est cruel - il ne se soucie pas du fait que Steve fasse des pompes vingt-huit mille fois. Ils lui ont dit que Vasya traduisait. Et non seulement il a traduit, mais il m'a aussi forcé à faire ce que vous m'aviez demandé. Donc si Steve meurt à la vingt-trois mille cinq cent treizième pompes, ce sera entièrement de votre faute.

En fait, c'est tout pour le moment. Dans le prochain article, nous approfondirons la question – pour l’instant, il suffit de comprendre cela. Imaginez simplement cette situation et comprenez quoi, qui joue quel rôle et en quoi la directive diffère de l’opérateur.
Et puis nous essaierons d'appeler tout par son nom propre et d'estimer grossièrement comment l'assembleur fonctionne avec un microcontrôleur comme un adulte.

Avez-vous aimé l'article? Partager avec des amis: