Tutoriel d’assembleur AVR 10 (9 / 10 étapes)

Étape 9: Comment fonctionne l’interruption TWI ?

Vous devez tout d’abord allez à l’étape suivante et télécharger le code final et Assemblez-la afin que vous pouvez l’utiliser dans cette étape (j’aimerais garder le code final et la vidéo dans la dernière étape pour ceux qui veulent juste sauter tous mon babillage et il suffit d’exécuter le code.)

La DHT est déroutant au début, parce que cela fonctionne différemment des autres interruptions. Habituellement lorsqu’une interruption se produit et le gestionnaire d’interruption correspondant est exécuté, l’I drapeau dans SREG automatiquement figure à 0 alors que globales interruptions sont désactivées, puis quand le le « RETI » est exécutée pour retourner à partir de l’interruption, le drapeau en SREG I figure automatiquement à 1 à nouveau pour réactiver les interruptions globales et aussi le drapeau de chaque interruption correspondant à l’interruption (i.e. le bit dans le registre de contrôle pour cette interruption) est désactivé afin que le nouveau système répond à ce type d’interruption (Voir l’État Registre description à la page 11). Si nous a permis d’interruptions de demeurer à l’intérieur d’une interruption, nous obtiendrions « interruptions imbriquées ». Vous pouvez le faire par réellement la réactivation à l’intérieur de votre routine d’interruption, mais vous ne voulez pas normalement de le faire depuis un autre appel à la même interruption serait alors vous éjecter de l’interruption qu’aux entrez-le de nouveau dans la partie supérieure.

Exercice 3: Essayez-le ! Allumez des interruptions mondiales au début de votre routine de TWI, puis quelque part dans l’ensemble la TWIE bit dans le registre de Confirm et voir ce qui se passe la prochaine fois que l’indicateur TWINT est défini.

Cependant, ce n'est pas comment fonctionne l’interruption TWI ! TWINT est le drapeau de l’interruption. À la DHT, il ne reste pas fixée pendant le gestionnaire d’interruption, il change tout le temps. C’est parce que la DHT a besoin d’utiliser l’indicateur d’interruption pour communiquer. Si nous ne pouvons pas simplement le laisser sur. Au lieu de cela, nous désactivons interruptions à l’aide de TWIE = 0 alors que le CPU ne nous éjecte vers le vecteur d’interruption lorsque TWINT change à un 1. En tout cas, cela peut encore sembler déroutant donc nous allons en discuter dans le cadre de notre code. Quelle est exactement TWINT = 1 et quelle est TWINT = 0 dans notre routine de TWI ?

Nous allons le comprendre.

Au lieu de sauter en arrière dans la feuille de données pour comprendre ce qui se passe. Nous allons utiliser notre rouleau de dés et afficher. Alors nous serons absolument clairs de quels bits sont définis et quand.

Commencez par ajouter la définition suivante en haut de votre code de rouleau de dés :

.def test = r23

Maintenant, allez vers le bas à la routine de tw_transmit et située en haut de celui-ci, lorsque le PC passe tout d’abord la sous-routine, mettre la ligne suivante

LDS test, SREG

Enfin, descendez les deux endroits dans le code où nous transmettre les données à l’écran. L’autre où nous transmettons l’octet de poids faible, remplacer le dicetotal par épreuve. Maintenant quand on pousse le bouton, le contenu du Registre SREG, lorsque nous sommes entrés tout d’abord la sous-routine, sera envoyé à l’écran.

Maintenant, quand nous assembler ceci et l’exécuter, nous trouvons qu’un 0000 apparaît sur l’écran. Cela signifie que le drapeau de SREG j’est désactivé comme il convient, car nous ne permettait pas d’interruptions globales dans nos rouleaux de dés.

Maintenant changez le code donc ce critère charge Confirm au lieu de SREG et afficher le contenu de Confirm.

Nous trouvons cela et que le TWEN drapeau est le seul sur Confirm. Ce qui signifie que la DHT est activé comme il devrait également être puisque nous utilisons la DHT.

Maintenant passons passer notre ligne de test vers un autre emplacement. Déplacez-le vers le bas pour juste après que nous avons mis la Confirm pour la première fois. C’est quand nous envoyons la condition de départ. Le résultat est un 36 sur notre écran. Cela signifie que Confirm est 0b00100100.

CONFIRM = (TWEA, TWSTA, TWSTO, TWWC, TWINT, TWEN, -, TWIE) = (0,0,1,0,0,1,0,0)

