Tutoriel PIC - Des registres aux interruptions

Essayez Notre Instrument Pour Éliminer Les Problèmes





Avant d'entrer dans les moindres détails de la programmation PIC, il serait d'abord important d'apprendre quelques bonnes méthodes de programmation.

Comprendre les registres

Pour commencer, supposons que vous tapez un (point-virgule) à n'importe quel point du programme, tout ce qui vient après ce point-virgule serait ignoré par le compilateur, jusqu'à ce que bien sûr le chariot revienne en position.



La fonction ci-dessus nous permet d’ajouter des commentaires ou des remarques de sorte qu’ils ne deviennent pas une partie du programme, mais nous permet d’identifier le programme à l’aide des commentaires à côté. Mettre des commentaires est une pratique recommandée lors de la programmation de n'importe quel IC.

La prochaine chose importante dans le cours est d'attribuer des noms aux différentes constantes (vous les apprendrez plus tard de manière élaborée). Cela simplifie également la compréhension de ce qui est écrit ou des valeurs impliquées, au lieu de se confondre avec les nombres inclus.



Ce qui précède doit être fait sous la forme de noms réels pour une reconnaissance instantanée, par exemple COUNT, il serait important de noter qu'ici toutes les lettres majuscules sont utilisées pour le rendre distinct et également indiquer qu'il s'agit d'une valeur constante.


Comme nous pouvons le voir, ce qui précède est fait sous la forme d'une boîte faite de points-virgules, ce qui le rend juste plus propre. Essayez également de documenter le programme sur papier, cette pratique vous aidera à comprendre les choses par étapes.

2. Les registres.

Le registre dans un PIC est une zone qui accepte les détails écrits et permet également de lire à partir de celui-ci. Vous pouvez le comparer à une feuille de papier où vous pouvez visualiser le contenu et l'ajouter en écrivant dessus.

La figure ci-dessous représente une carte de fichier de registre typique intégrée dans un PIC16F84. Le format n'est pas quelque chose qui est réellement défini à l'intérieur du PIC, il s'agit simplement d'indiquer comment les bits peuvent être disposés à l'intérieur de la puce et de comprendre quelques-unes des commandes impliquées.

Vous pouvez voir qu'elle est essentiellement divisée en banque 0 et banque 1. La banque 1 est chargée de contrôler le fonctionnement réel du PIC, par exemple, elle indique au PIC quels bits du port A sont affectés en tant qu'entrées et lesquels sont en tant que sorties.

La banque 2 sert uniquement à manipuler les informations.

Comprenons cela à travers l'exemple suivant:

Supposons que nous souhaitons attribuer un bit à PortA haut. Pour cela, nous devons d'abord aller à la banque 1 pour définir le bit ou la broche spécifié au port A sous la forme d'une sortie. Après cela, nous retournons à la banque 0 et délivrons un 1 logique (bit 1) à cette broche spécifique.

Les registres les plus courants que nous aimerions utiliser dans la banque 1 sont STATUS, TRISA et TRISB.

STATUS nous aide à revenir à la banque 0, TRISA nous permet de choisir quelles broches du port A sont des sorties et lesquelles peuvent être des entrées, tandis que TRISB facilite la sélection entre les broches de sortie et d'entrée sur le port B.Le registre SELECT dans la banque 0 permet à l'utilisateur pour basculer vers la banque 1.

Résumons l'ensemble du concept avec la description suivante:

STATUT:

Pour passer de la banque 0 à la banque 1, nous commandons le registre STATUS. Ceci est implémenté en mettant le bit # 5 du registre STATUS à 1. Pour revenir à la banque 0, nous affectons le bit 5 du registre STATUS à 0. Le registre STATUS est positionné à l'adresse 03h, ici h signifie tat le nombre peut être en hexadécimal.

TRISA et TRISB:

Celles-ci sont situées respectivement aux adresses 85h et 86h. Pour programmer une broche en tant que sortie ou entrée, nous fournissons simplement un zéro ou un un au bit particulier du registre. Maintenant, cela peut être fait de deux manières, via binaire ou Hex. Dans le cas où l'on est incapable de convertir le paramètre, il ou elle peut opter pour une calculatrice scientifique pour mettre en œuvre les valeurs.

Maintenant, nous avons 5 broches au port A, ce qui correspond à 5 broches. Si nous avons l'intention de fixer l'une des broches comme entrées, nous fournissons un «1» au bit particulier.

Au cas où nous voulions attribuer une des broches comme sorties, nous définirions la broche spécifique sur «0». Les bits sont d'aide vers le bas correspondant exactement aux bits, ou plus précisément le bit 0 est RAO, le bit 1 serait RA1, le bit 2 = RA2 et ainsi de suite. Comprenons-le de cette manière:

Supposons que vous souhaitiez fixer RA0, RA3 et RA4 comme sorties, tandis que RA1 / RA2 comme i / ps, vous le feriez en envoyant 00110 (06h). Vérifiez que le bit 0 est vers la droite comme indiqué ici:

Port A Broche RA4 RA3 RA2 RA1 RA0

Numéro de bit 4 3 2 1 0

Binaire 0 0 1 1 0

Il en va de même pour TRISB.

PORTA et PORTB

Afin de rendre l'une des broches de sortie haute, nous proposons simplement un bit «1» à thr respectif dans notre registre PORTA ou PORTB. Une procédure identique peut également être suivie pour les registres TRISA et TRISB.Avant de passer à notre premier exemple de codage, comprenons simplement une coupe de plusieurs registres, à savoir: w et f.

W et F

Le registre W est un registre ordinaire qui vous permet d'attribuer n'importe quelle valeur de votre choix. Dès que vous attribuez une grandeur à W, vous pouvez procéder en l'ajoutant à une autre valeur ou simplement la déplacer. Avec une autre valeur attribuée, les détails sont simplement écrasés sur W.

Le registre F transmet sa matière écrite à un registre. Nous aurions besoin de ce registre F pour attribuer une valeur sur un registre, peut-être sur les registres STATUS ou TRISA, car ils ne nous permettront pas de placer les valeurs directement sur eux. Un exemple de programme

Examinons l'exemple de code suivant qui nous montrera comment l'instruction ci-dessus est implémentée et qui témoignera également de quelques-unes des instructions du cours.

Commençons par corriger le port A comme indiqué ci-dessus.

Pour cela, nous devons passer de la banque 0 à la banque1, cela se fait en configurant le registre STATUS situé à l'adresse 03h, bit 5 à 1.

BSF 03h, 5

Le BSF signifie l'ensemble de bits F. Nous utilisons deux nombres après cette instruction - 03h, qui est l'adresse du registre STATUS, et le nombre 5 qui correspond au numéro de bit.

Donc, ce que nous disons est «Mettre le bit 5 de l'adresse 03h à 1».

Nous sommes maintenant dans la banque 1.

MOVLW 00110b

Nous mettons la valeur binaire 00110 (la lettre b signifie que le nombre est en binaire) dans notre registre à usage général W.J'aurais bien sûr pu le faire en hexadécimal, auquel cas notre instruction serait:

MOVLW 06h

L'un ou l'autre fonctionne. Le MOVLW signifie «Move Literal Value Into W», ce qui signifie en anglais mettre la valeur qui suit directement dans le registre W.

Nous devons maintenant mettre cette valeur dans notre registre TRISA pour configurer le port:

MOVWF 85h

Cette instruction indique «Déplacer le contenu de W dans l'adresse de registre qui suit», dans ce cas l'adresse fait référence à TRISA.

Notre registre TRISA à ce stade porte le chiffre 00110, ou est présenté graphiquement:

Port A Broche RA4 RA3 RA2 RA1 RA0

Binaire 0 0 1 1 0

Entrée / sortie O O I I O

Alors maintenant que nous possédons nos broches de port A, nous devons retourner à la banque 0 pour ajuster l'une des informations.

BCF 03h, 5

Cette instruction accomplit l'inverse de BSF. Cela implique «Bit Clear F». La paire de nombres qui correspondent sont l'adresse du registre, ici le registre STATUS, ainsi que le chiffre du bit, dans ce cas le bit cinq. Ce que nous avons terminé exactement à l'heure actuelle est, défini le bit cinq sur notre

Registre STATUS à 0

Nous sommes à ce stade retournés dans la banque 0.
Ce qui suit est le code en un seul bloc:

BSF 03h, 5 Aller à la banque 1
MOVLW 06h Mettre 00110 dans W
MOVWF 85h Déplacer 00110 sur TRISA
BCF 03h, 5 Revenir à la banque 0

