mardi 9 avril 2013

Introductuion au PIC32, partie 2

Quelques précisions

Le datasheet intitulé PIC32MX1xx/2xx family datasheet qu'on retrouve en haut de cette page n'est qu'un résumé, pour chaque section il y a un autre document PDF disponible plus bas sur cette même page. Heureusement grâce aux librairies on n'a pas besoin de lire toute cette documentation en détail, il suffit de si référer pour éclaircir certains points lorsque la lecture des fichiers d'entête n'est pas suffisante.

En ce qui concerne la fréquence maximale, d'après la page mentionnée ci-haut la fréquence maximale des MCU des familles PIC32MX1xx/2xx est de 40Mhz pourtant dans le datasheet à la page 1 c'est indiqué que le core peut fonctionné à 50Mhz. Que faut-il croire? Quoi qu'il en soit j'ai configuré le PLL pour 50Mhz et ça semble fonctionné sans problème pour le moment mais ça ne veut rien dire, pour un programme plus complexe ça pourrait posé problème, c'est donc à surveiller.

En bas de cette page il y a des notes applicatives avec le code source disponible. Inutile de téléchargé le document pdf car il est inclus avec la package source.

J'ai oublié de mentionner certains faits importants à propos des PIC32 dans la première partie. Premièrement ces MCU fonctionnent à une tension maximale de 3,6 Volt et le core lui-même fonctionne à 1,8 Volt. Il y a donc à l'intérieur du MCU un régulateur de tension de type LDO (Low Drop Output) et la broche marquée Vcap (20 sur les DIL-28) est la sortie de ce régulateur. Il faut mettre un condensateur de 100nF entre les broches 19 (Vss) et 20 (Vcap) le plus prêt possible des broches. J'ai vu sur certains schéma un condensateur de 10uF, mais ce n'est pas nécessaire. Si vous voulez mettre un électrolytique entre 19 et 20 mettez quand même un 100nF céramique. Voir la section Quickstart dans le datasheet.

Les broches 26 et 27 nommées AVss et AVdd correspondent à l'alimentation pour les circuits analogiques, comparateurs et convertisseur A/N. Encore une fois on doit-mettre un condensateur 100nF entre 26 et 27 le plus près possible des broches. De plus au lieu de raccorder la broche 27 (AVdd) directement à V+ de l'alimentation on peut mettre une petite résistance de 10 ohm pour améliorer le filtrage. Un MCU qui fonctionne à 50Mhz ça produit beaucoup de fluatuations parasites sur l'alimentation.

Certaines broches tolèrent une tension de 5 volt. Celle-ci sont indiquées en gris sur l'image suivante:

Certaines sorties numériques peuvent-être configurées en mode drain ouvert. En plus des résistances pullup configurables il y a aussi des pulldown configurables. Voir la section I/O ports du datasheet à ce sujet.

Les entrées/sorties numériques ont 3 registres associés SET, CLEAR, INVERT. Ces registres fonctionnent de la façon suivante, les bits qui sont mis a 1 sont affectés par l'opération ceux qui sont à zéro demeurent inchangés. Pour chacune de ces fonctions il y a une macro. Dans le programme présenté dans la première partie, la macro mPORTBToggleBits() prend simplement la valeur qu'on lui donne en argument pour la mettre dans le registre INVERT. les 2 autres macros mPORTBSetBits() et mPORTBClearBits() font la même chose pour les registres SET et CLEAR. La première mets les bits sélectionnés à Vdd et la deuxième les mets à Vss. Donc dans le programme de la première partie mPORTBToggleBits(BIT_6|BIT_7|BIT_8) inverse ces bits chaque fois qu'elle est invoquée.

Il y a dans le PIC32MX110F016B beaucoup plus de périphériques qu'il n'y a de broches. On ne peut donc pas tous les utilisés en même temps. Associé à chaque port il y a un mutliplexeur d'entrées et un autre pour les sorties. Le rôle de ces multiplexeurs est d'assigner les périphérique aux broches. La déclaration des macros nécessaires à cette configuration se trouve dans le fichier pps.h (Peripheral Pin Select). Dans cette deuxième partie nous allons configurer le périphérique UART2 sur les broche PB10 (21) et PB11 (22).

Matériel requis

En plus du matériel de la première partie on a besoin d'un adapteur USB - rs232 - TTL. Si vous avez déjà un adapteur USB-RS232 il ne vous manque que l'adapteur de niveaux de tension entre celui-ci et le PIC. Le programme démo de cette partie va communiqué avec le PC hôte dans les 2 sens. A la réinitialisation il va lui envoyé le message "hello from blinky!". Ensuite il va répondre à des commandes pour allumer et éteindre les LEDS.

interface UART

