Pour plus d'informations sur la programmation sur microcontrôleur PIC, consultez la section PIC.
PIC18F, deuxième
Le dimanche 29 janvier 2006 à 20:32 - Lien permanent
Après quelques essais, j'ai résolu les problèmes évoqués dans un premier billet sur les PIC !
Les problèmes électriques
Ces problèmes étaient à l'origine d'un certain non-déterminisme dans le fonctionnement du PIC. En vrac, voici les améliorations que j'ai apportées :
- le PIC a deux pattes Vss (8 et 19). Je n'avais connecté que la 19, mais cela peut visiblement causer des soucis. J'ai donc connecté les deux ;
- j'ai déplacé la capa de découplage (100 nF) entre Vdd et Vss pour la mettre le plus proche possible du PIC. Ça tombe bien, les deux pattes sont adjacentes (20 et 19)
- dans certaines configurations (et bien que n'étant pas a priori concerné), la patte 1 est traitée comme /MCLR (reset). Je l'ai donc relié à Vdd par l'intermédiaire d'une résistance de pull-up (10 k). Cette résistance ne pose visiblement pas de problème pour la programmation (la patte 1 est aussi Vpp).
Après avoir apporté ces modifications, le fonctionnement est devenu entièrement déterministe et reproductible, mais ça ne fonctionnait toujours pas comme je le voulais...
La programmation
On ne le dira jamais assez, RTFM !
Je me suis rendu compte du problème en visualisant les sorties RB0..7 sur le débugueur de MPLAB. Il est très bien fait, avec un mode « oscillo ». Hé bien lorsque j'envoyais un signal carré sur RB0..7, RB2 et RB3 restaient obstinément à 0, alors que les autres fonctionnaient !
Après lecture du datasheet, j'ai fini par localiser le problème : RB0..3 sont sur les mêmes pattes que les ports analogiques AN8..12, ce qui pose souci... Il faut donc indiquer que l'on veut utiliser les ports RBi sur ces pattes, et non les ANi. Cela se fait à l'aide du registre ADCON1 (décrit p. 254). Au passage, j'en ai profité pour reprendre la procédure d'initialisation de PORTB de la page 114.
Au final, le programme suivant fonctionne de façon très satisfaisante :
#include <p18f2455.h> #pragma config WDT = OFF #pragma config FOSC = INTOSC_XT #pragma config LVP = OFF void tempo(unsigned char val) { int j; for(j=0; j<700; j++) { PORTB = val; } } void main(void) { // PORTB initialization, from p. 114 LATB = 0; // clear data latches ADCON1 = 0x0E; // RB0:RB4 are multiplexed with AN8:AN12 // select digital outputs, see p. 254 TRISB = 0; // direction: output pins while(1) { tempo(0b00010000); tempo(0b00001000); } }
Si je ne fais qu'une seule itération dans la boucle (au lieu de 700), je génère un signal de fréquence 384 Hz (merci l'oscillo...)
Je pense qu'avant d'initialiser correctement PORTB, certaines pattes prenaient des valeurs « instables », et donc le fonctionnement réel pouvait dépendre de pas mal de facteurs... Comme la déclaration d'une variable inutile, par je ne sais quelle chaîne cause-conséquence complètement tordue.
Bilan
Je sais donc écrire un programme de base pour le PIC 18F2455. Prochaine étape : l'USB !
Commentaires
Brutal. Déboggage de 3 semaines de galères
le problème lié à la déclaration de la variable i est très surprenant et semblerait plus être lié à un problème de compilateur qu'un problème de câblage du micro. Il faudrait jeter un coup d'oeuil au code assembleur généré par C18.
bonne continuation,
Jeremie
Jeremiek : je ne pense pas qu'il y ait réellement de problème du compilateur. Je pense plutôt que selon la position des instructions dans le code généré, des timings (ou autre chose) pouvaient être différents, ce que modifiait l'allure des phénomènes d'instabilité induits par la mauvaise configuration de PORTB... De toute façon, le comportement est non-spécifié avec un PORTB mal initialisé, alors je n'ai pas trop vu d'intérêt à chercher à comprendre ;-)