Si le bit TWSTA est sur comme il se doit car nous viens de charger la condition de départ, et le TWEN est sur comme il convient également. Mais regardez ! Dans la ligne précédente, nous avons chargé TWINT = 1 dans le registre Confirm et quand nous avons immédiatement copié le registre et ont jugé qu’il nous trouve que TWINT est 0 ! Pourquoi est-ce ? Vous verrez que "paramètre TWINT = 1" fait quelque chose de différent que simplement définissant ce bit dans Confirm égal à un. Si vous regardez sur le bas de la page 17, où ils décrivent transmettant une condition de départ, vous verrez ce qu’ils disent, « TWINT doit être écrit dans 1 pour effacer l’indicateur TWINT »... Donc ce qui se passe réellement ici est lorsque vous écrivez un 1 à TWINT il définit la valeur de TWINT égal à zéro ! C’est parce que TWINT les deux * contrôles * la TWINT du pavillon et * est * l’indicateur TWINT. Il dit ensuite que la DHT va tester le bus série 2 fils et générer une condition de départ dès que le bus est gratuit. Puis, après qu’une condition de départ a été transmise, l’indicateur TWINT est définie par le matériel. Cela signifie que TWINT va devenir 1 quand c’est terminé. Nous savons déjà que c’est le cas, car notre ligne très prochaine est une sous-routine tw_wait qui juste maintient stable TWINT jusqu'à ce qu’il devient 1 lit ensuite le registre d’État. Le fait que l’envoi de 1 à TWINT seulement qu’elle soit définie sur 0 est la source de beaucoup de confusion pour les gens qui essaient de comprendre comment fonctionne le protocole I2C. La clé est de réaliser que la Confirm est un « contrôle » actif s’inscrire ainsi que d’un tas d’interrupteurs à bascule. Envoi de 1 à TWINT efface l’indicateur d’interruption et de cet indicateur se trouve être le même TWINT bit dans le registre Confirm si le résultat est TWINT = 0.

Maintenant passons changent notre variable de test afin qu’il copie le registre d’État TWSR au lieu de cela. Ne déplacez pas l’emplacement tout de suite. Il suffit d’exécuter ce qu’est et ce qui est dans le registre d’État immédiatement quand nous disons la Confirm pour transmettre une condition de départ, mais avant que cette condition a été transmise.

Je reçois 251. En binaire, il s’agit de 0b11111011. Dit de la feuille de données, dans la rubrique 22.5.5 p. 213, que le TWSR s’inscrire seulement renseigne voyants correspondants lorsque l’indicateur TWINT est défini (Rappelez-vous lorsque nous parlons « drapeaux » puis les mots signifie « flag is set » TWINT = 1, lorsque nous parlons de « contrôler les interruptions » alors les mots « définir l’indicateur » signifierait écrit un 0 au TWINT, ayant pour résultat TWINT = 1... bizarre mais c’est la façon dont ses œuvres). Car nous lisons TWSR lorsque TWINT = 0, c'est-à-dire l’interruption est éteint et TWI est occupé, cela signifie qu’il ne doit pas contenir d’informations voyants correspondants, au lieu de cela, l’article poursuit en disant qu’il devrait contenir « un statut spécial code indiquant qu’aucune information pertinente n’est disponible ». Eh bien. Je suppose que nous savons maintenant ce qui est le « code de statut spécial ». C’est 248. En d’autres termes, tous les bits sont définis sauf les 3 que nous masquons habituellement. Maintenant est une question que vous pourriez demander: « qu’en est-il le Prédiviseur bits TWSR, affectent-ils ce code d’état spécial? » n’oubliez pas que nous masquons les quand on veut lire les codes d’État, donc si la DHT est il suffit de lire la TWSR vers le haut ne serait pas il montrer ces bits diviseur ? Eh bien, remonter vers le haut et définir les bits diviseur à une valeur différente. Vous trouverez que si nous les deux bits diviseur partit (afin que la valeur du diviseur est maintenant 1 et SCL cadencé à une fréquence plus élevée!) et exécutez-le nous obtenons 248, qui est 0b11111000, si nous avons mis seulement TWPS0 à 1 et exécutez-le à nouveau (cette fois precaler serait 4) vous trouverez qu’il lit maintenant 249. Si vous définissez uniquement TWPS1 à 1 (le Prédiviseur est donc maintenant 16) vous obtiendrez 250 et avec les deux ensemble comme nous l’avons normalement nous l’avons vu, vous obtenez 251. Donc nous voyons que la véritable « code de statut spécial » est 248, ce qui signifie que tous les bits de la partie de « statut » de TWSR ont la valeur 1 et les 3 autres bits restent tels qu’ils étaient.