Un nouvel élément est apparut au début de la procédure main. SYSTEMConfig() permet d'optimiser la configuration du MCU en fonction de la fréquece Fsys. Le premier argument est la fréquence en Hertz et le deuxième argument représente des valeurs de configurations combinées avec l'opérateur booléen OU. Il y a 3 paramètres qui peuvent-être ajustés. SYS_CFG_WAIT_STATES configure les cycles d'attente pour l'accès à la mémoire flash. Cette mémoire a une vitesse d'accès maximale de 30Mhz donc si le MCU fonctionne à plus de 30Mhz il faut insérer des cycles d'attente entre chaque lecture de la mémoire flash. SYS_CFG_PB_BUS sert à ajuster le diviseur de l'horloge du bus périphérique qui est limité à 80Mhz. Utile donc seulement pour les MCU qui fonctionnent au delà de cette fréquence. SYS_CFG_PCACHE configure la mémoire cache pre-fetch ceci ne concerne pas vraiment les 1xx/2xx car ils ne possèdent pas de cache pre-fetch seul des 3xx/4xx/5xx/6xx/7xx ont une telle mémoire. Vous trouverez plus d'information à ce sujet dans le fichier d'entête system.h et la documentation fournie par Microchip.

Voyons voir maintenant l'assignation des périphériques aux broches du MCU. N'importe quel périphérique ne peut pas être assigné à n'importe quel broche, il y a des groupes de périphériques. Chaque groupe correspond à un multiplexeur. Il a 4 multiplexeurs d'entrées et 4 pour les sorties. La façon la plus rapide de savoir sur quel broche on peut assigné un périphérique particulié est de regarder dans le fichier d'entête pps.h. Nous voulons utilisé le UART2. Commençon par la sortie TX. En ce qui concerne le PPS les périphériques s'appelle des fonctions. On commence donc par rechercher à quel multiplexeur (groupe) appartient la fonction U2TX et découvre cette fonction dans le groupe 4, OUT_FN_PPS4_U2TX. OUT pour sortie, FN pour fonction, PPS4 le multiplexeur, et U2TX la fonction. Il suffit ensuite de choisir sur quel broche du groupe OUT_PIN_PSS4_ on veut assigné cette fonction. Dans notre programme on a choisi OUT_PIN_PPS4_RBP10. Donc on a dans le programme:

PPSOutput(4, RPB10, U2TX);
Le premier argument est le numéro du multiplexeur, le deuxième la broche et le 3ième la fonction
Si on regarde pour U2RX on a que le groupe est 2 et parmis les broches d'entrée disponible on a IN_PIN_PSS2_RBP11. Donc dans le programme on a:
PPSInput(2, U2RX, RPB10);
Ici le premier argument est le groupe, le deuxième la fonction et le 3ième la broche. Pourquoi est-ce que ce n'est pas dans le même ordre que pour PPSOutput? mystère!.

Maintenant que le périphérique a été assigné à des broches il faut le configuré. On consulte uart.h. Avec un nom comme UARTConfigure() on ne risque pas de se tromper c'est surement ce qu'il nous faut. Le premier argument est l'id du périphique ici UART2 et le deuxième est le mode de fonctionnement UART_ENABLE_PINS_TX_RX_ONLY, on n'utilise pas les lignes CTS et RTS seulement TX et RX. Maintenant il faut déterminé le nombre de bits , la parité et les stops.

UARTSetLineControl(UART2, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
On a choisi 8 bits, pas de parité et 1 seul stop bit.
La vitesse de communication est sélectionnée avec:
UARTSetDataRate(UART2, mGetPeripheralClock(), BAUD_RATE);
la fréquence du bus périphérique est nécessaire pour programmer le baud rate generator, d'ou le deuxième argument mGetPeripheralClock(). BAUD_RATE est défini à 38400 plus haut dans le fichier.
Finalement il ne reste qu'à activer le périphérique avec UARTEnable(UART2, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX)); la transmission et la réception sont activés indépendemment l'un de l'autre.

Une partie du code de ce démo a été emprunté sur le forum de eevblog. C'est le cas de la function serial_print(). Dans la boucle while externe qui transmet le contenu du buffer, on attend que le périphérique soit disponible pour la transmission, while(!UARTTransmitterIsReady(UART2)); et on transmet un caractère à la fois, UARTSendDataByte(UART2, *buffer++);. On sort de la bouche while externe lorsque le caractère est nul. Finalement on transmet un CRLF pour terminer la ligne.

Avant de réinitialisé le MCU utilisé un émulateur de terminal (il s'appelle simplement terminal dans windows 7) et connectez le au port sur lequel est branché le MCU. Au démarrage le programme envoie le message "hello from blinky!" et ensuite allume la LED qui est sur PB6 et dans la boucle while attend simplement une commande. Utilisez les touches 'r' et 'b'. Il n'y a que ces 2 commandes. 'r' bascule l'état de la LED branchée à PB7 et 'b' celle sur PB8.

Formidable nous venons de tuer un moustique avec un bazooka! En pratique ce genre de micro-contrôleur est assé puissant pour hébergé un petit système d'exploitation et dans un boitier plus compacte que le DIL-28 ferait très bien pour fabriquer un lecteur MP3 et autre gadget plus exigeant que de faire clignoter des LEDs. On pourrait l'utiliser pour fabriquer un petit ordinateur dans le style 1980 mais qui serait dopé comme un cycliste professionel. A ce sujet je vous invite à consulter la page de Goeff Graham au sujet du maximite, construit avec un PIC32MX795F512.

Aucun commentaire:

Enregistrer un commentaire