Pour plus d'informations sur la programmation sur microcontrôleur PIC, consultez la section PIC.
Analyseur logique du PICkit 2 et fréquence des PIC
Le lundi 17 août 2009 à 11:40 - Lien permanent
Depuis quelques temps, le logiciel de programmation du PICkit 2 dispose d'une fonction analyseur logique et UART, extrêmement pratique. Intéressons-nous tout d'abord à l'analyseur logique. Il peut analyser trois canaux en parallèle, sur les broches PGC, PGD et AUX du PICkit 2. Ce qui est génial, c'est que les broches PGD et PGC sont déjà connectées sur tous les montages qui supportent la programmation sur place (ICSP), et qu'elles sont à ma connaissance multiplexées sur tous les PIC avec des I/O numériques. De plus, on essaie en général de ne pas utiliser les I/O multiplexées avec PGD et PGC, donc il y a de fortes chances que ces pins soient inutilisées dans le montage, et qu'on puisse donc les réquisitionner pour faire du débug sur les signaux ! Sans modifier un montage existant, sans déplacer le PICkit entre la phase de programmation et la phase d'exécution du programme, on peut donc analyser des signaux émis par le programme. Pratique, non ?
Application
Souvent, les débutants ont du mal à configurer correctement l'horloge de leurs PIC, surtout les modèles complexes comme les PIC18, et au final ne savent pas très bien à quelle fréquence ils fonctionnent. Cela peut conduire à de bonnes séances d'arrachage de cheveux... Il peut donc être intéressant de vérifier la configuration de l'horloge avant toute chose.
Je vous propose d'utiliser la broche PORTB7, multiplexée avec PGD, donc connectée au canal 1 de l'analyseur, pour vérifier la fréquence d'horloge. L'idée est de faire exécuter une suite d'instructions dont on connaîtra précisément la longueur, entre des variations du signal sur PORTB7. Considérons le programme suivant, pour PIC18F2455/2550/4455/4550 :
#include <p18f2455.h> #pragma config FOSC = INTOSC_XT // activation de l'oscillateur interne #pragma config PBADEN = OFF // port B en I/O numériques #pragma config MCLRE = OFF // on n'utilise pas MCLR #pragma config WDT = OFF // pas de watchdog void main() { OSCCON = 0x42; // configuration de l'oscillateur // OSCCON<6:4> = 100 => oscillateur interne à 1 MHz // OSCCON<1:0> = 10 => sélection de l'oscillateur interne TRISB = 0; // PORTB en sortie boucle: PORTBbits.RB7 = 0; Nop(); Nop(); Nop(); Nop(); PORTBbits.RB7 = 1; Nop(); Nop(); goto boucle; }
La boucle va mettre PORTB7 à 1 une partie du temps, puis à 0 l'autre partie du temps. Pour savoir précisément combien de temps dure la boucle (en termes de cycles d'instruction), il faut absolument regarder le listing en langage machine, car le compilateur peut toujours ajouter des choses imprévues. Dans MPLAB, faire View → Diassembly Listing. Dans ce cas, il n'y a pas de surprise :
15: boucle: 16: PORTBbits.RB7 = 0; Nop(); Nop(); Nop(); Nop(); 00C8 9E81 BCF 0xf81, 0x7, ACCESS 00CA 0000 NOP 00CC 0000 NOP 00CE 0000 NOP 00D0 0000 NOP 17: PORTBbits.RB7 = 1; Nop(); Nop(); 00D2 8E81 BSF 0xf81, 0x7, ACCESS 00D4 0000 NOP 00D6 0000 NOP 18: goto boucle; 00D8 D7F7 BRA 0x462
On a donc 5 instructions avec PORTB7 à 0 (en comptant le BCF, bit clear), puis 4 instructions avec PORTB7 à 1 (en comptant le BSF, bit set). Or, toutes les instructions du PIC s'exécutent en un cycle d'instruction, sauf celles qui affectent le compteur ordinal (PC), qui durent deux cycles lorsque le compteur ordinal est effectivement affecté. C'est ici le cas du BRA
, qui durera deux cycles. Au final, on se trouve donc avec une boucle de 10 cycles d'instruction, donc 5 avec PORTB7 à 0, et 5 avec PORTB7 à 1.
Chargeons le programme dans le PIC, alimentons-le via le PICkit, et lançons l'analyseur (Tools → Logic Tool). Il faut configurer une condition de déclenchement, une fréquence, puis cliquer sur « Run ». On obtient alors un résultat du type suivant :
On retrouve bien la forme de résultat attendue sur le canal 1. Le curseur (en bleu), permet d'aller mesurer des temps. On voit ainsi que le temps d'exécution de la boucle est de 41 µs. Cela correspond-il à la configuration prévue pour l'oscillateur ? 41 µs donne environ 4 µs par cycle d'instruction (souvenez-vous, 10 cycles dans la boucle). Or sur PIC, un cycle d'instruction correspond à 4 cycles de l'horloge du CPU. Cela amène donc le cycle d'horloge à 1 µs, ce qui correspond bien à la valeur voulue, 1 MHz.
Note sur l'utilisation de l'oscillateur interne des PIC18F2455/2550/4455/4550
Il ne suffit pas d'activer l'oscillateur interne avec les bits de configuration #pragma config FOSC = INTOSC_XT
. Selon ma compréhension de la spec, cela se contente d'activer l'oscillateur interne. Il reste alors à la configurer et le sélectionner à l'aide du registre OSCCON
:
- avec
OSCCON<6:4>
on sélectionne la fréquence, ici 100 pour 1 MHz (voir datasheet). C'est la valeur par défaut. - avec
OSCCON<1:0>
on sélectionne l'oscillateur. Il faut mettre 10, sans quoi par défaut le PIC utilisera l'horloge primaire, c'est-à-dire celle générée à partir du quartz externe, ce qui n'est pas du tout ce que l'on veut. 10 sélectionne l'oscillateur interne. - les autres bits sont à laisser à 0.
Dans l'exemple ci-dessus, j'avais donc mis OSCCON
à 0x42
. Laissez toujours le nibble de droite à 2 en mode interne, et utilisez le nibble de gauche pour sélectionner la fréquence.