Maintenant, déplacez le « lds test, TWSR » commande après que nous attendons pour l’interruption (c'est-à-dire après TWINT = 1).

Quand on pousse le bouton nous voyons Voir la 0011 vers le haut sur l’écran, c'est-à-dire le nombre décimal 11. Que signifie le code d’État 11 ? Eh bien, rappelons que les deux derniers bits du Registre TWSR sont nos parcelles diviseur qui, dans notre cas, sont les deux 1. Il faut se débarrasser de ceux (Rappelez-vous comment nous masquons lorsqu’on veut vérifier l’État?) laisse ainsi soustraire 3 de notre résultat (3 est ce que ces deux bits donner lors de la conversion en décimal). Si le statut est en fait 8, ou 0 x 08 en hexadécimal. Qui est exactement ce que nous attendons.

Maintenant, placez la ligne de test vers le bas au-dessous du point où nous entrons dans l’adresse de l’esclave dans le registre TWDR. Vous trouverez qu’il lit encore 11. Il reste donc 11 jusqu'à ce que nous faisons réellement quelque chose d’autre avec la DHT. Dicking autour avec les autres registres comme TWDR n’affecte pas le registre d’État. Il ne change que lorsque la DHT est active.

Maintenant déplacer ci-dessous la prochaine fois que nous charger le registre de contrôle et vous trouverez qu’il devient le « statut spécial » à nouveau... vous obtenez l’image.

Comme un dernier test, passez à la section où nous envoyer le dicetotal à l’écran et ajouter les 3 lignes suivantes au début de cet article :

LDI 0b00000100 temp,
STS Confirm, temp
LDS test, Confirm

Vous voyez ce que cela fait. Il garde le TWEN sur afin que la DHT reste activée, mais maintenant nous écrire TWINT = 0 dans le registre de contrôle. Ensuite, nous lisons que la valeur de Registre contrôle. Qu’obtient-on ? Nous obtenons 132 apparaître sur l’écran ! En binaire, il s’agit de 0b10000100. En d’autres termes, le bit TWEN est activé comme nous l’avons mis, mais maintenant le bit TWINT est ON. Nous avons envoyé TWINT = 0 au contrôle Registre et le résultat est TWINT = 1. Vous voyez maintenant pourquoi il y a droit ? Envoi de TWINT = 0 au contrôle Registre définit l’indicateur de l’interruption. Donc le résultat est l’interruption indicateur est activé, c’est un 1.

Très bien. Maintenant, nous savons ce qui se passe dans le rouleau de dés avec le bit TWINT du Registre Confirm. La partie seulement pouvant prêter à confusion était quand nous avons mis en TWINT = 1 et puis ne lire que pour trouver sa valeur est 0 et quand nous avons mis TWINT = 0, nous avons constaté que sa valeur est 1. Je pense que vous voir maintenant pourquoi il s’agit et comment il fonctionne. Affectant des valeurs à la Confirm est le même que l’envoi des commandes à la DHT. Le TWINT = 1 commande signifie « dans la Confirm, exécutez la commande », mais la valeur get définie dans le TWINT bit lorsque cette commande est exécutée est le « clear le drapeau interrupt » qui signifie « démarrer la DHT et envoyer des données ». En ce qui concerne l’indicateur d’interruption (la valeur réelle dans le bit) concernés, TWINT = 0 signifie interrupt flag est désactivé, la DHT est occupée à faire quelque chose. Quand TWINT remonte à 1, cela signifie l’interruption indicateur est défini, et vous pouvez maintenant modifier les choses à nouveau. En revanche, dans la mesure où les * commandes * vous envoyez à la Confirm, écrit TWINT = 0 * jeux * le drapeau de l’interruption et les résultats dans TWINT = 1, et le TWI s’éteint vous permettant de modifier le registre de données. J’ai battu le cheval mort assez longtemps ? Je le fais seulement parce que c’est aussi confus que f... bien. vous voyez l’idée. Si vous êtes encore confus tout simplement jouer avec elle pendant un certain temps.

Maintenant examiner Figure 22-10, qui montre les choses qui se passe pendant une transmission typique. Maintenant que nous comprenons comment TWINT fonctionne ce sont claire la valeur réellement dans ce petit à tout moment pendant la transmission. Dans le blanc des sections TWINT = 0 et dans le noir les articles TWINT = 1. Chaque fois que la description dit « veiller à ce que TWINT est écrit dans un » vous savez maintenant que cela se traduit par TWINT = 0, c'est-à-dire l’interruption drapeau est éteint ou position « débranché ». La déclaration citée ci-dessus tout en vous assurant que TWINT est écrit à l’un doit être la source de rien d’autre que la confusion aux gens lorsqu’ils essaient de comprendre comment fonctionne la DHT. Il est regrettable que les rédacteurs de la feuille de données n’a pas pris le temps de vraiment expliquer ce qui se passe. Autres drapeaux d’interruption au AVR fonctionne de la même façon, par exemple l’indicateur de débordement Timer/Compteur qui nous avons traité dans les tutoriels précédents. Écrit un 1 au bit TOV0 de la TIFR0 Timer/Counter0 interrompre drapeau s’inscrire aussi * efface * le drapeau et donc se traduit par une logique que le bit 0. Cependant dans le cas des autres drapeaux d’interruption que ne faut habituellement pour définir et faire disparaître avec le logiciel, le matériel prend en charge cela. C’est seulement parce que dans le cas de la DHT nous devons activer et désactiver l’indicateur à l’intérieur de la routine d’interruption réelle dont nous avons besoin de s’inquiéter à ce sujet et il existe la possibilité de confusion.

Nous allons maintenant restaurer notre code de rouleau dés à la façon dont il a été et passer à notre affichage à 4 chiffres.

Dans le code de 4 chiffres-écran Ajouter un nouveau registre d’usage général appelé « test » comme nous l’avons fait avec le rouleau de dés. Puis dans notre gestionnaire d’interruption tw_int, ajoutez les deux lignes suivantes au début de notre label de tw_return, c’est à dire à la fin, juste avant que vous retournez à la principale :

LDI playercashH, 0
playercashL MOV, test

pour que l’écran affiche tout ce qui est dans le registre de test. Maintenant permet de tester certaines choses.

Première nous allons tester SREG dans divers endroits dans le gestionnaire d’interruption. Mettre « lds test, SREG » à droite en haut lorsque l’interruption est d’abord appelée. Vous trouverez qu’il indique 0. Cela signifie que le drapeau « je » est automatiquement désactivé lorsque nous entrons dans le gestionnaire d’interruption. Vous trouverez également qu’il reste éteint pendant l’interruption complète. C’est la façon normale qui SREG se comporte.

Maintenant nous allons tester TWSR. Voici où nous trouvons quelque chose qui peut sembler étrange. Si nous le tester juste après que l’interruption est appelée nous obtenons 96 apparaître. Pourquoi est-ce ? Eh bien, vous vous souviendrez que les codes d’État TWSR sont en hexadécimal. Si vous convertissez 96 en hexadécimal, vous trouverez que c’est 60. Qui est la valeur que nous devrions obtenir lorsque l’interruption est d’abord appelée.

Exercice 4: Quel est le « code de statut spécial » utilisé dans le récepteur slave ?

Lorsque vous entrez tout d’abord l’interruption, regardez maintenant le registre TWDR. Vous trouverez qu’il est égal à l’adresse que nous avons mis en place pour l’esclave, comme il se doit depuis la lecture de que l’adresse de la DHT dans le registre de données est comment nous savions que nous étions appelés.

Enfin, regardons Confirm et le TWINT bit. Si vous mettez « lds test, Confirm » dès le début, lorsque le gestionnaire est inscrit tout d’abord vous téléchargez 197 qui est 0b11000101. Cela signifie que TWINT = 1, TWEA = 1, TWEN = 1 et TWIE = 1. C’est exactement comment nous avons mis les choses vers le haut dans notre section de remise à zéro du programme (aller chercher, voir?) sauf que maintenant le drapeau d’interruption TWINT est activée. Qui est aussi normal étant donné que nous avons vient d’entrer dans l’interruption, nous ne serions ici si quelque chose n’a pas indiqué ce drapeau.

Maintenant, allez vers le haut de votre programme à la section réinitialisation et ajoutez les deux lignes suivantes :

LDI temp, 0
m TWDR, temp

comme si nous allions à initialiser notre registre de données TWDR à zéro. Que se passe-t-il maintenant lorsque vous vérifiez le registre Confirm au début de l’interruption ? Vous obtenez 205.

Exercice 5: Pourquoi avez-vous 205 ?

Maintenant, vous pourriez aimer tester les valeurs des registres ailleurs dans le code. Je pense que vous constaterez qu’ils sont comme vous l’attendez.

Articles Liés

Tutoriel d’assembleur AVR 11

Tutoriel d’assembleur AVR 11

Bienvenue au didacticiel 11 !Dans ce bref didacticiel, nous allons enfin construire la première partie de notre projet final.La première chose que vous devriez faire est d'aller à la toute dernière étape de ce tutoriel et voir la vidéo. Puis revenez
Tutoriel d’assembleur AVR 1

Tutoriel d’assembleur AVR 1

J'ai décidé d'écrire une série de tutoriels sur la façon d'écrire des programmes de langage d'assemblage pour le Atmega328p qui est le microcontrôleur utilisé dans l'Arduino. Si les gens restent intéressées, je vais continuer à mettre un une semaine
Tutoriel d’assembleur AVR 8

Tutoriel d’assembleur AVR 8

Bienvenue au didacticiel 8 !Dans ce bref didacticiel, nous allons prendre un peu d'une déviation de l'introduction de nouveaux aspects de la programmation en langage assembleur pour montrer comment déplacer nos composants de prototypage pour un circu
Tutoriel d’assembleur AVR 6

Tutoriel d’assembleur AVR 6

Bienvenue au didacticiel 6 !Tutoriel d'aujourd'hui sera un court où nous mettrons au point une méthode simple pour transmettre des données entre un atmega328p et un autre à l'aide de deux ports qui les relient. Nous puis prendre dés rouleau de tutori
Tutoriel d’assembleur AVR 9

Tutoriel d’assembleur AVR 9

Bienvenue au didacticiel 9.Aujourd'hui nous allons montrer comment piloter un afficheur 7 segments, mais aussi un affichage à 4 chiffres à l'aide de notre code en langage assembleur ATmega328P et AVR. Ce faisant cela que nous allons devoir prendre de
Tutoriel d’assembleur AVR 2

Tutoriel d’assembleur AVR 2

Ce tutoriel est une continuation de "tutoriel d'assembleur AVR 1"Si vous n'avez pas passé par 1 tutoriel, vous devez arrêter maintenant et faire celui-là en premier.Dans ce tutoriel, nous allons poursuivre notre étude de programmation en langage
Tutoriel d’assembleur AVR 7

Tutoriel d’assembleur AVR 7

Bienvenue au didacticiel 7 !Aujourd'hui nous allons voir la première comment faire pour nettoyer un clavier et ensuite montrer comment utiliser les ports d'entrée analogiques pour communiquer avec le clavier.Nous ferons cela en utilisant les interrup
Tutoriel d’assembleur AVR 5

Tutoriel d’assembleur AVR 5

Aujourd'hui nous allons regarder de plus près aux divers emplacements mémoire dans le microcontrôleur Atmega328p et voir si nous pouvons mieux comprendre comment les choses sont stockés, où ils sont stockés et comment les pointeurs et les tables de r
Tutoriel d’assembleur AVR 4

Tutoriel d’assembleur AVR 4

Bienvenue au didacticiel numéro 4 !Dans ce tutoriel, nous allons construire un circuit qui simulera l'enroulement des deux dés. Ensuite, nous allons tout d'abord écrire un programme de force brute qui fait le travail. Puis nous permettra de simplifie
Tutoriel d’assembleur AVR 3

Tutoriel d’assembleur AVR 3

Bienvenue au didacticiel numéro 3 !Avant que nous commencions, je tiens à faire un point philosophique. N'ayez pas peur d'expérimenter avec les circuits et le code que nous construisons dans ces tutoriels. Changer les câbles près, ajouter de nouveaux
MRETV - vidéo, stéréo Sound et beaucoup plus d’un Arduino standard !

MRETV - vidéo, stéréo Sound et beaucoup plus d’un Arduino standard !

MRETV - vidéo, stéréo Sound et beaucoup plus d'un Arduino standard !Maintenant mis à jour pour Arduino 1.6.6 novembre 2015 !Utiliser seulement deux résistances et deux diodes pour générer la vidéo plein écran. Texte 47 x 29 de 8 x 8 caractères, doubl
Comment charger des programmes à un Arduino UNO de Atmel Studio 7

Comment charger des programmes à un Arduino UNO de Atmel Studio 7

Dans ce court Instructable, nous allons apprendre à charger un programme à une carte Arduino UNO utilisant Atmel Studio au lieu de l'IDE Arduino. Cela est utile lorsque vous avez besoin élaborer un programme à l'aide de plusieurs fonctions avancées o
Star Trek sonnette Hack

Star Trek sonnette Hack

J'ai toujours été un fan de la Star Treks et comme tel, j'étais très excité lorsque mon colocataire ramené un panneau la comm série style Star Trek original. Je n'avais jamais vu l'un d'entre eux, mais une recherche rapide nous a pris sur le site de
Carte de développement pour microcontrôleurs Attiny84

Carte de développement pour microcontrôleurs Attiny84

Il s'agit d'une carte de développement pour microcontrôleur Attiny84. Tha Attiny84 puce possède 11 broches adressables avec l'IDE Arduino, 8k de mémoire flash pour le stockage de programme et 512 octets de mémoire vive disponible pour les variables d