Dans la dernière instruction, nous vous avons confirmé la manière d'établir les broches du port IO sur le PIC pour être éventuellement une entrée ou une sortie.

Grâce à ce cours, laissez-moi vous aider à envoyer des données aux ports.

Envoi de données aux ports

Dans le didacticiel suivant, nous allons terminer en faisant clignoter une LED allumée et éteinte qui consiste en un programme complet détaillant et un schéma de circuit simple afin que vous puissiez voir le PIC effectuer exactement ce que nous prévoyons.

N'essayez pas d'assembler et de programmer votre PIC avec les résultats ci-dessous, car ce ne sont que des illustrations. Au départ, nous établirons le port A bit 2 en tant que sortie:

Cela pourrait être reconnaissable à partir de l'instruction précédente. La seule distinction pourrait être que nous avons fixé chaque bit des broches sur A en tant que sortie, en fournissant 0h au registre à trois états. Alors, ce qu'il doit faire maintenant, c'est allumer une LED.

Nous accomplissons cela en programmant l'une des broches (celle avec la LED qui lui est liée) haute. Pour le dire différemment, nous appliquons un «1» à la broche. C’est exactement ainsi que cela se fait (observez les commentaires pour une clarification pour chaque ligne):

Par conséquent, ce que nous avons maintenant accompli est d'allumer puis d'éteindre la LED une fois. Ce que nous souhaitons, c'est que la LED s'éteigne par la suite en continu.

Nous y parvenons en obtenant le programme pour revenir au départ. Nous accomplissons cela en établissant initialement une étiquette au début de notre programme, puis en informant le programme de revenir là-bas. Nous spécifions une balise assez simplement.

Nous saisissons un terme, disons START, puis saisissons le code:

Comme cela a été démontré, nous avons initialement mentionné l’expression «Démarrer» dès le début du programme.

Ensuite, à la toute fin du programme, nous avons clairement mentionné «goto Start». L’instruction ‘goto’ exécute exactement ce qu’elle déclare.

Ce programme allumerait et éteindrait systématiquement la LED chaque fois que nous allumons le circuit, ayant tendance à s'éteindre une fois que nous avons coupé l'électricité. Peut-être devrions-nous revoir notre programme:

Nous avons sûrement omis les commentaires, mais nous pouvons toujours observer les instructions et les chiffres.

Cela peut être un peu déroutant plus tard au cas où vous essayez de dépanner le programme et en écrivant le code, vous avez mémorisé toutes les adresses.

Bien que les commentaires puissent être placés immobiles, ils peuvent devenir un peu encombrés. Cela nécessitera de nommer les nombres et pourrait être accompli par une instruction supplémentaire: 'equ' L'instruction 'equ' suggère que certains trucs pourraient être égaux à d'autres trucs.

Ce n'est peut-être pas une instruction pour PIC, mais plutôt pour l'assembleur. Cette instruction facilite l'attribution d'un nom à un emplacement d'adresse de registre ou d'une constante à un terme de programmation.

Nous établirons quelques constantes pour notre programme et constaterons à quel point il est simple de lire le programme.

Depuis, nous avons fixé les valeurs constantes que nous pouvons procéder en les définissant dans notre programme. Les valeurs constantes doivent être désignées avant de les utiliser.

veillez donc à toujours les positionner au début du programme. Nous réécrirons le programme en excluant à nouveau les commentaires, afin de comparer l'étiquetage précédent avec le dernier.

Peut-être êtes-vous en mesure de remarquer que les constantes permettent une compréhension un peu plus facile du programme, cependant nous sommes toujours sans commentaires, pas de soucis cependant, car nous n'avons pas encore fini.

Il peut y avoir un inconvénient mineur de notre programme de LED clignotantes.
Chaque instruction a besoin d'une séquence d'horloge pour se terminer. Dans le cas où nous utilisons un cristal de 4 MHz, chaque instruction demande 1 / 4MHz, ou 1uS pour terminer.

Puisque nous n'utilisons que cinq instructions, la LED s'activerait puis s'éteindrait en 5uS. Cela pourrait être beaucoup trop rapide pour que les gens le remarquent, de plus, il semblera que la LED est complètement allumée.

Ce que nous devrions plutôt accomplir, c'est produire une inhibition entre l'allumage et l'extinction de la LED. La théorie de l'inhibition est que nous comptons à rebours à partir d'une quantité antérieure, donc quand elle arrive à zéro, nous arrêtons de compter.

La valeur zéro signifie la conclusion du retard et nous continuons à travailler notre processus tout au long du programme. Par conséquent, la première chose que nous devons faire est de déterminer une constante à utiliser comme compteur.

Appelons cette constante COUNT. Après cela, nous devons déterminer la signification d'un nombre à partir duquel commencer à compter. Sûrement, le plus grand chiffre que nous pourrions inclure est 255, ou FFh en hexadécimal., Comme je l'ai mentionné dans le tutoriel précédent, l'instruction equ affecte une expression à une situation de registre.

Cela implique que quelle que soit la quantité que nous allouons à notre COUNT, cela correspondrait aux articles d'un registre. Au cas où nous essayions de désigner la valeur FFh, nous aurons une erreur une fois que nous aurons pu compiler le programme.

La raison étant l’emplacement FFh est que nous ne pouvons donc pas y accéder. Par conséquent, comment doit-on désigner un nombre réel? Certes, il faudra une petite quantité de réflexion latérale.

Si nous désignons peut-être notre COUNT à l'adresse 08h, par exemple, cela indiquerait une destination de registre objectif de base. Par défaut, les zones intactes sont définies sur FFh. Par conséquent, si COUNT mène à 08h, vous rencontrerez la valeur de FFh lors de la première mise sous tension. Néanmoins, je vous, comment pouvons-nous fixer COUNT à un autre nombre?, Tout ce que nous appliquons est de «déplacer» une évaluation vers cette destination en premier.

À titre d'illustration, supposons que nous souhaitions que COUNT possède une valeur de 85h, nous ne pouvons pas mentionner COUNT equ 85h car c'est la position de notre registre des trois États pour le port A. Ce que nous accomplissons précisément est le suivant: movlw 85h la valeur de 85h dans le registre W movwf 08h

Maintenant, déplacez-le dans notre registre de 08h. Par la suite, dans le cas où nous exprimons COUNT équiv 08h, COUNT correspondra à la valeur 85h. Délicat, n'est-ce pas! Par conséquent, dans un premier temps, nous déterminons notre constante: COUNT equ 08h Ensuite, nous devons réduire ce COUNT de un jusqu'à ce qu'il devienne zéro.

Il se trouve simplement qu'il existe une instruction conçue pour accomplir cela pour nous, en utilisant un 'goto' et une balise.

L'instruction que nous allons appliquer est: DECFSZ COUNT, 1 Cette instruction indique «Décrémentez le registre (ici c'est COUNT) du nombre qui suit la virgule. Si nous atteignons zéro, sautons deux places devant. »Commençons par le trouver en action, avant de le placer dans notre cap.

Ce que nous avons effectué, c'est d'abord établir notre constante COUNT à 255. Le segment suivant positionne une balise, appelée LABEL près de notre instruction decfsz.

Le decfsz COUNT, 1 réduit la valeur de COUNT de un, et conserve le résultat final directement dans COUNT. De plus, il vérifie si COUNT possède une valeur de 0.

Si ce n’est pas le cas, dans ce cas, le programme passe à la ligne suivante. Nous avons maintenant une déclaration «goto» qui nous renvoie à notre instruction decfsz.

Si la valeur de COUNT est égale, l’instruction decfsz permet à notre programme d’avancer de 2 points et est envoyée là où nous avons déclaré «Continuer ici».

Par conséquent, puisque vous pouvez observer, nous avons amené le programme à s'asseoir au même endroit pendant un temps prédestiné avant de continuer. Cela pourrait être appelé une boucle de retard.

Comprendre les boucles de retard

Au cas où nous aurions besoin d'un délai plus important, nous pourrions poursuivre une boucle par la suivante. Les boucles supplémentaires, le délai prolongé. Laissez-nous au moins deux, en supposant que nous voulons observer le flash de la LED .. Nous allons placer ces boucles de retard dans notre programme, et accomplir en le rendant un véritable programme en introduisant des commentaires:

Il est possible de compiler ce programme après quoi programmer le PIC. De toute évidence, assurez-vous d'essayer le circuit pour vérifier s'il fonctionne effectivement. Ce qui suit est un schéma de circuit que vous devez construire dès que vous avez programmé le PIC.


