Étape 3: ChipKIT Microcontrollers avec jetons PIC32
Nous allons commencer avec ma famille préférée personnelle de microcontrôleurs, le chipKIT. (Si vous le souhaitez, l’esquisse abrégée pour l’Arduino UNO est à l’étape suivante, mais la logique sera expliquée ici). À l’aide de processeurs 32bits PIC32 Microchip, la chipKIT a beaucoup plus de mémoire, presque deux fois plus de broches d’e/s et s’exécute beaucoup plus rapidement que les cartes Arduino comparables, alors si vous avez besoin de ce punch supplémentaire, je recommande de vous pencher sur obtenir un. (C’est aussi une bonne idée pour vous familiariser avec autant d’appareils que possible de vous rendre aussi utile que possible à l’employeur, si c’est votre but.)
Chaque broche de I/O sur un microcontrôleur est reliée au moins trois registres différents. (Broches qui ont plusieurs fonctions qui leur sont associées ont plusieurs autres, p. ex. PWM et I2C/SPI/UART). Des trois nous intéresse ici, est le registre TRISx qui détermine que si le code pin doit être une entrée ou une sortie, où « x » désigne les TRIS nous travaillons avec puisqu’il y en a plusieurs (la fonction de() pinModedéfinit TRISx). Définissant un peu dans les TRISx comme un 1 fixera la broche correspondante comme entrée, et il s’ensuit que mettre comme un 0 fixera la broche en tant que sortie. La prochaine est le registre LATx, qui est où nous assignons un NIP établi en tant que sortie haute (1) ou faible (0) (digitalWrite() définit LATx). Le dernier est le registre PORTx, et c’est où on peut lire l’état actuel de l’axe lorsqu’elle est définie à une entrée (digitalRead() lit PORTx). Un bit « 1 » dans PORTx indique que le pin d’entrée correspondant détecte une valeur élevée de la logique. Chaque registre est mis à jour avec l’horloge du bus périphérique alors que le code s’exécute donc votre statut d’entrée/sortie sera en temps réel. Techniquement vous pouvez lire/écrire dans tous les trois de ces registres, mais vous avez vraiment envie d’écrire pour le TRISx s’inscrire une fois dans votre configuration() déclaration au début de votre esquisse. Vous pouvez récupérer l’état de LATx et PORTx et utiliser ces données selon les besoins, mais écrire un 1 au registre LATx d’entrer un NIP qui est désigné comme un intrant ne fera rien parce qu’il ne peut pas afficher (vous configurez comme une entrée au registre TRISx). Confus encore ?
Garder sur le transport par camion, il sera judicieux.
Pour initialiser TRISx dans le programme d’installation(en), vous devez tout d’abord savoir quel Registre et des morceaux est liés aux quelles broches. En utilisant le tableau de brochage (voir ci-joint le fichier .pdf ci-dessous) pour la chipKIT Uno32, nous pouvons voir que 26→33 broches correspondent très bien pour vous inscrire E, bits 0→7. (Je trouve plus facile d’utiliser des fraises séquentielles dans un registre. Plus tard, nous devrons faire certaines opérations au niveau du bit, et il simplifie les choses.) Il devrait faire sens alors que nous sera mise TRISE, 0→7 bits. En regardant le code, nous avons déterminé que broches 26→29 serait LEDs et 30→33 seraient les commutateurs. Pins 26→29 carte à TRISE bits 0→3. LED sont de sortie, donc bits 0→3 obtenir un 0. Pins 30→33 carte à TRISE bits 4→7. Interrupteurs sont entrés, ainsi bits 4→7 obtenir un 1. En examinant le registre bit par bit, il faut les 8 derniers bits de TRISE d’être 1111 0000. Prendre une seconde pour s’assurer que vous comprenez pourquoi.
Nous pourrions simplement assigner la valeur, en utilisant une valeur hexadécimale de 0xF0 ou une valeur binaire de 0b11110000, directement au TRISE avec la ligne
TRISE = 0XF0 ;
mais nous courons le risque de modifier par inadvertance des autres les bits les plus significatifs dans le registre. N’oubliez pas que nous traitons avec des registres 16-32 bits avec le PIC32. (Tableau 4-27 sur pg 73 de la feuille de données pour le PIC32MX320F128, je sais que TRISE seulement me permet d’accéder aux 10 bits les moins significatifs, mais j’ai choisi de protéger le registre entier de 16 bits comme une question de bonne pratique.) Nous devons veiller à ce que nous mettons seulement les bits exactes, que nous avons besoin tout en laissant les autres bits dans quelque État qu’ils sont actuellement en sorte nous n’accidentellement jack substance vers le haut. Pour ce faire, nous utilisons une technique appelée masquage et certains opérateurs bit à bit de la logique. Disons que TRISE commence avec une valeur de 0b1101 0010 1001 1011. À l’aide de l’opérateur de bits OR logique "|", nous TRISE ou avec 0b0000 0000 1111 0000 (0x00F0). Lorsque nous ou, là où il y a un « 1 », le résultat sera toujours un seul. S’il y a un « 0 », le résultat sera déterminé par l’état de l’autre opérande. Retour à notre exemple, si nous 0b1101 OR 0010 1011 de 1001 avec 0b0000 0000 1111 0000, nous nous retrouvons avec 0b1101 1011 1111 0010. Nous pouvons voir que 4→7 bits sont maintenant tous les 1, c’est ce que nous voulions.
En utilisant une logique semblable et l’opérateur AND, nous prenons alors TRISE et et avec 0b1111 1111 1111 0000. Une fois que nous, et avec un « 0 », le résultat est toujours 0. ANDing avec un « 1 » résultats dans l’état de l’autre opérande. Donc nous avons 0b1101 0010 1111 1011, et avec 0b1111 1111 1111 0000 et le résultat est 0b1101 0000 1111 0010. Les quatre derniers bits, 0→3, sont maintenant 0, c’est encore ce que nous souhaitions. Notez que les 8 bits les plus significatifs sont laissés intacts. Les deux opérations (et/ou) peut être inversé sans affecter le résultat. Les deux lignes de code pour cela sont les suivantes :
TRISE TRISE DE = | 0x00F0 ; 0b0000 0000 1111 0000
TRISE = TRISE & 0xFFF0 ; 0b1111 1111 1111 0000
Si il devient plus facile, les valeurs hex/bin peuvent être désignés comme variables int avant installation().
Maintenant que nous avons TRISE mis, (pinMode()), nous pouvons maintenant écrire notre boucle() déclaration. En regardant la version plus courte et simplifiée du code dans la dernière étape, remarquez que nous lisons l’état de la broche d’entrée (digitalRead() = PORTE) et en le mappant sur la broche de sortie (digitalWrite() = LATE). Si tard = PORTE, mais avec un léger ajustement. N’oubliez pas que les boutons sont liés à 4→7 morceaux de PORTE et les LEDs sont liés à la fin 0→3 bits. Si nous écrivons la fin = PORTE, nous écrivons l’état de 4→7 bits PORTE à fin 4→7 bits, pas en retard 0→3 bits. Nous devons changer les données PORTE sur les espaces de droite 4 afin qu’il corresponde le placement peu en retard. Autrement dit, si la PORTE lit 0b0010 1101 1111 0000, mèches 4→7 sont tous riches. Nous déplacer les données de 4 bits (0b0000 0010 1101 1111) et assigner cette nouvelle valeur trop tard, réglage 0→3 bits haut et tous les 4 LEDs s’allument. Un changement au niveau du bit est simple pour le processeur à faire et n’affectera pas les données actuelles sur la PORTE. Les données de PORTE sont réellement copiées à un registre provisoire et c’est celui qui est manipulé si nécessaire. Pour PORTE de changer les valeurs, la seule consiste à modifier les États du bouton. Voici la ligne de code :
LATE = PORTE >> 4 ;
Vous remarquerez que je n’essaie pas de faire n’importe quel masque ici lors de l’assignation PORTE trop tard. La raison est que tardive n’est pas utilisé pour autre chose que de la sortie, et si le bit spécifique dans TRISE n’est pas défini en tant que sortie, un 1 sur que peu en retard n’aura aucun effet. Le même est vrai pour la PORTE lorsque vous essayez de le lire. Vous pouvez attacher un bouton à n’importe quel bit dans la PORTE, mais à moins que vous attribuiez PORTE comme intrant dans TRISE, appuyant sur le bouton ne changera pas la valeur dans le registre. Toutes les modifications sont errants et aléatoire parce que la broche a sans résistance de/vers le bas du pull-up.
En utilisant 4 bits séquentielles dans la PORTE, extraire les données est une simple question de décalage au niveau du bit, qui est une opération ridiculement bas, pour ce qui est la puce est en termes de temps et les ressources nécessaires. Si nous avions utilisé dispersés bits et registres autour du Conseil, nous aurions besoin de faire quelques ORing et masquage et ANDing, mais nous pourrions obtenir les données. Nous avons également évité appelant pinMode(), digitalRead()et digitalWrite(), donc notre code devrait prendre moins de place sur la puce car ces fichiers d’arrière-plan ne doivent pas être chargé. Nous allons voir combien nous avons besoin maintenant d’espace.
Voici le code :
Ce code prend 10 lignes sans commentaires et la plupart de qui sont les structures de() () et bouclerequise configuration. Il y a seulement 3 lignes de code réel. 3.
Cette compilation en MPIDE pour la chipKIT Uno32 nécessite 4792 octets, une réduction de 1532 octets de la version courte à l’étape précédente qui a coûté 6324 octets.
L’étape suivante montre le même code mais spécifiquement pour le chip ATMEL.