Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Liaison I2C entre deux PIC (Maître-Esclace)
pic18f4580
Membre
Membre
Messages : 11
Enregistré en : mai 2016

#1 Message par pic18f4580 » lun. 2 mai 2016 17:33

Bonjour,

J'utilise MPLAB ICD2 v7.30 et mcc18 comme compilateur
Des PIC 18F4580
Résistances pull up : 2kohm. (J'avais des 10k, mais pour avoir plus de chances, j'ai baissé.)

Le but de mon projet est de faire une interface entre 2 bus CAN.
J'ai donc :
BUS CAN1 <--> PIC1 <--> BUS I2C <--> PIC2 <--> BUS CAN2
Mon BUS CAN fonctionne très bien depuis des années, mais l'I2C... j'ai du mal, et ça dure longtemps.
Merci donc pour votre aide.

Pour débuter, je voudrais que le maitre envoi une donnée à l'esclave.
Ce serait déjà un bon début.

Après, je voudrais que sur it timer, il dise soit :
-"voici un message CAN pour toi : "id, taille, data[4]"
Soit :
-"combien de messages CAN as tu à me donner ?" et "donne le(s) moi si tu en as"

Donc, pour commencer :
L'adresse d'esclave est 2.
La vitesse est très lente pour avoir un max de chance que ça fonctionne.

PS désolé, les tabulations ne tombent plus juste avec le copié collé.

Code du maitre :
main()

Code : Tout sélectionner


SSPADD 
= 249;//20kHz à 40MHz
OpenI2C(MASTER,SLEW_OFF); // Setup MSSP for master I2C 
 


it timer()
J'envoie en boucle à l'adresse "2" les données "4" et "6"

Code : Tout sélectionner


IdleI2C
();                                // ensure module is idle
SSPCON2bits.SEN = 1;            // initiate bus start condition
while(SSPCON2bits.SEN);        // wait until start condition is over
SSPBUF = 2;                         //adresse de l'esclave (2 pour écrire, 3 pour lire)
while( SSPSTATbits.BF );       // wait until write cycle is complete
IdleI2C();

SSPCON2bits.RSEN = 1;           // initiate bus restart condition
while ( SSPCON2bits.RSEN );    // wait until re-start condition is over
SSPBUF = 4;                         //donnée à envoyer
while( SSPSTATbits.BF );         // wait until write cycle is complete
IdleI2C();

SSPCON2bits.RSEN = 1;           // initiate bus restart condition
while ( SSPCON2bits.RSEN );      // wait until re-start condition is over
SSPBUF = 6;                             //une autre donnée à envoyer
while( SSPSTATbits.BF );             // wait until write cycle is complete
IdleI2C();

SSPCON2bits.PEN = 1;            // initiate bus stop condition
while ( SSPCON2bits.PEN );      // wait until stop condition is over 
 



Code de l'esclave :
main()

Code : Tout sélectionner


SSPADD                
= 2;    //adresse de l'esclave --> paire pour écrire(2), impaire pour lire (3)
OpenI2C(SLAVE_7,SLEW_OFF);    // Setup MSSP for slave I2C

PIE1bits.SSPIE        =1; // Master Synchronous Serial Port Interrupt Enable bit it ()
 


it I2c()

Code : Tout sélectionner

if( PIR1bits.SSPIF)        //it Master Synchronous Serial Port Interrupt Flag bit
{                                  //1 = The transmission/reception is complete (must be cleared in software)
                                   //0 = Waiting to transmit/receive

        donnees_it[0] = 26;
        donnees_it[1] = SSPBUF;
        ecriremessageCAN(46,&donnees_it[0],2,DONNEE);--> cette fonction envoie sur le bus CAN la valeur du buffer de reception SSPBUF (les "26" et "46" ne sont que des identifiants)
        --> ici, j'ai bien le "2" envoyé par le maitre dans SSPBUF
            
        --> j'
ai essayé de mettre PIR1bits.SSPIF à 0 ici, mais ça ne donne rien de mieux...

        SSPCON2bits.ACKDT = 0;           // set acknowledge bit state for ACK, je suis prêt à recevoir la prochaine donnée...
        SSPCON2bits.ACKEN = 1;           // initiate bus acknowledge sequence
        --> à mon avis, le problème vient d'ici, il me manque le "truc" pour passer à la donnée suivante
        temporisation20Microsecondes();temporisation5Microsecondes();

        donnees_it[0] = 26;
        donnees_it[1] = SSPBUF;
        ecriremessageCAN(46,&donnees_it[0],2,DONNEE);
        --> j'
ai toujours le "2", alors que je devrais avoir le "4" que le maitre a envoyé...
        SSPCON2bits.ACKDT = 0;           // set acknowledge bit state for ACK, je suis prêt à recevoir la prochaine donnée...
        SSPCON2bits.ACKEN = 1;           // initiate bus acknowledge sequence
        temporisation20Microsecondes();temporisation5Microsecondes();

        donnees_it[0] = 26;
        donnees_it[1] = SSPBUF;
        ecriremessageCAN(46,&donnees_it[0],2,DONNEE);
        --> pareil j'ai toujours le "2" dans SSPBUF, alors que je devrais avoir le "6" que le maitre a envoyé...
        SSPCON2bits.ACKDT = 0;           // set acknowledge bit state for ACK, je suis prêt à recevoir la prochaine donnée...
        SSPCON2bits.ACKEN = 1;           // initiate bus acknowledge sequence
        temporisation20Microsecondes();temporisation5Microsecondes();

        donnees_it[0] = 27;//debug
        donnees_it[1] = j++;
        ecriremessageCAN(46,&donnees_it[0],2,DONNEE);
        --> j'
ai bien de temps en temps j="0" "1" "2" "3" etc...
        --> ca me permets de compter ne nombre de messages reçus
        
--> mais la donné reçue est toujours le même "2" 
        
        PIR1bits
.SSPIF = 0;    // on ré-autorise l'interruption
}
 