Bien joué, vous auriez pu en fait composer votre premier programme PIC, ainsi que construire un circuit pour allumer et éteindre une LED. Jusqu'à présent, au cas où vous auriez suivi ces cours, vous auriez peut-être appris un total de sept instructions sur 35, mais sans aucun doute jusqu'à présent vous contrôlez les ports d'E / S!

Souhaitez-vous essayer de changer les boucles de retard pour rendre le flash LED plus rapide - quelle est la valeur minimale de COUNT pour voir essentiellement le flash LED? Ou peut-être voudrez-vous inclure une troisième boucle de retard ou supplémentaire après la boucle initiale pour stabiliser la LED. une constante unique pour chaque boucle de retard.

Vous pourriez alors potentiellement jouer avec vos boucles de retard pour rendre le flash LED à une vitesse spécifique, par exemple après une seconde. Dans les instructions suivantes, voyons comment nous pouvons utiliser quelque chose de connu sous le nom de sous-programme pour maintenir le programme compact et basique Un sous-programme fait partie intégrante du code, ou programme, qui peut être référencé comme et quand vous en avez besoin. Les sous-programmes sont utilisés dans les cas où vous accomplissez fréquemment la même fonction.

Que sont les sous-programmes

Les avantages de l'utilisation d'un sous-programme sont qu'il sera probablement plus simple de modifier la valeur une fois dans un sous-programme au lieu de, disons, dix fois tout au long de votre programme, ainsi que cela contribue grandement à réduire le niveau de mémoire que votre programme consomme dans le PIC. Nous allons vérifier un sous-programme:

Au départ, nous devons fournir à notre sous-programme une désignation, et dans cette situation, nous avons sélectionné ROUTINE. Après cela, nous tapons le code que nous aimerions appliquer normalement. C'est pourquoi, nous avons sélectionné le retard dans notre programme de clignotement à LED. Enfin, nous terminons le sous-programme en tapant l'instruction RETURN.

Pour commencer le sous-programme de n'importe où dans notre programme, nous tapons rapidement l'instruction CALL puis la désignation du sous-programme.

Nous examinerons cela un peu plus en profondeur. Une fois que nous arrivons à la section de notre programme qui CALL xxx, dans laquelle xxx est le nom de notre sous-programme, le programme saute à n'importe quel endroit où le sous-programme xxx est installé. Les instructions à l'intérieur du sous-programme sont exécutées.

Chaque fois que l'instruction RETURN est accomplie, le programme saute en revenant à notre programme principal à l'instruction suivant notre instruction CALL xxx.

Il est possible d'appeler le même sous-programme plusieurs fois comme vous le souhaitez, ce qui explique pourquoi l'utilisation de sous-programmes diminue la durée générale de notre programme.

Néanmoins, il y a quelques facteurs à connaître. Au départ, comme avec notre programme principal, toutes les constantes spécifiques doivent être reconnues avant de pouvoir les utiliser.

Ceux-ci peuvent être éventuellement reconnus dans le sous-programme lui-même, ou directement au début du programme principal. Je vous propose de tout reconnaître au début de votre programme principal, puisque vous reconnaissez alors que les choses sont dans une position identique. Ensuite, il faut s'assurer que le programme principal saute le sous-programme.

Ce que je veux dire, c'est que si vous placez le sous-programme directement à la fin de votre programme principal, sauf si vous utilisez une déclaration 'Goto' pour sauter de l'endroit où se trouve le sous-programme, le programme continuerait et implémenterait le sous-programme, que vous l'exiger ou autrement.

Le PIC ne ferait pas la distinction entre un sous-programme et le programme principal. Nous allons vérifier notre programme à led clignotant, mais cette fois nous allons utiliser un sous-programme pour la boucle de retard. Dans l'idéal, vous découvrirez à quel point le programme est moins compliqué, ainsi que comment le sous-programme s'applique pratiquement.

Finalement, vous pouvez observer qu'en utilisant un sous-programme pour notre boucle de retard, nous pourrions avoir réduit les dimensions du programme.

Chaque fois que nous désirons un délai, éventuellement lorsque la LED est allumée ou éteinte, nous appelons essentiellement le sous-programme de délai. À la fin du sous-programme, le programme revient à la ligne suivant notre instruction «Call». Dans l'illustration ci-dessus, nous allumons la LED.

Nous contactons ensuite le sous-programme. Le programme revient ensuite afin que nous puissions éteindre la LED. Nous appelons le sous-programme une fois de plus, juste au cas où le sous-programme aurait pu se terminer, le programme revient et l'instruction suivante qu'il reconnaît est «goto Start». Pour tous ceux qui pourraient être intrigués, notre premier programme faisait 120 octets.

Grâce à l'utilisation du sous-programme, nous pourrions réduire la taille de notre programme à 103 octets. Cela ne peut pas sembler aussi fantastique, mais compte tenu du fait que nous n'avons que 1024 octets au total à l'intérieur du PIC, chaque petite quantité en profite.

Dans la prochaine instruction, vérifions la lecture des ports.

Jusqu'à présent, nous avons composé sur le port A afin de pouvoir allumer et éteindre une LED. À ce stade, nous verrons comment nous allons lire les broches d'E / S sur les ports.

Lecture des ports d'entrée / sortie

C'est exactement pour nous assurer que nous sommes en mesure de relier un circuit externe et d'influencer les sorties spécifiques qu'il offre.

Si vous vous souvenez de nos cours précédents, si vous voulez établir les ports d'E / S, nous devions passer de la banque 0 à la banque 1. Nous allons accomplir cela dans un premier temps:

À ce stade, nous avons fixé le bit 0 du port A à l'entrée. nous devons maintenant examiner si la broche est haute ou basse. Pour ce faire, on peut utiliser une seule des deux instructions:

BTFSC et BTFSS.

L’instruction BTFSC signifie «Faites un test de bit sur le registre ainsi que sur le bit que nous désignons.

Dans le cas où c’est un 0, dans ce cas, nous omettons l’instruction suivante ». BTFSS implique «Faites un petit test dans le registre et le bit que nous établissons. Dans le cas où il est mis à 1, alors nous contournons l'instruction suivante.

Celui que nous utilisons est déterminé par la manière précise dont nous souhaitons que notre programme réponde pendant que nous étudions l'entrée. À titre d'illustration, au cas où nous attendions juste que l'entrée soit un 1, nous pourrions être en mesure d'utiliser l'instruction BTFSS de la manière suivante:

Code ici:

BTFSS PortA, 0Goto commencer Continuez ici:
:

Le programme passerait simplement sur «Continuer ici» à condition que le bit 0 sur PortA soit programmé sur 1.

Nous allons actuellement écrire un programme qui pourrait déclencher une LED à une vitesse, cependant si un interrupteur est confiné, il fera clignoter la LED deux fois plus lentement.

Il est peut-être possible d'exercer ce programme par vous-même, mais nous avons intégré la liste d'une manière ou d'une autre.

Vous pouvez essayer et créer l'intégralité du programme, afin de vérifier si vous avez compris les principes. Nous utiliserons le circuit équivalent comme auparavant, avec l'inclusion d'un interrupteur attaché RA0 du PIC et du rail positif de notre alimentation.

Ce que nous avons accompli ici, c'est d'allumer la LED. Je détermine par la suite si l'interrupteur est fermé.

Au cas où il serait confiné, je me connecte ensuite à notre sous-programme de délai. Cela nous fournit le délai équivalent au précédent, mais nous le contactons à ce stade deux fois.

La même chose s'applique à chaque fois que la LED est éteinte. Dans le cas où l'interrupteur n'est pas fermé, nous enregistrons nos périodes d'activation et de désactivation précédentes.

Avez-vous suivi ces leçons depuis le début, vous cherchez peut-être à comprendre que vous avez actuellement découvert dix des 35 instructions pour le PIC 16F84! Et chacun de ces éléments peut être appris simplement en allumant et éteignant une LED.

Jusqu'à présent, nous avons composé le clignotement PIC d'une LED allumée et éteinte.

Par la suite, nous avons pu le faire avec notre PIC en incluant un interrupteur, donc en faisant varier la vitesse du flash.

Utilisation efficace de l'espace mémoire

Le seul problème est que le programme est assez long et peu efficace en termes d'espace mémoire. Cela me semblait correct pendant que j'incluais les commandes pour la première fois, mais il devrait y avoir un moyen plus simple de l'exécuter. Positivement, nous allons analyser comment nous allumions et éteignions littéralement la LED.

movlw 02hmovwf PORTAmovlw 00hmovlw PORTA

Au début, nous avons bourré notre registre w avec 02h, après cela nous l'avons transféré dans notre registre PortA pour allumer la LED. Pour l'éteindre, nous avons emballé w avec 00h, après quoi nous l'avons transféré dans notre registre PortA.

