Ayant obtenu des PIC18F4550 et 18F2550 en échantillons, j'ai décidé de les découvrir un peu plus.
L'environnement de développement est fourni par Microchip :
Ma plaque de test est on ne peut plus simple :
- Un quartz à 12MHz avec ses 2 capacités
- Le circuit de "Reset" composé d'une résistance et d'un condensateur
- Une alimentation 5 Volts tirée directement du port USB.
- Quelques résistances de Pull Up
Tous les exemples trouvés sur le web fontionne avec des quartz à 20 MHz, il suffit simplement de modifier les bits de configuration.
J'utilise le mode HSPLL, c'est à dire High Speed with PLL enabled. En utilisant un quartz 12MHz, il faut configurer le diviseur pour diviser par 3 la fréquence d'horloge pour obtenir un 4MHz permettant de générer par la suite un 48MHz nécessaire pour la gestion USB.
Il faut donc modifier la ligne :
#pragma config PLLDIV = 3
Utilisation du MSSP pour établir une communication I2C
Le PIC18f4550 peut être configurer pour établir une communication SPI, I2C maitre et esclave. L'utilisation est relativement simple. Il ne faut pas oublier de configurer les ports RB0 et RB1 en entrée tel qu'indiqué dans la documentation.
Le premier test a été d'allumer les célèbres leds connectées sur un PCF8574. Celui ci est configuré à l'adresse 0x40.
Ouverture de la communication I2C
Il ne faut pas oublier de configurer les ports en entrées avant:
//RB0 et RB1 en entrées
TRISBbits.TRISB0 = 1;
TRISBbits.TRISB1 = 1;
On utilise la fonction fournie par Microchip : OpenI2C()
Etant donné que l'on travaille en mode Master, il faut configurer la vitesse de la communication. La formule fournie par Microchip est la suivante :
clock = Fosc/(4*(SSPADD+1)).
On peut en tirer la formule suivante : SSPADD = ((Fosc/clock)/4)-1
Désirant travailler à une vitesse de 100 Kbits par secondes, et avec une vitesse interne de 48 MHz, il faut donc initialiser la valeur de SSPASS à 0x77.
SSPADD = ((48000000/100000)/4)-1 = (480/4)-1 = 120-1 = 119
Ecriture vers un composant I2C Slave
Voici la fonction utilisée pour écrire sur ce composant :
unsigned char Write(unsigned char cAddress, unsigned char cValue)
{
unsigned char bRet = 0x00;
IdleI2C(); //Attente du bus OK
StartI2C(); //Envoi de message de début
IdleI2C(); //Attente de la disponibilité du bus
putcI2C(cAddress); //Envoi de l'adresse
IdleI2C(); //Attenre de la disponibilité du bus
if (SSPCON2bits.ACKSTAT) //Si AckStat == 1, on n'a pas reçu d'acquittement
{
StopI2C(); //Envoi de la condition de stop
return bRet;
}
putcI2C(cValue); //On écrit la valeur
IdleI2C(); //Attente de disponibilité du bus
if (!SSPCON2bits.ACKSTAT ) //Si on reçoit un acquittement, on retourne 1
{
bRet = 0x01;
}
StopI2C();
return bRet;
}
Pour écrire 0x0F sur ce composant, il suffit d'appeler la fonction Write(0x40,0x0F);
Lecture sur le bus I2C
La lecture du composant m'a posé plus de problème, mais c'est relativement simple quand même. Voici donc la fonction de lecture :
unsigned char Read(unsigned char cAddress)
{
unsigned char bRet = 0x00;
IdleI2C(); //Attente du bus OK
StartI2C(); //Envoi de message de début
IdleI2C(); //Attente de la disponibilité du bus
putcI2C(cAddress); //Envoi de l'adress
IdleI2C(); //Attente de la disponibilité du bus
if (SSPCON2bits.ACKSTAT) //Si AckStat == 1, on n'a pas reçu d'acquittement
{
StopI2C(); //Envoi de la condition de stop
return bRet;
}
bRet = ReadI2C(); //Lecture I2C
NotAckI2C(); //Pas d'acquittement car on lit qu'un seul caractère
IdleI2C();
StopI2C(); //Envoi du stop
return bRet; //Retour de la valeur lue
}