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 !