Entre toutes ces routines, nous avons été obligés de contacter un sous-programme pour nous assurer que nous pouvions observer le clignotement de la LED.

Par conséquent, nous avons dû transférer deux ensembles d'informations plusieurs fois (une fois dans le registre w puis vers PORTA) et appeler un sous-programme deux fois (une fois pour on puis une fois pour off). Ainsi, comment pourrions-nous y parvenir avec une efficacité accrue? Très simple.

Nous utilisons une instruction différente connue sous le nom de XORF. L'instruction XORF utilise une fonction OU exclusif sur le registre que nous stipulons avec les informations que nous fournissons. Je crois que je dois clarifier ce qu'est dans le monde une salle d'opération exclusive avant de continuer. Dans le cas où nous avons deux entrées et une sortie, l'entrée ne peut être un 1 que si et tant que les deux entrées diffèrent. Bien qu'ils soient identiques, le résultat sera probablement 0. Ce qui suit est une table de vérité, pour les personnes qui choisissent de les consulter:

A B F0 0 00 1 11 0 11 1 0

Nous allons à ce stade vérifier ce qui se passe si nous rendons B comme notre sortie précédente, et en modifiant simplement la valeur de A:

A B F
0 0 0
0 0 0
1 0 1
1 1 0
1 0 1

Si nous maintenons la valeur de A identique à 1, et nous l'exclusif OU avec la sortie, la sortie basculera. Dans le cas où vous ne pouvez pas le remarquer à partir de la table de vérité, ci-dessous, il peut être observé en utilisant le binaire:

0 sortie courant
EX-OR avec 1 1 nouvelle sortie
EX-OR avec 1 0 nouvelle sortie

Peut-être que vous pouvez trouver qu'en effectuant un OU exclusif sur la sortie avec 1, nous allons maintenant basculer la sortie de 0 à 1 à 0.
Par conséquent, pour allumer et éteindre notre LED, nous n'avons besoin que de quelques phrases:

MOVLW 02h
PORTE XORWF, 1

Ce que nous allons précisément accomplir, c'est ajouter notre registre w avec 02h. Dans ce cas, nous utilisons ce numéro en OU exclusif, quel que soit le contenu de notre PortA. Dans le cas où le bit 1 est un 1, il va se transformer en 0. Dans le cas où le bit 1 est un 0, il va se transformer en 1. Examinons ce code une ou deux fois, pour afficher comment il exécute le binaire:

PORTE
00010
xorwf 00000
xorwf 00010
xorwf 00000
xorwf 00010

Nous n'avons pas à charger la valeur identique dans notre registre w à chaque fois, il est donc possible de le faire une seule fois au début et de revenir simplement à notre commande bascule. De plus, nous ne devons pas fixer une valeur sur notre registre PortA. La raison? Sûrement, puisque au cas où à la mise sous tension il s'agit d'un 1, nous pouvons facilement le basculer. Moi, alternativement un 0 à la mise sous tension, nous le basculerions même maintenant.

Par conséquent, vous voudriez voir notre code nouvellement formé. Le premier représente notre code LED clignotant, tandis que le second montre celui avec l'ajout du commutateur:

Souhaitons que vous puissiez trouver que simplement en utilisant une instruction simple, nous avons maintenant réduit l'échelle de notre programme. La vérité est que, afin d'afficher à quel point nous pourrions réduire nos programmes, nous avons démontré les deux programmes, juste ce qui a été composé, et leurs dimensions dans le tableau ci-dessous:

Program Alter Dimensions (octets)
LED clignotante Original 120
Sous-programme LED clignotant ajouté 103
LED clignotante Fonction XOR utilisée 91
LED avec interrupteur Original 132
LED avec fonction interrupteur XOR utilisée 124.

Par conséquent, non seulement nous avons découvert quelques nouvelles instructions, mais nous avons certainement également diminué la taille de nos scripts!

Ci-dessous, nous analyserons comment vous pouvez agiter des bits individuels, effectuer certaines arithmétiques simples, ainsi que des tableaux de données.

Gestionnaires logiques

Dans le dernier tutoriel, j'ai présenté l'opération OU exclusif. La fonction ExOR est comprise comme un opérateur logique.

Dans ce didacticiel, j'éclairerai les opérateurs logiques supplémentaires promus par le PIC. Il n’y aura pas de cas dans les programmes ponctuels, mais nous allons apprendre des méthodes simples pour utiliser les opérateurs en appliquant de petites zones de code.

ET La fonction ET analyse essentiellement deux bits et délivre un 1 s'ils sont identiques, et un 0 s'ils sont distinctifs. Par exemple, si nous avons mentionné 1 ET 1, le résultat est 1, tandis que dans le cas où nous avons déclaré 1 ET 0, la conséquence serait 0.

Inutile de dire que nous pouvons également évaluer les mots, et que toutes les fonctions de la fonction AND sont de revoir les deux termes petit à petit. L'instance ci-dessous montre deux mots de 8 bits qui deviennent AND avec le produit:

11001011
ET 10110011
Égale 10000011

J'espère que vous êtes d'accord, le résultat possédera simplement un 1 chaque fois que 2 1s main dans la main l'un avec l'autre dans une paire de mots. Nous pouvons utiliser la fonction AND pour vérifier les ports, par exemple.

Dans le cas où nous vérifions quelques broches d'E / S liées à un circuit, et nous devrions garder un œil sur une situation particulière dans laquelle seules quelques broches sont hautes, dans ce cas, nous sommes en mesure de lire à peu près le port, après quoi ET le résultat avec la condition que nous avons examinée, identique à l'instance ci-dessus.

Le PIC nous fournit deux ingrédients pour ET.
Ce sont ANDLW et ANDWF. ANDLW nous permet de réaliser une fonction ET avec les détails du registre W, et un montant que nous stipulons.

La syntaxe est: ANDLW où est exactement ce que nous allons ET le contenu de W avec.

La conséquence de la fonction ET serait stockée directement dans le registre W.
ANDWF nous permet de réaliser une fonction ET sur le registre W et un registre différent, par exemple un PORT. La syntaxe est: ANDWF, d dans lequel est le registre qui nous passionne, par ex. PORTA, et d montre le PIC où vous devez positionner le résultat. Si d = 0, le résultat est mis dans le registre W, et de d = 1 le résultat final est sauvegardé dans le registre que nous avons stipulé. Les deux parties de code ci-dessous affichent un bon exemple de chaque fonction ET.

La première consiste à examiner l'état du PORTA, dans lequel nous devons vérifier si les entrées sont 1100. Nous pouvons replacer le résultat dans le registre W

movlw 1100
ANDWF 05h, 0 La deuxième illustration peut maintenant vérifier le contenu du registre W:
ANDLW 1100

OU

Nous avons maintenant découvert une fonction OR, pour être précis le XOR. Cela se développe en un 1 si deux bits ne sont pas identiques, mais sont différents. Vous pouvez trouver une autre fonction OR appelée IOR, qui est le OU inclusif. Cette fonction générera un 1 dans le cas où l'un ou l'autre des bits est un 1, mais en plus si chaque bit est égal à 1. Voici une table de vérité claire pour illustrer ceci:

A B O / P
0 0 0
0 1 1
1 0 1
1 1 1

Que sont les opérateurs arithmétiques

AJOUTER

Cette fonction accomplit ce qu'elle prétend habituellement. Cela apporte deux chiffres! Dans le cas où la conséquence de l'addition des deux chiffres dépasse 8 bits, dans ce cas, un drapeau CARRY sera probablement défini. Le drapeau CARRY est situé à l'adresse 03h bit 0.

Lorsque ce bit est programmé, les deux chiffres dépassent 8 bits. Lorsqu'il est à 0, dans ce cas, la conséquence est située à moins de 8 bits. Comme auparavant, le PIC nous offre deux styles d'ADD, en particulier ADDLW et ADDWF. Comme vous l'avez peut-être supposé, cela ressemble beaucoup à la fonction ci-dessus. ADDLW propose le contenu du registre W à ce que nous stipulons. La syntaxe est la suivante: ADDLW ADDWF ajouter le contenu du registre W et un autre registre que nous désignons.

La syntaxe est: ADDWF, d est où

SOUS

À ce stade, je suppose que vous ne pouvez pas présumer de ce que cette fonction conduit! En effet, vous vous en doutiez, cette fonction
soustrait un bit d'un autre. Encore une fois, le PIC nous offre 2 goûts: SUBLW et SUBWF. La syntaxe est exactement la même que pour la fonction ADD, à part évidemment vous tapez SUB à la place de ADD!