Donc voila, comme il y a toujours "2" dans le buffer de reception de l'esclave, soit son adresse, j'ai essayé ça pour que le maitre puisse recharger le buffer :
SSPSTATbits.BF = 0;//SSPBUF doit être lu afin de remettre BF à 0.
Mais ca ne change rien.

Avec ce code, l'esclave reçoit
"2" "2" "2" "0" au lieu de "2" "4" "6" "0"
"2" "2" "2" "1" au lieu de "2" "4" "6" "1"
"2" "2" "2" "2" au lieu de "2" "4" "6" "2"
"2" "2" "2" "3" au lieu de "2" "4" "6" "3"
"2" "2" "2" "4" au lieu de "2" "4" "6" "4"
"2" "2" "2" "5" au lieu de "2" "4" "6" "5"
"2" "2" "2" "6" au lieu de "2" "4" "6" "6"
etc...

Donc merci pour votre aide !

Liaison I2C entre deux PIC (Maître-Esclace)
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#2 Message par Jérémy » lun. 2 mai 2016 18:06

Bonjour ,

Bienvenue à toi sur FantasPic . J’espère que tu trouvera une solution à ton problème.

Je me suis essayé il y quelques mois, tu y trouveras peut être des pistes : Lien
Mais j'avais baissé les bras . Ce n'est que partie remise, car l'I²C est vraiment courant et pratique.

Tiens nous au jus si tu trouve ça m’intéresse .
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Liaison I2C entre deux PIC (Maître-Esclace)
Guest
Confirmé
Confirmé
Messages : 800
Enregistré en : mars 2017

#3 Message par Guest » lun. 2 mai 2016 19:50

Bonjour

Je ne connais pas cette fonction

Code : Tout sélectionner

ecriremessageCAN(46,&donnees_it[0],2,DONNEE)


Tu peux nous dire ou est la variable qui doit contenir dans cette fonction (2 4 6 )
-C'est pas 46
-Ni donnees_it[0] elle contient SSPBUF a la passe 0,1,2,et a la passe 3, j++
-pas 2
-il nous reste DONNEE et DONNEE est charge par quoi,enfin si j'ai bien compris
Allez un peu de lumiere je te l'avoue je ne vois rien?

Apres lecture :wink: ,Donc les donnees recherchées sont fournit par donnees_it[i] dans SSPBUF, pourquoi ne pas faire alors

Code : Tout sélectionner

ecriremessageCAN(46,&SSPBUF,2,DONNEE)
Pour les passe 0,1,2

C'est quoi donnees_it[0] ?

Comment fais tu pour passer a donnees_it[1], qui elle contient bien ce que tu désires ?? plus je lis ton code au moins je comprends quelles explications sont nécessaires car la les passes 0,1,2 sont identiques donc normal que tu es toujours 2

A+

Liaison I2C entre deux PIC (Maître-Esclace)
Guest
Confirmé
Confirmé
Messages : 800
Enregistré en : mars 2017

#4 Message par Guest » lun. 2 mai 2016 23:37

bonsoir
tu as essayé de remplacer donnees_it[0] par donnees_it[1] pour les passes 1 et 2 afin de sortir 4 et 6 dans it I2c()

A+

Liaison I2C entre deux PIC (Maître-Esclace)
pic18f4580
Membre
Membre
Messages : 11
Enregistré en : mai 2016

#5 Message par pic18f4580 » mar. 3 mai 2016 07:51

Bonjour,
Merci à vous.

ecriremessageCAN(identifiant can,unsigned char tableau[ ; ; ; ],taille du message (0 à 4), type donnée ou requette)
Cette fonction est mon seul lien avec le PIC, elle envoie sur le bus CAN 0 à 4 unsigned char (en fonction de "taille" qui va de 0 à 4), qui sont dans le tableau[].
Puis, une autre carte me dit tout ce qu'il y a sur ce bus par RS232 et arrive sur le PC, où chaque message CAN est traité et affiché comme il se doit.
ex:

Code : Tout sélectionner