Incrément Dans le cas où nous souhaiterions inclure 1 à un nombre dans le PIC, nous pourrions absolument utiliser la fonction ADD et utiliser le numéro un. ~ La difficulté avec ceci est que nous devons d'abord placer la figure dans le registre W, puis utiliser la commande ADDLW 1 pour l'incrémenter. Si nous souhaitons inclure 1 dans un registre, cela peut être pire encore. Nous devons d'abord placer le numéro 1 dans le registre W, puis utiliser ADDWF, 1. Par conséquent, par exemple, pour inclure 1 à l'emplacement 0C, disons, nous aurions besoin de posséder la partie suivante du script:

movlw 01
addwf 0c, 1

Il existe une méthode plus simple pour y parvenir. Nous pouvons exercer la commande INCF. La syntaxe est: INCF, d où, est le registre, ou le lieu, qui nous concerne, et d montre le PIC où vous devez positionner le résultat. Dans le cas d = 0, le résultat est dans le registre W, et dans le cas d = 1, la conséquence est définie dans le registre que nous avons stipulé.

En utilisant cette instruction individuelle, nous pouvons en fait cinquante pour cent du codage. Dans le cas où nous aurions souhaité que le résultat soit restauré dans le registre W, dans ce cas en utilisant l'instance ci-dessus, nous aurions peut-être dû inclure une commande supplémentaire pour déplacer les éléments de 0C dans le registre W, après quoi remettre le registre 0C à no peu importe ce que c'était.

Il existe une commande d'incrémentation. C'est INCFSZ. Cette commande pourrait incrémenter le registre que nous stipulons, cependant si nous le registre est égal à 0 après l'incrément (cela se produira alors que nous incluons 1 à 127), le PIC contournera probablement l'instruction suivante. La partie du code ci-dessous reflète ceci:

Boucle incfsz 0C
Aller à la boucle
:
:
Reste du programme.

Dans la partie de code ci-dessus, 0C va être incrémenté de 1. Nous possédons ensuite une instruction qui informe le PIC de revenir à notre balise nommée Loop, et d'incrémenter à nouveau 0C de 1. Cela continue jusqu'à ce que 0C soit égal à 127. Dans ce cas, lorsque nous incrémentons 0C de 1, 0C va maintenant correspondre à 0. Notre instruction INCFSZ pourrait très bien informer le PIC d'omettre l'instruction suivante, qui dans ce cas est la déclaration goto, par conséquent, le PIC ira de l'avant avec le reste du programme.

Décrémenter

Nous avons maintenant discuté de la fonction de décrémentation dans la formation précédente, donc je ne la réviserai plus.

Complément

L'instruction finale de cette discussion inverserait chaque bit du registre que nous stipulons. La syntaxe est: COMF, d dans laquelle

Comprendre les opérations sur les bits

Cela pourrait être utilisé, par exemple, pour permuter rapidement les broches d'un port de la sortie à l'entrée et ainsi de suite. Les fonctions de bits nous permettent de façonner un seul bit dans une expression. Ils nous permettent de procéder, de définir et de supprimer des bits uniques dans les registres ou les nombres que nous stipulons.

À la fin de ce cours, nous allons divulguer un programme conçu pour créer un ensemble de lumières séquentielles qui avancent, puis dans le sens inverse. Nous avons observé cela accompli plus tôt lorsque nous avons examiné la fonction OU exclusif, dans laquelle nous avons effectué un OU exclusif des ports avec une expression. Nous avons maintenant remarqué quelques fonctions de bits lorsque nous établissons les ports sur le PIC, et

Permettez-moi de réitérer leur utilisation ici.

BCF

Cette instruction effacera un peu ce que nous stipulons dans un registre que nous désignons. La syntaxe
est:
BCF,

Nous l'avons utilisé précédemment pour passer de la page 1 à la page 0 en supprimant un peu dans le registre STATUS. Nous pouvons également l'utiliser pour fixer un bit à 0 dans n'importe quel registre / emplacement différent. Par exemple, au cas où nous souhaiterions définir le 3ème bit de 11001101 enregistré dans la section 0C sur 0, nous pourrions
insérer:

BCF 0C, 03

BSF

Cette instruction fixerait tout bit que nous stipulons à 1 dans tout registre que nous indiquerons. Nous l'avons utilisé plus tôt pour passer de la page 0 à la page 1. La syntaxe est: BSF ,, et est utilisée précisément dans la même méthode que BCF ci-dessus.

BTFSCJusqu'à présent, nous pourrions définir ou effacer un peu dans un registre. Cependant, imaginez si nous devons vérifier fondamentalement si un bit est un 1 ou un 0 dans un registre?

Certes, il est possible d'utiliser BTFSC. Il indique le registre de test de bits F et Ignorer s'il est clair. Cette instruction va analyser le bit que nous désignons dans le registre. Dans le cas où le bit est un 0, l'instruction informerait le PIC de contourner l'instruction suivante.

Nous pourrions utiliser cette instruction au cas où nous souhaiterions vérifier un drapeau, par exemple le drapeau de retenue. Cela nous évite d'avoir à lire le registre STATUS et à rechercher les bits individuels pour savoir quels drapeaux sont fixés. 29 Par exemple, au cas où nous souhaitions vérifier si le drapeau Carry était défini sur 1 après avoir ajouté 2 chiffres, nous pourrions taper ce qui suit:

BTFSC 03h, 0
continuer ici s'il est réglé sur 1
ou ici si mis à 0

Dans le cas où l'état du bit est un 1, dans ce cas, l'instruction suivant BTFSC serait terminée. Dans le cas où il est mis à 0, dans ce cas, l'instruction suivante est ignorée. La partie suivante du code expose dans laquelle il pourrait être utilisé:

Boucle :
:
:
BTFSC 03,0
Aller à la boucle

Dans le code ci-dessus, le PIC sortira simplement de la boucle au cas où le bit 0 du registre STATUS (ou le drapeau Carry) est défini à 0. Sinon, la commande goto serait exécutée.

BTFSS

Cette instruction indique le registre de test de bits F et Ignorer si défini. Cela peut être comparable à l'instruction BTFSC, sauf que le PIC omettrait l'instruction suivante si le bit que nous avons évalué est mis à 1, au lieu de 0.

CLRF

Cette instruction fixerait tous les détails d'un registre à 0. La syntaxe est:

CLRF
Nous l'avons utilisé précédemment pour définir la sortie des ports sur 0, en appliquant CLRF 85h. Nous l'avons également utilisé pour fixer les ports afin d'inclure toutes les broches à la sortie en utilisant CLRF
05h.

CLRW

Cela pourrait ressembler à l'instruction CLRF, sauf pour effacer le registre W. La syntaxe est assez simple:

CLRW

RLF et RRF

Ces directions transporteraient un bit dans un registre un seul créneau vers la gauche (RLF) ou la droite (RRF) dans un registre. Par exemple, si nous avions besoin de 00000001 et que nous utilisions RLF, dans ce cas, nous pourrions posséder 00000010. À ce stade, que se passe-t-il dans le cas où il y aurait 10000000 et appliquer l'instruction RLF? Sûrement, le 1 serait positionné dans le drapeau de portage. Dans le cas où nous appliquions à nouveau l'instruction RLF, le 1 réapparaîtrait au début. La même chose se produit, cependant à l'opposé, pour l'instruction RRF. Le cas ci-dessous le montre pour l'instruction RLF, dans laquelle nous pouvons voir les 8 bits d'un registre, ainsi que le drapeau de retenue:

C 87654321
0 00000001
RLF 0 00000010
RLF 0 00000100
RLF 0 00001000
RLF 0 00010000
RLF 0 00100000
RLF 0 01000000
RLF 0 10000000
RLF 1 00000000
RLF 0 00000001

Exemple de programme

Nous allons maintenant voir un exemple de code que l'on peut compiler et piloter. Cela générerait une lumière de séquençage commençant au bit 0 de PortA, allant au bit 8 de PortB et
puis revenant.
Connectez les LED à chacune des broches du port. Nous aurons une partie du peu
procédures décrites dans ce didacticiel.

TIME EQU 9FH Variable pour la boucle de retard.
PORTB EQU 06H Adresse du port B.
TRISB EQU 86H Port B Adresse tristate.
PORTA EQU 05H Adresse du port A.
TRISA EQU 85H Port A Adresse tristate.
STATUS EQU 03H Registre de sélection de page.
COUNT1 EQU 0CH Registre de boucle.
COUNT2 EQU 0DH Registre de boucle.

ÉTAT BSF, 5 Aller à la page 1
MOVLW 00H et configuration
MOVWF TRISB les deux ports A et B
MOVLW 00H à la sortie,
MOVWF TRISA puis revenez à
ÉTAT BCF, 5 page 0.
MOVLW 00H Effacer le port A.
PORTE MOVWF

Début du programme principal

RUNMOVLW
01H Définir le premier bitMOVWF
PORTB sur le port B.CALL
DELAY Attendez un peu
RETARD
Déplacez le bit sur le port B vers la gauche, puis faites une pause.
PORTB, 1 APPEL
DELAYCALL
DELAYRLF
PORTB, 1 APPEL
DELAYCALL
DELAYRLF
PORTB, 1 APPEL
DELAYCALL
DELAYRLF
PORTB, 1 APPEL
DELAYCALL
DELAYRLF
PORTB, 1 APPEL
DELAYCALL
DELAYRLF
PORTB, 1 APPEL
DELAYCALL
DELAYRLF
PORTB, 1 APPEL
DELAYCALL
DELAYRLF
PORTB, 1 Ceci déplace le bit dans le drapeau de retenue
Passez maintenant au port A et déplacez le bit vers la gauche.
PORTA, 1 Cela déplace le bit de l'indicateur zéro dans PortACALL
DELAYCALL DELAYRLF
PORTE, 1 APPEL
DELAYCALL
DELAYRLF
PORTE, 1 APPEL
DELAYCALL
DELAYRLF
PORTE, 1 APPEL
DELAYCALL
RETARD
Déplacer le bit sur le port ARRF
PORTE, 1 APPEL
DELAYCALL
DELAYRRF
PORTE, 1 APPEL
DELAYCALL
DELAYRRF
PORTE, 1 APPEL
DELAYCALL
DELAYRRF
PORTA, 1 Cela déplace le bit dans l'indicateur zéro Maintenant, déplacez le bit
retour sur Port BRRF
PORTB, 1 APPEL
DELAYCALL
DELAYRRF
PORTB, 1 APPEL
DELAYCALL
DELAYRRF
PORTB, 1 APPEL
DELAYCALL
DELAYRRF
PORTB, 1 APPEL
DELAYCALL DELAYRRF
PORTB, 1 APPEL
DELAYCALL
DELAYRRF
PORTB, 1 APPEL
DELAYCALL
DELAYRRF
PORTB, 1 APPEL
DELAYCALL
RETARD Maintenant nous sommes de retour là où nous avons commencé, GOTO
RUN allons-y à nouveau.

Il existe une excellente option dans l'ensemble d'apprentissage qui vous permet d'utiliser une table de données.

Une table de données est juste une liste de citations de données, dans laquelle tout est examiné en fonction de quelques considérations.
Par exemple, vous pourriez avoir un circuit qui utilise un PIC qui compte la quantité d'instances qu'une broche d'entrée devient élevée en 1 seconde. Après cela, vous pouvez afficher le numéro sur un affichage à 7 segments.

Dès que le chronométrage est lancé, le PIC commence à compter le nombre d'occasions où la broche monte. Après 1 seconde, il visite la table et regarde les données, il doit afficher le numéro sur l'écran qui symbolise le nombre de situations où la broche s'est élevée. Cela peut être bénéfique, car nous ne déterminons pas ce que pourrait être le chiffre tant que le PIC n’a pas réalisé son estimation.

En utilisant un tableau, nous pouvons permettre au PIC de déterminer la figure à représenter. À ce stade, avant de continuer à vous montrer comment la table de données fonctionne, je pourrais avoir à vous dire que le PIC maintient le chemin des allées et venues dans le programme qu'il se trouve pendant que le programme fonctionne.

Il facilite pour ceux qui ont effectué certaines programmations en BASIC. Sinon, ne vous inquiétez pas, vous voudrez peut-être continuer à en apprendre davantage sur la théorie. Envision, il existe un programme BASIC similaire à celui présenté ci-dessous:

10 ANS K = 0
11 K = K + 1
12 SI K> 10 ALORS GOTO 20 AUTREMENT GOTO 11
20 IMPRIMER K
21 FIN

Le programme commence à la ligne 10. Dès que K est programmé à 0, il passe ensuite à la ligne 11. Après avoir inclus 1 à K, nous passons ensuite à la ligne 12.

À ce stade, nous pourrions être curieux de savoir si K est supérieur à 10. Dans ce cas, nous allons ensuite à la ligne 20, ou bien nous revenons à la ligne 11.

La ligne 20 documente le K et la ligne 21 conclut le programme. BASIC utilise des statistiques de ligne pour aider le programmeur à garder une trace de l'emplacement des problèmes, car les étiquettes ne sont pas autorisées. Le PIC utilise des étiquettes pour s'échapper entre les destinations - ou le peut-il vraiment?

Nous utilisons les étiquettes pour nous assurer que nous savons où se trouvent les problèmes, ainsi que pour nous assurer que nous sommes en mesure d'informer le PIC d'une manière simple où rechercher.

Ce qui se passe précisément, c'est que le PIC tire parti d'un compteur de ligne interne appelé compteur de programme. Le chemin du compteur de programme (abrégé en PC) de la destination mémoire de l'endroit où se trouve l'instruction actuelle.

Chaque fois que nous informons le PIC de visiter une étiquette sélectionnée, il comprend le point mémoire et augmente donc le PC jusqu'à ce qu'il voit cette destination mémoire. C'est exactement la même méthode que nous vérifions le programme BASIC ci-dessus. Voici un segment de code, avec les espaces mémoire, ou les éléments du PC, à côté de chaque instruction:

Instruction PC0000 movlw 03
0001 movwf 0C
0002 Boucle decfsc 0C
0003 boucle goto
0004 fin

Dans la démonstration ci-dessus, nous avons fixé le PC à 0000. Sur cela, nous avons l'instruction movlw 03. Lorsque le PIC a implémenté ces données, il incrémente le PC afin que l'instruction suivante soit scannée. À ce stade, le PIC affiche movwf 0C. Le PC est à nouveau incrémenté.

Maintenant, le PIC étudie decfsc 0C. Dans le cas où les détails de 0C ne sont pas 0, dans ce cas le PC est incrémenté de 1, ainsi que l'instruction suivante, goto Loop, informe le PC de revenir à la position 0003, où il y a ladite boucle. Dans le cas où les détails de 0C sont 0, il est conseillé au PC d'incrémenter de 2, en omettant simplement l'instruction suivante.

Comprendre les tableaux de données

Cela place le PC à la position 0004, où le programme se termine. Les destinations sont fixées par l'assembleur, et nous ne devrions généralement pas nous préoccuper de ce que le PC accomplit. Jusque-là, nous trouvons le besoin de le maîtriser, comme lorsque nous utilisons des tables de données. La manière la plus pratique de décrire le fonctionnement d'une table de données est de commencer par une illustration.

PC equ 02
movlw 03
table d'appel
:
table addwf PC
retlw 01
retlw 02
retlw 03
retlw 04
retlw 05
retlw 06
retlw 07
revenir

L'instruction initiale attribue à l'étiquette PC l'adresse du compteur de programme (02h). Nous serons bientôt après avoir mis la valeur de 03h dans le registre w. Nous communiquons ensuite à table. La première ligne de la table des sous-programmes augmente les détails du registre W (03h) vers le compteur de programme.

Cela déclenche l'augmentation du compteur de programmes de 3, ou pour le dire d'une manière différente, stimule le compteur de programmes à descendre de 3 lignes. Pendant que le compteur arrive 3 lignes plus bas, le PIC reconnaît l'instruction retlw. Cette commande envoie la valeur qui la suit dans le registre W, après quoi elle revient du sous-programme. RETLW signifie fondamentalement Retour, littéral à W.

Voir j'ai placé une virgule après le mot Retour. Puisque nous sommes dans un sous-programme, nous avons besoin d'une instruction Return pour en faire surface. Par conséquent, le RET dans l'instruction. Après l'instruction RETLW, il y a un nombre, et c'est exactement ce qui est mis dans le registre W.

Dans ce cas, il s'agit de la figure 3. Nous pourrions désigner n'importe quelle quantité dans le registre W, tant que cette figure est combinée avec le compteur de programme dans le sous-programme de table, nous allons découvrir une instruction retlw. Dans l'illustration ci-dessus, cela implique que nous sommes capables de posséder n'importe quel nombre de 1 à 7. Dans le cas où nous passerions au-delà du sous-programme, nous pourrions être en mesure de finir d'exécuter une section supplémentaire du programme. Pour cette raison, il est généralement judicieux de placer la table de données exactement vers la fin du programme PIC, donc si nous dépassons dans ce cas, nous arriverons de toute façon à la conclusion du programme.