donnees_it
[0] = 26;
donnees_it[1] = SSPBUF;
ecriremessageCAN(46,&donnees_it[0],2,DONNEE);
 


Le PIC envoie sur le bus CAN un message CAN du type :
id CAN 46, tableau[26;SSPBUB;x;x]
Et l'ordi comprend que l'id 46 c'est un message qui me sert à debugger la carte qui marche pas encore, tab[0]==26 correspond à SSPBUF, donc il va m'afficher dans une case à l'écran tab[1], soit la valeur de SSPBUF.
Et j'ai sur l'écran la valeur de SSPBUF qui s'affiche, soit "2".

Autre exemple bidon, si je fais :

Code : Tout sélectionner


donnees_it
[0] = 7;
donnees_it[1] = 47;
donnees_it[1] = 3;
donnees_it[1] = 5;
ecriremessageCAN(10,&donnees_it[0],4,DONNEE);
 

L'ordi reçoit le message n°10 avec les unsigned char [7;47;3;5] dans un tableau, et m'affiche à l'écran "il est 7 heure 47, on est le 03/05".

J'utilise certains identifiants pour le debbug, qui sont noyés parmi d'autres messages sur le BUS.

Mais tout ceci fonctionne, c'est l'I2C qui coince.

Je me suis essayé il y quelques mois, tu y trouveras peut être des pistes : Lien


--> je vais voir...

Liaison I2C entre deux PIC (Maître-Esclace)
Guest
Confirmé
Confirmé
Messages : 800
Enregistré en : mars 2017

#6 Message par Guest » mar. 3 mai 2016 10:35

bonjour

Ce que j'ai pu comprendre c'est :
si tu fais:
ecriremessageCAN(46,&donnees_it[0],2,DONNEE); tu as 26
et si tu fais
ecriremessageCAN(46,&donnees_it[1],2,DONNEE);tu as le SSPBUF et dans ta routine it I2c() tu n'as JAMAIS SSPBUF puis tu ne fais jamais donnees_it[1]

ou alors je nais pas encore compris :wink:

Liaison I2C entre deux PIC (Maître-Esclace)
pic18f4580
Membre
Membre
Messages : 11
Enregistré en : mai 2016

#7 Message par pic18f4580 » mar. 3 mai 2016 10:54

ecriremessageCAN() me permets seulement d'envoyer un tableau de 0 à 4 éléments sur le bus CAN, c'est à dire d'écrire un message CAN : d'où son nom.
Ca n'a rien à voir avec l'I2C.
C'est plus facile que d'utiliser le debbuger de l'ICD2, de faire du pas à pas et de voir sur l'outil de Microchip la mémoire du PIC. Que de toute façon, je ne sais plus faire.

Mon problème n'est pas là.
Mon problème, c'est que le buffer SSPBUF de l'esclave du bus I2C n'est pas mis à jour.
L'esclave I2c ne reçoit que son adresse(c'est déjà un bon début), c'est à dire la première donnée qu'envoie le maitre sur le Bus I2C.
C'est un peu comme si l'esclave ne dis pas "buffer SSPBUF du driver bien lu par le programme, je peux le remplir avec ce que me donne le maitre", ou "maitre, va-y, donne moi la donnée I2C suivante, je t'écoute".
Si ça se trouve, c'est le maitre qui envoie toujours "2", soit l'adresse de l'esclave... et non "4" puis "6".
Je coince...

Liaison I2C entre deux PIC (Maître-Esclace)
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#8 Message par Jérémy » mar. 3 mai 2016 11:14

Bonjour,

Tu n'as pas d'analyseur logique ? Ca aurait aidé pour voir le problème de dialogue, si c'est un problème du maitre ou de l'esclave
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Liaison I2C entre deux PIC (Maître-Esclace)
pic18f4580
Membre
Membre
Messages : 11
Enregistré en : mai 2016

#9 Message par pic18f4580 » mar. 3 mai 2016 12:01

Juste un oscillo à 2 entrées.
J'ai vu que ça bouge sur le bus, je ne suis pas allé plus loin pour le moment.

Si quelqu'un a une solution toute faite, je suis preneur.

Ou alors, je me fais une carte :
Bus CAN1-PIC1-RS232-PIC2-Bus CAN2.
Je maitrise le 232 entre un PIC et un PC, je pense qu'un 232 entre 2 PIC devrait se faire tout seul, je n'ai pas essayé.
Mais l'I2c, c'est plus simple. Pas besoin de MAX232 et ses condos.
Ca fait un peu bricolage un RS232 de 3 cm de long sur la même carte...

Liaison I2C entre deux PIC (Maître-Esclace)
Gérard
Avatar de l’utilisateur
Expert
Expert
Messages : 1640
Âge : 65
Enregistré en : septembre 2015
Localisation : Alsace - Haut-Rhin

#10 Message par Gérard » mar. 3 mai 2016 20:14

Tu parles bus I2C ou bus CAN?
Le 18/04/19 je suis devenu papy de jumeaux, le 01/09/23 une petite cousine des jumeaux est née.


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 51 invités