Le sujet des interruptions pourrait bien être le plus long et le plus difficile à aborder.

Vous ne pouvez trouver aucune méthode simple pour détailler les interruptions, mais avec un peu de chance vers la fin de cette partie, vous pourrez peut-être appliquer des interruptions dans vos propres programmes.
Nous avons séparé la section en 2 étapes. Cela permet de séparer le sujet en sections, ainsi que de vous fournir un plan pratique pour une compréhension facile.

Qu'est-ce qu'une interruption? Sûrement, comme le terme l'indique, une interruption est une technique ou un signal qui empêche un microprocesseur / microcontrôleur de quelque chose qu'il exécute que quelque chose de différent puisse se produire.

Permettez-moi de vous en donner une illustration quotidienne. Pensez que vous vous détendez chez vous, en discutant avec une autre personne. Tout à coup, le téléphone sonne.

Vous arrêtez de parler et prenez le téléphone pour parler à l'appelant. Une fois que vous avez votre conversation téléphonique, vous décidez de reprendre la conversation avec l'individu avant que le téléphone ne sonne. Il est possible de considérer la routine principale pendant que vous discutez avec quelqu'un, la sonnerie du téléphone provoque une perturbation de votre conversation, et la rupture de routine est la méthode de parler au téléphone.

Lorsque la discussion téléphonique prend fin, vous revenez à votre routine principale de discussion. Cette illustration est précisément comment interrompre un processeur pour agir.

Le programme principal est en cours de fonctionnement, exécutant certaines fonctions dans un circuit, cependant, lorsqu'une interruption a lieu, le programme principal s'arrête tandis qu'un programme différent est exécuté. le programme se termine, le processeur revient au programme principal comme précédemment.

Comprendre les interruptions

Le PIC possède 4 sources d'interruption. Ils pourraient être divisés en deux groupes. Deux sont des sources d'interruptions qui peuvent être utilisées vers l'extérieur pour le PIC, tandis que les deux autres sont des processus internes. Permettez-moi de clarifier les deux types externes ici. Les deux autres vont être décrits dans différents tutoriels une fois que nous arriverons aux minuteries et au stockage des données.

Si vous vérifiez le brochage du PIC, vous remarquerez que la broche 6 est RB0 / INT. À ce stade, RB0 est clairement le bit 0 du port B. L'INT représente qu'il pourrait aussi bien être configuré comme une broche d'interruption extérieure. En outre, les broches 4 à 7 du port B (broches 10 à 13) peuvent également être utilisées pour les interruptions. Avant de pouvoir utiliser les broches INT ou un autre port B, nous devons accomplir deux tâches. Tout d'abord, nous devons informer le PIC que nous utiliserons les interruptions.

Ensuite, nous devons désigner la broche du port B que nous allons utiliser comme une interruption plutôt que comme une broche d'E / S. À l'intérieur du PIC, vous pouvez trouver un registre connu sous le nom d'INTCON, et se trouve à l'adresse 0Bh. Dans ce registre, vous découvrirez 8 bits qui peuvent être activés ou désactivés. Le bit 7 d'INTCON est appelé GIE. Il s'agit du Global Interrngupt Enable. Fixer ceci à 1 informe le PIC que nous utiliserons une interruption.

Le bit 4 d'INTCON est appelé INTE, INTerrupt Enable. Mettre ce bit à 1 indique au PIC que RB0 va être une broche d'interruption. La configuration du bit 3, appelé RBIE, informe le PIc que nous allons utiliser les bits 4 à 7. À ce stade, le PIC comprend quand cette broche peut être haute ou basse, doit arrêter ce qu'elle exécute et procéder à une interruption routine. À ce stade, nous devons informer le PIC si l'interruption sera vraisemblablement sur le front montant (0V à + 5V) ou sur la transformation du front descendant (+ 5V à 0V) du signal.

En termes simples, souhaitons-nous que le PIC s'interrompe à chaque fois que le signal passe de bas en haut ou de haut en bas. Par délinquance, celle-ci peut être établie pour être placée sur le front montant.

Le front «déclenchement» est planifié dans un registre supplémentaire appelé registre OPTION, à l'adresse 81h. Le bit qui nous passionne est le bit 6, souvent appelé INTEDG.

Le réglage à 1 déclenche la perturbation du PIC sur le bord de montage (état par défaut) et le réglage à 0 stimule le PIC à se perturber sur le bord coulissant. Si vous souhaitez que le PIC s’active sur le front montant, vous n’avez certainement rien à faire pour ce bit.

À ce stade, malheureusement, le registre d'options est dans la banque 1, ce qui signifie que nous aimons modifier de la banque 0 à la banque 1, définir le bit dans le registre d'options, après ce retour à la banque 0. La clé ici est d'accomplir chaque bit de la banque 1 s'enregistre en une seule frappe, par exemple en établissant les broches du port, puis en revenant à la banque 0 si vous avez terminé.

Très bien, par conséquent, nous avons notifié au PIC quelle broche sera probablement l'interruption, et où le bord à déclencher, que se passe-t-il dans le programme et le PIC à chaque fois que l'interruption se produit? Quelques trucs ont lieu. Tout d’abord, un «drapeau» est prévu.

Cela informe le processeur interne du PIC qu'une interruption s'est produite. Ensuite, le compteur de programmes (dont j'ai parlé dans le didacticiel précédent) pointe vers une adresse spécifique dans le PIC. Voyons rapidement tous ces éléments individuellement. Indicateur d'interruption Dans notre registre INTCON, le bit 1 est l'indicateur d'interruption, appelé INTF. À ce stade, chaque fois qu'une interruption survient, cet indicateur sera probablement fixé à 1.

Lorsqu'il n'y a pas d'interruption, l'indicateur est placé à 0. De plus, c'est à peu près tout ce qui est accompli. À ce stade, vous vous demandez peut-être 'quel est le point?'. Certes, même si cet indicateur est programmé sur 1, le PIC ne peut pas et ne réagira pas à une autre interruption. Par conséquent, exprimons que nous provoquons une interruption. Le drapeau sera probablement fixé à 1, et le PIC pourrait accéder à notre routine pour traiter l'interruption.

Lorsque cet indicateur n’était pas fixé à 1 et que le PIC était autorisé à continuer de répondre à l’interruption, le fait de pulser continuellement la broche pouvait permettre au PIC de revenir au début de notre routine d’interruption, et en aucun cas de la terminer. Pour en revenir à mon illustration du téléphone, cela revient à décrocher le téléphone, et immédiatement après avoir discuté, il recommence à sonner car une autre personne souhaite vous parler.

Il est conseillé de terminer un dialogue, puis de reprendre le téléphone pour parler à la personne suivante. Vous pouvez trouver un petit problème avec ce drapeau. Même si le PIC définit rapidement cet indicateur sur 1, il ne le remet pas à 0! Cette activité doit être exercée par le programmeur - c'est-à-dire vous. Cela peut être accompli sans effort, car j’en suis certain, et doit être réalisé une fois que le PIC a exécuté la routine d’interruption.

Emplacement de la mémoire Chaque fois que vous mettez le PIC sous tension pour la première fois, ou en cas de réinitialisation, le compteur de programme bascule pour adresser 0000h, ce qui pourrait être immédiatement au début de la mémoire de programme. Mais, en cas d'interruption, le compteur de programme indiquera l'adresse 0004h.

Par conséquent, pendant que nous composons notre programme qui aura des interruptions, nous devons d'abord informer le PIC de sauter par-dessus l'adresse 0004h, et de maintenir la routine d'interruption qui commence à l'adresse 0004h discrète du reste du programme.

Cela peut être facile à exécuter. Au départ, nous commençons notre programme avec une commande appelée ORG. Cette commande indique l'origine ou le début. Nous nous y tenons avec une adresse. Puisque le PIC commence à l'adresse 0000h, nous tapons ORG 0000h. Après cela, nous devons contourner l'adresse 0004h. Nous accomplissons cela en mettant une instruction GOTO, accompagnée d'une étiquette qui pointe vers notre programme principal.

Nous adhérons ensuite à cette commande GOTO avec un ORG de plus, ce moment avec l'adresse 0004h. Ce sera après cette commande que nous insérerons notre routine d'interruption. À ce stade, nous pourrions être en mesure de taper éventuellement notre routine d'interruption juste après la deuxième commande ORG, ou nous sommes en mesure de positionner une instruction GOTO qui pointe vers la routine d'interruption.

C'est vraiment lié à l'option de votre part. Pour informer le PIC qu'il propose arrivé à l'issue de la routine d'interruption il faut positionner la commande RTFIE vers la fin de la routine. Cette commande signifie le retour de la routine d'interruption. Pendant que le PIC le remarque, le compteur de programme indique la position finale à laquelle se trouvait le PIC avant l'interruption. Nous avons établi ci-dessous une brève section de code pour afficher ce qui précède:

Il y a quelques choses dont vous devez être informé lorsque vous utilisez des interruptions. L'initialisation tend à être que si vous utilisez le même registre dans votre programme principal et la routine d'interruption, sachez que les détails du registre seront très probablement modifiés lorsque l'interruption aura lieu.

Par exemple, utilisons le registre w pour transférer les données vers le programme principal du port A. Par conséquent, vous pouvez également utiliser le registre w dans la routine d'interruption pour déplacer les données d'une destination à une autre.

Au cas où vous ne seriez pas prudent, le registre w inclurait la dernière valeur qu'il a reçue pendant qu'il était dans la routine d'interruption, donc lorsque vous revenez de l'interruption, ces informations vont être livrées au port A plutôt que la valeur que vous possédiez auparavant l'interruption s'est produite.

Le moyen autour de cela est de sauvegarder momentanément les détails du registre w avant de l'utiliser à nouveau dans le programme d'interruption. Le second est le fait que vous pouvez trouver un délai entre le moment où une interruption a lieu et le moment où la suivante peut survenir. Bien que vous compreniez, le PIC possède une horloge extérieure, qui pourrait éventuellement être un cristal ou un combo résistance-condensateur.

Quelle que soit la fréquence de cette horloge, le PIC la divise par 4, après quoi l’emploie pour sa synchronisation interne. Par exemple, dans le cas où vous avez un cristal de 4 MHz lié à votre PIC, dans ce cas, le PIC exécutera les instructions à 1 MHz. Cette minuterie intérieure est connue sous le nom de cycle d'instruction. À ce stade, la fiche technique affirme (sans aucun doute en caractères minuscules) que vous devez activer 3 à 4 tours d'instructions entre les interruptions.

Mon serait d'activer 4 tours. La raison du retard est que le PIC a besoin de temps pour sauter à l'adresse d'interruption, le drapeau, et revenir loin du programme d'interruption. Par conséquent, gardez cela à l'esprit si vous travaillez avec un circuit alternatif pour activer une interruption pour le PIC.

À ce stade, un point important est le fait que si vous utilisez les bits 4 à 7 du port B comme interruption. Vous ne pouvez pas choisir des broches spécifiques sur le port B pour fonctionner comme une interruption.

Par conséquent, si vous autorisez ces broches, elles pourraient probablement toutes être obtenues. Par conséquent, par exemple, vous ne pouvez pas simplement avoir les bits 4 et 5 - les bits 6 et 7 seront probablement activés en même temps. Quel est exactement le but d'obtenir quatre bits pour représenter une interruption? Sûrement, vous pourriez avoir un circuit connecté au PIC, au cas où l'une des quatre lignes deviendrait haute, dans ce cas, cela peut être un problème que vous exigez que le PIC influence instantanément.

Une illustration de ceci pourrait être une alarme de sécurité domestique, dans laquelle quatre capteurs sont liés aux broches 4 à 7. Tout capteur spécifique peut inviter le PIC à déclencher une alarme, et la routine de signalisation d'alarme est la routine d'interruption. Cela évite de vérifier constamment les ports et permet au PIC de continuer avec différentes questions. Dans le prochain tutoriel, nous allons composer un programme pour gérer une interruption.

Nous avons traité beaucoup de bases dans le dernier tutoriel, donc je pense que le moment est venu que nous avons composé notre premier programme.

Le programme que nous écrirons compterait le nombre de fois où nous allumons un interrupteur, puis affichera le nombre.

Le programme comptera de 0 à 9, visible sur 4 LED sous forme binaire, avec l'entrée ou l'interruption sera probablement sur RB0.

La première chose que nous devons faire est d'informer le PIC de sauter par-dessus l'adresse sur laquelle pointe le compteur de programme chaque fois qu'une interruption a lieu.

Vous remarquerez que nous utilisons une méthode unique pour présenter des nombres hexadécimaux. Avant que je n'arrive, appliquez F9h dans lequel h indiquait hexadécimal. Nous pourrions écrire ceci comme 0xF9, qui est la structure que nous allons utiliser à partir de maintenant.

Maintenant, nous devons dire au PIC que nous allons utiliser des interruptions, et nous utilisons la broche 6 de RB0 comme broche d'interruption:

bsf INTCON, 7GIE - Activation d'interruption globale (1 = activée)
bsf INTCON, 4INTE - Activation interruption RB0 (1 = activation)
Je vais effacer l'indicateur d'interruption au cas où (je ne fais jamais confiance à rien!)
bcf INTCON, 1INTF - Effacer le bit de drapeau juste au cas où

Actuellement, nous devons établir nos 2 ports. Gardez à l'esprit que comme nous utilisons maintenant RB0 comme broche d'interruption, cela doit être établi en tant qu'entrée:

Nous allons utiliser une variable appelée COUNT pour stocker le nombre de comptages de commutateurs. Nous pourrions simplement incrémenter la valeur sur le port A, mais vous verrez pourquoi j'utilise une variable lorsque nous écrivons notre routine d'interruption.

Par conséquent, notre programme principal est composé, et à ce stade, nous devons informer le PIC comment procéder chaque fois qu'une interruption a lieu. Dans cet exemple, notre interruption sera probablement le commutateur. Tout ce que nous aimerions que le PIC soit un au COUNT réglable chaque fois que le commutateur est confiné.

Néanmoins, nous souhaitons juste montrer combien de fois le commutateur s'arrête de 0 à 9. Ci-dessus, j'ai déclaré que nous pourrions simplement avoir incrémenté la valeur sur le port A chaque fois qu'il y a une interruption. Cependant, le port A a 5 bits, au cas où nous aurions simplement incrémenté le port, nous aurons le plus grand nombre de 31. Il y a quelques explications pour lesquelles j'ai choisi de ne pas passer à 31.

Dans un premier temps, nous utiliserons un écran à 7 segments, qui ne pourra au maximum passer que de 0 à 15 (0 à F en hexadécimal). Ensuite, je souhaite également vous montrer quelques-unes des commandes arithmétiques sur lesquelles vous êtes tombé par hasard au cours des dernières leçons.

Par conséquent, nous allons continuer avec notre routine d'interruption. Actuellement, la première chose que nous devons accomplir est de stocker brièvement les détails de notre registre w, puisque nous l'avons appliqué pour déplacer le contenu de COUNT vers PORTA. Au cas où nous ne le sauvegardions pas, dans ce cas, nous pourrions être en mesure de fournir un nombre totalement différent à cause de notre arithmétique. Par conséquent, faisons cela en premier:

À ce stade, nous comprenons si la valeur de COUNT est de 9 ou plus. Ce que nous devons simplement accomplir maintenant est que si COUNT est supérieur à 9, remettez-le à 0, ou retournez au programme principal pour nous assurer que nous sommes en mesure de le livrer au port A. La commande BTFSS puisque vous comprenez que la suite
instruction dans le cas où l'indicateur de report est planifié, c'est-à-dire COUNT = 10:

La seule chose qui reste à faire maintenant est de saisir collectivement et de déterminer les valeurs de nos constantes, que nous sommes en mesure d'effectuer dès le début de notre programme.

A chaque fois que vous activez l'interrupteur, les LED vont compter en binaire de 0000 à 1010 puis revenir à 0000.

La figure suivante montre le schéma de circuit compatible avec le code expliqué ci-dessus. Fait intéressant, vous constaterez que le condensateur de synchronisation a été inclus dans la conception. C'est un joli petit stratagème grâce auquel vous avez la liberté d'éviter l'inclusion du condensateur au cas où vous n'en auriez pas avec vous pendant ce temps.

Ici, la capacité entre en jeu via la capacité parasite à travers la broche et la masse de l'oscillateur.
Bien sûr, cela ne semble pas être un moyen très intelligent d'éviter pratiquement un condensateur car la valeur parasite peut varier avec différentes conditions données.

Une autre section qui peut être observée dans le circuit est le réseau de dénonciation à travers le commutateur. Cela empêche les interférences lors de la commutation mécanique et empêche le PIC de se confondre si la commutation était une simple bascule ou plusieurs bascules.




Une paire de: Circuit de minuterie de moteur bidirectionnel programmable Un article: Comment fonctionnent les circuits Buck-Boost