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 ---
Idée, bugs, propositions .......
Problème de séquence I2C entre deux PIC
Serge
Amateur
Amateur
Messages : 163
Enregistré en : septembre 2018

#51 Message par Serge » lun. 4 mai 2020 10:46 lien vers la Data-Sheet : Cliquez ici

Alors, avec tous les essais réalisés, il me semble qu'en fait, si on envoie plusieurs Octets à la suite, derrière une seule adresse, on doit en fait les récupérer avec une interruption par octet sur l'esclave et non pas à la suite sur la même interruption. Car de cette façon, ça ne plante plus.
Mais c'est bien dommage, car c'est plus difficile à trier à la réception sur l'esclave.

Problème de séquence I2C entre deux PIC
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#52 Message par satinas » lun. 4 mai 2020 10:57 lien vers la Data-Sheet : Cliquez ici

Chez moi, cela ne plante pas, tu as essayé le code ci-dessus ?
Sans toucher au code du maître, tu remplaces juste l'interruption de l'esclave.
A tester dans une boucle ou par interruption. Ca partait toutes les 10ms sans problème (Fosc = 8MHz).
Bien sur chaque fois que ça ne marche pas, il faut resetter le pic, car les bits d'erreur I2C restent coincés.

Problème de séquence I2C entre deux PIC
Serge
Amateur
Amateur
Messages : 163
Enregistré en : septembre 2018

#53 Message par Serge » lun. 4 mai 2020 13:55 lien vers la Data-Sheet : Cliquez ici

En fait, si dans mon programme je réceptionne chaque Octet par interruption, ça ne plante plus.
Mais si je réceptionne plusieurs Octets dans une seule interruption, ça fonctionne aussi..... jusqu'à ce que ça plante lors d'autre séquences intervenantes.

Et toujours derrière le premier octet data.

Problème de séquence I2C entre deux PIC
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#54 Message par satinas » lun. 4 mai 2020 14:10 lien vers la Data-Sheet : Cliquez ici

Si tu envoies les 3 octets toutes les 10 ms, cela tient combien de temps sans erreur ?
Avec mon premier programme qui ne fait que recevoir ?
Avec mon deuxième programme qui reçoit et stocke ?
Pas de réponse style fût du canon :)

Problème de séquence I2C entre deux PIC
Serge
Amateur
Amateur
Messages : 163
Enregistré en : septembre 2018

#55 Message par Serge » lun. 4 mai 2020 14:20 lien vers la Data-Sheet : Cliquez ici

C'est pas un problème de temps, c'est dès que j'envoie une séquence qui n'est pas la même. que celle qui cycle en premier....
Difficile à t'expliquer, je vais essayer de t'envoyer le soft dès que j'ai un moment.

Problème de séquence I2C entre deux PIC
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#56 Message par satinas » lun. 4 mai 2020 14:23 lien vers la Data-Sheet : Cliquez ici

ok, mais fais des sous-programmes, il faut que ce soit lisible.
Dans mes essais j'incrémentais aussi les données à chaque envoi, et ça passait.
Et j'ai un poussoir sur le maître, qui permet d'arrêter le flot de données en fin d'envoi, puis le relancer
Pour ne pas interrompre une transmission en cours.

Problème de séquence I2C entre deux PIC
Serge
Amateur
Amateur
Messages : 163
Enregistré en : septembre 2018

#57 Message par Serge » lun. 4 mai 2020 21:38 lien vers la Data-Sheet : Cliquez ici

Voilà mon Programme de test pour l'esclave.
Il fonctionne en réception d'Ecriture du Maître, Mais ne fonctionne pas en Réception de Lecture du Maître.
J'ai deux règles (Horizontale et verticale)
4 entrées pour les 4 directions
Si on appuie sur un bouton, on envoie une séquence d'un octet pour activer sur l'autre pic le déplacement correspondant d'un moteur pas à pas
Si on relache le bouton, on envoie une séquence d'arrêt suivie d'une lecture de deux mots (4 Octets) pour avoir la position de la règle.
Et pendant ce temps une led "Chien de garde" clignotte par le biais de l'I2c" pour valider le bon fonctionnement I2C (Sortie20)

Code : Tout sélectionner

; ESCLAVE
; PIC 18F2620

  #CONFIG
    CONFIG  OSC = INTIO67         ; oscillator   interne
    CONFIG  FCMEN = OFF           ; Fail-Safe Clock Monitor disabled
    ;CONFIG  IESO = ON            ; Oscillator Switchover mode disabled
    CONFIG  PWRT = ON            ; PWRT disabled
    CONFIG  BOREN = SBORDIS       ; Brown-out Reset enabled in hardware only (SBOREN is disabled)
    CONFIG  BORV = 3              ; Minimum setting
    CONFIG  WDT = OFF             ; WDT enabled
    ;CONFIG  WDTPS = 128                ;
    ;CONFIG  WDTEN = 1
    CONFIG  PBADEN = OFF          ; PORTB<4:0> pins are configured as digital I/O on Reset
    ;CONFIG  LPT1OSC = ON         ; Timer1 configured for higher power operation
    CONFIG  MCLRE = OFF           ; MCLR pin enabled; RE3 input pin disabled
    CONFIG  LVP = OFF              ; Tension de Programmation Standard (si non RB5 n'est pas utilisable)
    ;CONFIG  WTDCON = ON           
  #ENDCONFIG
  define OSC 8

    OSCCON=%01110010  ' Bit 7 Inocupé sur instruction de Someil,   4-5-6 8Mh
   
    TRISA=%00000011         '1= entrée
    TRISB=%00000000         '0= sortie
    TRISC=%00011000         ' C6 en sortie TX UART   C7 en entrée RX UART C6 doit etre mis en entrée c'est le UART qui le met à 0 sortie

    ADCON1=%00001101 'bit 4 et 5 référence tension + et -   et config portA 0 et 1 -2-3-4
    ADCON2=%10100000   ' bit 7à0 Justifie à gauche le résultat dans ADRH ou ADRL  ensuite 8 TAD et Fosc/4    ' a confirmer selon mesures réalisées
    T0CON=%11000101    ' bit 7=Timer0_Enabled 6=1=8Bits (si non=16 bits) 5=source_clock_TOCK1 (si non TOCK0) 4=Front montant_de_TOCK1  3=0=Préscale_assigned   2-0=Valeur_de Préscale_TMR0 (110)

    'Module MMSP I2C
    'ADRESSE       ' en Esclave mettre l'adresse de la carte dans SSPADD
    SSPADD = $82 '$13 à 8MHz   ' en Maitre ($27=100kHz $0C=308kHz $09=400kHz @ 20 MHz)  = 8MHz   'si Maitre, ce registre contient la vitesse du réseau et si Esclave, contient l'adresse de l'esclave
                     ' adresse des valeurs= $84
    SSPSTAT.7 = 0  ' SMP: Controle de la vitesse du bus: 1=vitesse standard 100 Khz  0=vitesse haute 400 Khz
    SSPSTAT.6 = 0  ' CKE:  SMBus Select 1=enable SMBus  0=desable SMBus
    SSPSTAT.5 = 0  ' D/A: Data/Address en mode Maitre: (réservé). en esclave: 1=dernier byte reçu ou transmis=DATA si non 0= Adresse
    SSPSTAT.4 = 0  ' P: Stop bit    si=1 StB à été détecté  si=0 n'as pas été détecté
    SSPSTAT.3 = 0  ' S: Start bit(1) si=1 StB à été détecté  si=0 n'as pas été détecté
    SSPSTAT.2 = 0  ' R/W: Read/Write Information bit (I2C mode only) en mode Esclave 1=Read 0=Write en mode Maitre 1= Transmission en cours 0= pas de transmission en cours
    SSPSTAT.1 = 0  ' UA: Update Address bit (10-Bit Slave mode only) 1=Indique que l'utilisateur doit mettre à jour l'adresse dans le registre de SSPADD
                   ' 0=L'adresse ne doit pas être mise à jour
    SSPSTAT.0 = 0  ' 0=BF: Buffer Full Status bit    en mode Transmission 1= SSPBUF est plein 0=Vide
                                                    'en mode Réception    1= SSPBUF est plein (sans inclure l'ACK et le StB)  0=vide
    'Config I2c Esclave
    SSPCON1.7 = 0   'WCOL  Maitre: 1= Ecriture dans SSPBUF en transmission non valide (erreur) effacer le bit par soft
                    '     Esclave: 1= le registre SSPBUF  est écrit en transmission non finie (erreur) effacer le bit par soft
    SSPCON1.6 = 0   'SSPOV Réception: 1= SSPBUF contient toujours un octet tandis qu'il en reçois un autre. (erreur) effacer le bit par soft
                    '   Transmission: 1= Sans importance.
    SSPCON1.5 = 1   'SSPEN  1= I2c Enable et configure les pins SDA et SCL
    SSPCON1.4 = 1   'CKP  Esclave:  1= Horloge de sortie  0= temps bas utilisé pour monter les données
                    '      Maitre:  1= Non utilisé
    SSPCON1.3 = 0   'SSPM  1111 = I2C Slave mode, 10-bit address with Start and Stop bit interrupts enabled
    SSPCON1.2 = 1         '1110 = I2C Slave mode, 7-bit address with Start and Stop bit interrupts enabled
    SSPCON1.1 = 1         '1011 = I2C Mode Maitre COntrolé par soft. (Inopérant en Slave)
    SSPCON1.0 = 0         '1000 = I2C Master mode, clock = FOSC/(4 * (SSPADD + 1))
                          '0111 = I2C Slave mode, 10-bit address
                          '0110 = I2C Slave mode, 7-bit address
                          'Bit combinations not specifically listed here are either reserved or implemented in SPI mode only.


    'Gestion I2c
    SSPCON2.7 = 0   'GCEN  en mode Esclave seulement si =1 Enable Interruption si appel général à l'adresse(0000h) réception dans le SSPSR  si=0 Desable l'appel générale
    SSPCON2.6 = 0   'ACKSTAT Transmission Maitre seulement 1= pas d'acknowledge reçu de l'esclave 0= acknowledge reçu
    SSPCON2.5 = 0   'ACKDT En Réception Maitre seulement  1= Pas d'acknowledge  0= acknowledge
    SSPCON2.4 = 0   'ACKEN En Réception Maitre seulement  1= acknowledge sur SDA et SCL et transmission ACKDT Automatiquement (clear Hardwaire)  0= bus inocupé
    SSPCON2.3 = 0   'RCEN  Mode Maitre seulement  1= Enable mode réception I2c
    SSPCON2.2 = 0   'PEN  Mode Maitre seulement  1= Condition STOP sur SDA et SCL  0= libre  (clear hardwaire)
    SSPCON2.1 = 0   'RSEN Mode Maitre seulement  1= Condition Repeated START sur SDA et SCL  0= libre   (clear hardwaire)
    SSPCON2.0 = 0   'SEN Maitre:  1= Condition START sur SDA et SCL   Esclave: 1= maintient l'horloge tant que l'esclave transmet

    INTCON.7 = 1    'GIE/GIEH: Interruptions générales Enabled
    INTCON.6 = 1   'PEIE/GIEL: Interruptions Périphériques Enabled
    INTCON.5 = 0    'TMR0IE: Interruption Compteur_0 Overflow Enabled
    INTCON.4 = 0 '1   'INT0IE: Interruptions Externes Enabled
    INTCON.3 = 0 '1   'RBIE: Interruption Ports "B" Enabled
    INTCON.2 = 0    'TMR0IF: Flag de TMR0
    INTCON.1 = 0    'INT0IF: Flag Interruptions externes
    INTCON.0 = 0    'RBIF: Flag Interruptions des ports B_7-4
       
    INTCON2.7 = 1   'RBPU: PullUp du Port B Desabled (=1) sur les 8 bits

    PIE1.3=1  '1    'SSPIE  1=Enabled Interruption Port Série synchrone Maitre
 

 


    WHILE OSCCON.2=0 : WEND    ' attente que la fréquence de l'oscillateur soit stable 

       
               'mise à 0 des sorties
    PORTA=0
    PORTB=0
    PORTC=0
   
    'Sort var byte[21]
 
    'Entrées
    Tr var PORTA.0           ' Trimmer de Carte
    An_1 var PORTA.1      ' Entrée analogique 4-20 mA
               
    'Sorties
    Sort1 var PORTA.2           ' Voyant Bleu   
    Sort2 var PORTA.5           ' Voyant Vert 
    Sort3 var PORTA.7           ' Voyant Jaune
    Sort4 var PORTC.2           ' Voyant Rouge
    Sort5 var PORTC.1           ' Buzzer
    Sort6 var PORTC.0           ' Réserve
    Sort7 var PORTA.3           ' Relais Cte Sec_1
    Sort8 var PORTA.4           ' Relais Cte Sec_2
    Sort9 var PORTB.5           ' Sens Moteur_1
    Sort10 var PORTB.6          ' Pulses Moteur_1
    Sort11 var PORTB.7          ' Sens Moteur_2
    Sort12 var PORTB.4          ' Pulses Moteur_2
    Sort13 var PORTB.3          ' Sens Moteur_3
    Sort14 var PORTB.2          ' Pulses Moteur_3
    Sort15 var PORTB.1          ' Voyant Jaune BP
    Sort16 var PORTB.0          ' Voyant Vert BP
    Sort17 var PORTC.7          ' EV Montée Poinçon
    Sort18 var PORTC.6          ' EV Descente Poinçon
    Sort19 var PORTC.5          ' Contacteur Groupe hydraulique
    Sort20 var PORTA.6          ' Led de contrôle I2c et PIC
    'Led var sort20
    Pontet var PORTE.3
   
    SCL var PORTC.3             ' Ligne de l'I2C Horloge  Borne 1 "H"
    SDA var PORTC.4             ' Ligne de l'I2C Data     Borne 2 "D"
 
   
    Ad_Affich con $78              ' Adresse de l'afficheur
    Ad_Mere_E con $80              ' Adresse de la carte Mère en Ecriture
    Ad_Mere_L con $81              ' Adresse de la carte Mère en Lecture
    Pic2620_CM_EA con $82          ' Adresse du PIC de sorties de la carte Mère en Ecriture 1er data
    Pic2620_CM_LA con $83          ' Adresse du PIC de sorties de la carte Mère en Lecture 1 
    Pic2620_CM_EB con $84          ' Adresse du PIC de sorties de la carte Mère en Ecriture 2 ème data
    Pic2620_CM_LB con $85          ' Adresse du PIC de sorties de la carte Mère en Lecture 2
    Pic2620_CE_EA con $86          ' Adresse du Pic De sorties de la carte Esclave en écriture 1
    Pic2620_CE_LA con $87          ' Adresse du Pic De sorties de la carte Esclave en lecture 1
    Pic2620_CE_EB con $88          ' Adresse du Pic De sorties de la carte Esclave en écriture 2
    Pic2620_CE_LB con $89          ' Adresse du Pic De sorties de la carte Esclave en lecture 2   


    On_Off var bit              ' bit faible du premier octet I2c (état de la variable de sortie)
    Reste var bit               ' si Différence Verticale ou Horizontale
    Origine var bit             ' Si Origines faites
    Arret_1 var bit             ' Capteurs des origines Moteur 1
    Arret_2 var bit             ' Capteurs des origines Moteur 2
    Arret_3 var bit             ' Capteurs des origines Moteur 3
    Recu var bit                ' Indicateur de réception
    Premier_Data var byte       ' premier Octet reçu
    Data_2 var byte             ' second Octet reçu
    Data_3 var byte             ' troisième Octet reçu



    i var byte                  ' Boucle

         
    Variable var byte[31]       ' Variables de sortie au dessus des 20 sorties HARD
    Valeur_1 var byte[21]         ' Valeur de l'octet 2 derrière la Variable
    Valeur_2 var byte[21]         ' Valeur de l'octet 2 derrière la Variable
    Decale var byte             ' pour extraire le N° de variable
    Sens var byte               ' Valeur du troisième octet qui détermine le sens
    Poubelle var byte           ' Variable poubelle
    Envoie var word             ' Variable d'envoie d'un Octet en réponse ( ou deux)
   
    GD var word
    HB var word
   
    sort20=0                    ' Led de clignotement
    on_off=0
    Premier_data=0

    GD=0
    hb=0
 
    data_2=0
    data_3=0
    envoie(1)=0
    envoie(2)=0

    recu=0

     
    for i=0 to 20          ' Mise à "0" des Variables possibles au dessus des sorties hard (107+20=127 on compte pas le 0)
        variable(i)=0
        valeur_1(i)=0
        valeur_2(i)=0
    next i
   
    for i =1 to 10
        variable(i+20)=0
    next i
   

   
   On Interrupt Goto Int     
   
   
   
Prg:
    if recu then
        recu=0
        on_off=premier_data.0
        decale=premier_data >> 1
        'premier_data=0
        select case decale
            case 1            ' Voyant Bleu
            sort1=on_off
            case 2            ' Voyant Vert
            sort2=on_off
            case 3            ' Voyant Jaune
            sort3=on_off
            case 4            ' Voyant Rouge
            sort4=on_off
            case 5            ' Buzzer
            sort5=on_off
            case 6            ' Réserve
            sort6=on_off
            case 7            ' Relais Cte Sec_1
            sort7=on_off
            case 8            ' Relais Cte Sec_2
            sort8=on_off
            case 9            ' Sens Moteur_1   ' Moteur vertical
            sort9=on_off
            case 10           ' Pulses Moteur_1
            sort10=on_off
            case 11           ' Sens Moteur_2   ' idem moteur 1
            sort11=on_off
            case 12           ' Pulses Moteur_2
            sort12=on_off
            case 13           ' Sens Moteur_3    ' Moteur Horizontal
            sort13=on_off
            case 14           ' Pulses Moteur_3
            sort14=on_off
            case 15           ' Voyant Jaune BP
            sort15=on_off
            case 16           ' Voyant Vert BP
            sort16=on_off
            case 17           ' EV Montée Poinçon
            sort17=on_off
            case 18           ' EV Descente Poinçon
            sort18=on_off
            case 19           ' Contacteur Groupe hydraulique
            sort19=on_off
            case 20           ' Led de contrôle I2c et PIC
            sort20=on_off
            case 21           ' Variable des Origines
            variable(1)=on_off
            case 22           ' Origine 1 atteinte si =1
            variable(2)=on_off
            case 23           ' Origine 2 atteinte si =1
            variable(3)=on_off
            case 24           ' Origine 3 atteinte si =1
            variable(4)=on_off
            case 25             ' déplacement Manuel vers le bas
            variable(5)=on_off
            case 26             ' déplacement Manuel vers le haut
            variable(6)=on_off
            case 27             ' déplacement Manuel vers la droite
            variable(7)=on_off
            case 28             ' déplacement Manuel vers la gauche
            variable(8)=on_off
            case 29             ' réserve
            variable(9)=on_off
            case 30             ' réserve
            variable(10)=on_off ' les 30 premières variables n'ont pas de "Valeurs()" (un seul octet)
           
            case is < 50       ' Variables binaires complémentaires jusqu'à 40 avec valeurs word
            variable(decale-20)=on_off
            ' Les valeurs correspondantes sont décalées de -10 à partir de la Variable 11
            valeur_1(decale-30)=data_2
            valeur_2(decale-30)=data_3
            case else
            'err=10  ' à modifier l'erreur           
        end select

    endif
   
   
    'Déplacement règles

    if variable(5) and hb<50000 then        ' Déplacement manuel vers le bas
        sort9=0                                 ' on met le sens à l'opposé des  moteurs
        sort11=0
        do
            sort10=1 : sort12=1 : pauseus 100       ' pause = 100 soit  20 Cm en 10 secondes ou 2Cm seconde ' si pause = 1000 soit 20 Cm en 81 secondes ou 2,5 mm seconde
            sort10=0 : sort12=0 : pauseus 100
            sort10=1 : sort12=1 : pauseus 100     
            sort10=0 : sort12=0 : pauseus 100
            hb=hb+1

        loop until premier_data=50 or hb>50000
    endif
    if variable(6) and hb>0 then               ' Déplacement manuel vers le haut
        sort9=1                                 ' on met le sens vers les moteurs
        sort11=1
        do
            sort10=1 : sort12=1 : pauseus 100       ' pause = 100 soit  20 Cm en 10 secondes ou 2Cm seconde ' si pause = 1000 soit 20 Cm en 81 secondes ou 2,5 mm seconde
            sort10=0 : sort12=0 : pauseus 100
            sort10=1 : sort12=1 : pauseus 100     
            sort10=0 : sort12=0 : pauseus 100
            hb=hb-1

        loop until premier_data=52 or hb=0
    endif   
    if variable(7) and gd<50000 then             ' Déplacement manuel vers la Droite
       sort13=0                                     ' on met le sens  à l'opposé du  moteur
       do
            sort14=1 : pauseus 100     ' pause = 100 soit  20 Cm en 10 secondes ou 2Cm seconde ' si pause = 1000 soit 20 Cm en 81 secondes ou 2,5 mm seconde
            sort14=0 : pauseus 100
            sort14=1 : pauseus 100     
            sort14=0 : pauseus 100
            gd=gd+1

       loop until premier_data=54 or gd>50000 
    endif
    if variable(8) and gd>0 then            ' Déplacement manuel vers la Gauche
       sort13=1        ' on met le sens vers le  moteur
       do
            sort14=1 : pauseus 100     ' pause = 100 soit  20 Cm en 10 secondes ou 2Cm seconde ' si pause = 1000 soit 20 Cm en 81 secondes ou 2,5 mm seconde
            sort14=0 : pauseus 100
            sort14=1 : pauseus 100     
            sort14=0 : pauseus 100
            gd=gd-1

       loop until premier_data=56 or gd=0   
    endif
   
   
   
   
   
   
   
    goto prg   
    ; ------------------------------------------------

'Intéruptions_Intéruptions_Intéruptions_Intéruptions_Intéruptions_
   disable   
Int:

    if PIR1.3 then                                'Flag de l'I2c
        if not SSPSTAT.2 and not SSPSTAT.5 then      ' Si c'est l'adresse en écriture
            do while not SSPSTAT.0 : loop         ' Attente buffer plein
            poubelle = SSPBUF

            do while not SSPSTAT.0 : loop       ' Attente buffer plein
            premier_data = SSPBUF               ' Les 30 premières commandes n'ont qu'un Octet

        'elseif not SSPSTAT.2 and SSPSTAT.5 then
           
        '    if  data_2=0 then                   ' les 30 premieres commandes n'ont qu'un octet sur les 127 dispo+1
        '        do while not SSPSTAT.0 : loop   ' Attente buffer plein
        '        data_2= SSPBUF
        '    else
        '        do while not SSPSTAT.0 : loop   ' Attente buffer plein
        '        data_3= SSPBUF
        '
        '        recu=1
        '    endif
           
             recu=1

        elseif SSPSTAT.2 then                   '  c'est l'adresse en mode Lecture
            do while not SSPSTAT.0 : loop         ' Attente buffer plein
            poubelle=SSPBUF
            'SSPCON1.4 = 0                   ' CKP  Esclave:  0= maintient CLK bas
                                            ' SSPCON2.0=1    ' Maintient l'Horloge  ??
           
            envoie=hb/256                   ' Calcul de l'Octet (poid fort du "Word")
            SSPBUF=envoie                   ' Premier octet à envoyer
            do while not SSPSTAT.0 : loop
            SSPCON1.4 = 1                   ' CKP  Esclave:  1=  on libère SCL
           
            'SSPCON1.4 = 0                   ' CKP  Esclave:  0= maintient CLK bas
           
            envoie=hb-(envoie*256)          ' Calcul de l'octet (poid faible du "Word")
            SSPBUF=envoie                   ' Deuxième octet à envoyer
            do while not SSPSTAT.0 : loop
            SSPCON1.4 = 1                   ' CKP  Esclave:    1=  on libère SCL
           
            envoie=gd/256                   ' Calcul de l'Octet (poid fort du "Word") 2ème mot
            SSPBUF=envoie                   ' troisième octet à envoyer
            do while not SSPSTAT.0 : loop
            SSPCON1.4 = 1                   ' CKP  Esclave:   0= Blocage CLK
           
            envoie=gd-(envoie*256)
            SSPBUF=envoie                   ' quatrième octet à envoyer
            do while not SSPSTAT.0 : loop
            SSPCON1.4 = 1                   ' CKP  Esclave:   0= Blocage CLK
        else
            'if premier_data<=61 then recu=1
           
        endif

        PIR1.3=0
    endif


    resume
    enable         
   

Problème de séquence I2C entre deux PIC
Serge
Amateur
Amateur
Messages : 163
Enregistré en : septembre 2018

#58 Message par Serge » lun. 4 mai 2020 21:58 lien vers la Data-Sheet : Cliquez ici

Et voici le code du pic Maître qui va avec.

Code : Tout sélectionner

; ------------------------------------------------
;
 Master
; ------------------------------------------------
  #CONFIG
    CONFIG  OSC = INTIO67         ; oscillator   interne 
    CONFIG  FCMEN 
= OFF           ; Fail-Safe Clock Monitor disabled
    
;CONFIG  IESO = ON            ; Oscillator Switchover mode disabled
    CONFIG  PWRT 
= ON             ; PWRT disabled
    CONFIG  BOREN 
= SBORDIS       ; Brown-out Reset enabled in hardware only (SBOREN is disabled)
    CONFIG  BORV = 3              ; Minimum setting
    CONFIG  WDT 
= OFF             ; WDT enabled
    
;CONFIG  WDTPS = 128                 ;
    ;CONFIG  WDTEN = 1
    CONFIG  PBADEN 
= OFF          ; PORTB<4:0> pins are configured as digital I/O on Reset
    
;CONFIG  LPT1OSC = ON         ; Timer1 configured for higher power operation
    CONFIG  MCLRE 
= OFF           ; MCLR pin enabled; RE3 input pin disabled
    CONFIG  LVP 
= OFF             ; Tension de Programmation Standard (si non RB5 n''est pas utilisable)
    ;CONFIG  WTDCON = ON            
  
#ENDCONFIG
    define OSC 8

    OSCCON
=%01110010  
 
    TRISA
=$FF        
    TRISB
=%11111110
    TRISC
=$FF         
    TRISD
=$FF
   

    
'ADRESSE'       ' en Esclave mettre l''adresse de la carte dans SSPADD'
    SSPADD = $13   '$13 à 8MHz'   
    
    SSPSTAT.7 
= 0  ' SMP: Controle de la vitesse du bus: 1=vitesse standard 100 Khz  0=vitesse haute 400 Khz'
    SSPSTAT.6 = 0  ' CKE:  SMBus Select 1=enable SMBus  0=desable SMBus'
    SSPSTAT.5 = 0  ' D/A: Data/Address en mode Maitre: (réservé). en esclave: 1=dernier byte reçu ou transmis=DATA si non 0= Adresse'
    SSPSTAT.4 = 0  ' P: Stop bit    si=1 StB à été détecté  si=0 n''as pas été détecté'
    SSPSTAT.3 = 0  ' S: Start bit(1) si=1 StB à été détecté  si=0 n''as pas été détecté'
    SSPSTAT.2 = 0  ' R/W: Read/Write Information bit (I2C mode only) en mode Esclave 1=Read 0=Write en mode Maitre 1= Transmission en cours 0= pas de' 
    SSPSTAT.1 
= 0  ' UA: Update Address bit (10-Bit Slave mode only) 1=Indique que l''utilisateur doit mettre à jour l''adresse dans le registre de SSPADD'
                   ' 0=L''adresse ne doit pas être mise à jour'
    SSPSTAT.0 = 0  ' 0=BF: Buffer Full Status bit    en mode Transmission 1= SSPBUF est plein 0=Vide '
                                                    'en mode Réception    1= SSPBUF est plein (sans inclure l''ACK et le StB)  0=vide'
    'Config I2c Maitre'
    SSPCON1.7 = 0   'WCOL  Maitre: 1= Ecriture dans SSPBUF en transmission non valide (erreur) effacer le bit par soft'
                    '     Esclave: 1= le registre SSPBUF  est écrit en transmission non finie (erreur) effacer le bit par soft '
    SSPCON1.6 = 0   'SSPOV Réception: 1= SSPBUF contient toujours un octet tandis qu''il en reçois un autre. (erreur) effacer le bit par soft'
                    '   Transmission: 1= Sans importance.'
    SSPCON1.5 = 1   'SSPEN  1= I2c Enable et configure les pins SDA et SCL'
    SSPCON1.4 = 0   'CKP  Esclave:  1= Horloge de sortie  0= temps bas utilisé pour monter les données'
                    '      Maitre:  1= Non utilisé '
    SSPCON1.3 = 1   'SSPM  1111 = I2C Slave mode, 10-bit address with Start and Stop bit interrupts enabled'
    SSPCON1.2 = 0         '1110 = I2C Slave mode, 7-bit address with Start and Stop bit interrupts enabled '
    SSPCON1.1 = 0         '1011 = I2C Firmware Controlled Master mode (Slave Idle)'
    SSPCON1.0 = 0         '1000 = I2C Master mode, clock = FOSC/(4 * (SSPADD + 1))'
                          '0111 = I2C Slave mode, 10-bit address '
                          '0110 = I2C Slave mode, 7-bit address '
                          'Bit combinations not specifically listed here are either reserved or implemented in SPI mode only.' 


    
'Gestion I2c' 
    SSPCON2.7 
= 0   'GCEN  en mode Esclave seulement si =1 Enable Interruption si appel général à l''adresse(0000h) réception dans le SSPSR  si=0'
    SSPCON2.6 = 0   'ACKSTAT Transmission Maitre seulement 1= pas d''acknowledge reçu de l''esclave 0= acknowledge reçu'
    SSPCON2.5 = 0   'ACKDT En Réception Maitre seulement  1= Pas d''acknowledge  0= acknowledge '
    SSPCON2.4 = 0   'ACKEN En Réception Maitre seulement  1= acknowledge sur SDA et SCL et transmission ACKDT Automatiquement (clear Hardwaire)  0=' 
    SSPCON2.3 
= 0   'RCEN  Mode Maitre seulement  1= Enable mode réception I2c '
    SSPCON2.2 = 0   'PEN  Mode Maitre seulement  1= Condition STOP sur SDA et SCL  0= libre  (clear hardwaire)'
    SSPCON2.1 = 0   'RSEN Mode Maitre seulement  1= Condition Repeated START sur SDA et SCL  0= libre   (clear hardwaire)'
    SSPCON2.0 = 0   'SEN Maitre:  1= Condition START sur SDA et SCL   Esclave: 1= maintient l''horloge tant que l''esclave transmet'

    'Interruptions'
    INTCON.7 = 1    'GIE/GIEH: Interruptions générales Enabled '
    INTCON.6 = 1    'PEIE/GIEL: Interruptions Périphériques Enabled '
    INTCON.5 = 1    'TMR0IE: Interruption Compteur_0 Overflow Enabled'
    INTCON.4 = 0    'INT0IE: Interruptions Externes Enabled '
    INTCON.3 = 0    'RBIE: Interruption Ports "B" Enabled'
    INTCON.2 = 0    'TMR0IF: Flag de TMR0'
    INTCON.1 = 0    'INT0IF: Flag Interruptions externes'
    INTCON.0 = 0    'RBIF: Flag Interruptions des ports B_7-4'
    
    INTCON2.7 
= 1   'RBPU: PullUp du Port B Desabled (=1) sur les 8 bits '

    ADCON1=%00000110    ' bit 4 et 5 référence tension + et -   et config portA 0 et 1'  
    ADCON2
=%10100100    ' bit 7à=0 Justifie à gauche le résultat dans ADRH ou ADRL  ensuite 8 TAD et Fosc/4'    
    T0CON
=%11000101     ' bit 7=Timer0_Enabled 6=1=8Bits (si non=16 bits) 5=source_clock_TOCK1 (si non TOCK0) 4=Front montant_de_TOCK1 ' 
    WHILE OSCCON.2
=: WEND    ' attente que la fréquence de l''oscillateur soit stable ' 

   
'Entrées'
    Potar var PORTA.0           ' Trimmer de Carte '
    Anal var PORTA.1      ' Entrée analogique 4-20 mA '
               
    Sortie_led var PORTB.0      
' Sortie '
    Entree_1 var PORTB.1        ' Entrée 1 '
    Entree_2 var PORTB.2                  
    Entree_3 var PORTB.3        
' BP_D  '
    Entree_4 var PORTB.4        ' Origine_3 '
    Entree_5 var PORTB.5        ' BP_M     '
    Entree_6 var PORTB.6        ' Origine_2 '
    Entree_7 var PORTB.7        ' BP_Enreg  '
    Entree_8 var PORTE.3        ' Origine_1 '  
    Entree_9 var PORTA.0         
    Entree_10 var PORTA.1        
    Entree_11 var PORTA.2         
    Entree_12 var PORTA.3         
    Entree_13 var PORTA.4         
    Entree_14 var PORTA.5       
    Entree_15 var PORTE.0        
    Entree_16 var PORTE.1        
    Entree_17 var PORTE.2      
    Entree_18 var PORTA.6       
' BP_Haut'  
    Entree_19 var PORTA.7          
    Entree_20 var PORTC.1       
' BP_Bas '   
    Entree_21 var PORTC.0        
    Entree_22 var PORTD.0       
' BP_Gauche '
    Entree_23 var PORTC.2       
    Entree_24 var PORTD.2       
' BP_Droite '
    Entree_25 var PORTD.1      
    Entree_26 var PORTC.5        
    Entree_27 var PORTD.3        
    Entree_28 var PORTC.7        
    Entree_29 Var PORTC.6         
    Entree_30 var PORTD.5          
    Entree_31 var PORTD.4          
    Entree_32 var PORTD.7          
    Entree_33 var PORTD.6          



    
    SCL var PORTC.3             
' Ligne de l''I2C Horloge  Borne 1 "H" '
    SDA var PORTC.4             ' Ligne de l''I2C Data     Borne 2 "D" '

    
    Ad_Affich con 
$78               ' Adresse de l''afficheur'
    Ad_Mere_E con $80               ' Adresse de la carte Mère en Ecriture'
    Ad_Mere_L con $81               ' Adresse de la carte Mère en Lecture'
    Pic2620_CM_EA con $82           ' Adresse du PIC de sorties de la carte Mère en Ecriture 1er data '
    Pic2620_CM_LA con $83           ' Adresse du PIC de sorties de la carte Mère en Lecture 1 ' 
    Pic2620_CM_EB con 
$84           ' Adresse du PIC de sorties de la carte Mère en Ecriture 2 ème data '
    Pic2620_CM_LB con $85           ' Adresse du PIC de sorties de la carte Mère en Lecture 2 '
    Pic2620_CE_EA con $86           ' Adresse du Pic De sorties de la carte Esclave en écriture 1'
    Pic2620_CE_LA con $87           ' Adresse du Pic De sorties de la carte Esclave en lecture 1 '
    Pic2620_CE_EB con $88           ' Adresse du Pic De sorties de la carte Esclave en écriture 2'
    Pic2620_CE_LB con $89           ' Adresse du Pic De sorties de la carte Esclave en lecture 2'   
    Pose con 10
           
    Cli var bit
    Bip var bit
    Led var bit
    mem_bp_bas var bit
    mem_bp_haut var bit
    mem_bp_droite var bit
    mem_bp_gauche var bit
    
    mem_bp_bas
=0
    mem_bp_haut
=0
    mem_bp_droite
=0
    mem_bp_gauche
=0    
       
    i var byte                
    Sortie_led
=0

    
    D var byte
    Data_1 var byte
    Data_2 var byte
    Data_3 var byte
    Data_4 var byte
 
    T0 var byte
    T1 var byte
    T2 var byte
    T3 var byte
    T4 var byte

    HB var word
    GD var word                       
' Position des règles'


    data_1=0
    data_2
=0
    data_3
=0
    data_4
=
    hb
=0
    gd
=0
    
    pause 500
    
    on interrupt goto int
:
    


prg
:
    sortie_led=cli
    if led
<>cli  then           ' si la led Change, info à l''esclave qui gère la sortie '
        data_1 = 40+led
        gosub WR_i2C
        led
=cli
    endif

    if Entree_20 and not Entree_18 and hb
<50000 then                 ' Si Bouton Poussoir vers le bas'
        if not mem_bp_bas then                                  ' Si pas déjà envoyé'
            data_1 = 25 << 1                                  ' calcul de l''octet à envoyer pour déplacer moteur Bas' 
            data_1 
= data_1+1                               ' Valeur de la variable (25) à "1"'
            gosub WR_i2C                                        ' envoie à l''esclave de l''état de la variable 25 '
            Mem_BP_bas=1                                        ' on mémorise l''info envoyée variable 25 à "ON"'
        endif
    else
        if mem_bp_bas then                                      
' si info "ON" de la variable 25 '
            data_1 = 25 << 1                                  ' On met la variable 25 à "Off"  '
                                                                ' envoie à l''esclave de l''état de la variable 25 '
            gosub RD_i2C                                        ' Lecture de la position des règles sur 4 Octets'
            mem_bp_bas=0                                        ' Mémoire de la variable 25 à "Off"'
        endif
    endif
    
    if Entree_18 and not Entree_20 and hb
>0 then                     ' Idem sur BP Vers le Haut'
        if not Mem_BP_haut then                                 ''
            data_1 = 26 << 1                                  ''
            data_1 = data_1+1                               ''
            gosub WR_i2C                                   ''
            Mem_BP_haut=1                                       ''
        endif                                                   ''
    else                                                        ''
        if mem_BP_haut then                                     ''
            data_1 = 26 << 1                                  ''
                                                                ''
            gosub RD_i2C                                        ''
            mem_bp_haut=0                                       ''
        endif 
    endif
    
    if Entree_24 and not Entree_22 and gd
<50000 then            ' Idem sur BP Vers la Droite'
        if not mem_bp_droite then 
            data_1 
= 27 << 1    
            data_1 
= data_1+1  
            gosub WR_i2C
            mem_bp_droite
=1
        endif
    else
        if mem_BP_droite then
            data_1 
= 27 << 1

            gosub RD_i2C
            mem_bp_droite
=0
        endif
    endif
                                                                
    if Entree_22 and not Entree_24 and gd
>0 then                ' Idem sur BP Vers la Gauche'
        if not mem_bp_gauche then 
            data_1 
= 28 << 1  
            data_1 
= data_1+1  
            gosub WR_i2C
            mem_bp_gauche
=1
        endif
    else
        if mem_BP_gauche then
            data_1 
= 28 << 1

            gosub RD_i2C
            mem_bp_gauche
=0
        endif
    endif

    
    
    
    
    
    
    GOTO prg

'_______________________________________________________________________________'


envoie_Acknowledge:            
    SSPCON2.5 
= 0                 ' préparation de l''Acknowledge'
    SSPCON2.4 = 1                 ' Envoie de l''Acknowledge'
    do while SSPCON2.4 
    loop
    return 
    
envoie_Non_Ack
:
    SSPCON2.5 = 1                 ' préparation du non Acknowledge'
    SSPCON2.4 = 1                 ' Envoie du non Acknowledge'
    do while SSPCON2.4 : loop
    return 

repeat_start
:
    SSPCON2.1 = 1                           ' RSEN Condition Repeated START'
    do while SSPCON2.1 : loop               ' Attente fin de la condition START'
    return 

recep_acknowledge
:
    do while SSPSTAT.2 : loop                         ' Attente fin transmission'
    do while SSPCON2.6 : loop                   ' Attente de l''acknowledge'
    return
    
I2CSTART
:
    WHILE SSPCON2<<3 or SSPSTAT.2 : WEND
    SSPCON2.0 
= 1                   ; SEN - Start Condition Enable Bit
    WHILE SSPCON2.0 
= 1 : WEND      ; Wait for Start to complete
RETURN

I2CSTOP:
    'WHILE (SSPCON2<< 3) OR SSPSTAT.2 : WEND'
    SSPCON2.2 = 1                   ; PEN - send stop bit
    WHILE SSPCON2.2 
= 1 : WEND      ; Wait for SSP to complete
RETURN

I2CWR:
    WHILE SSPSTAT.2 = 1 : WEND      ; SSPSTAT = 1 Transmit in progress
    WHILE SSPCON2.6 
= 1 : WEND      ; Wait for Acknowledge from slave 1=NotAck
RETURN 

WR_i2C
:
    Gosub I2CSTART
    SSPBUF 
= Pic2620_CM_EA                      ; Move data to SSPBUF
    gosub I2CWR
    gosub recep_acknowledge
    SSPBUF 
= data_1
    gosub I2CWR
    gosub recep_acknowledge

    if data_1
>61 then
        SSPBUF
= data_2
        GOSUB I2CWR 
        gosub recep_acknowledge                             

        SSPBUF 
= data_3
        GOSUB I2CWR
        gosub recep_acknowledge 
    endif               

    GOSUB I2CSTOP
    return
    
RD_i2C
:
    Gosub I2CSTART
    SSPBUF 
= Pic2620_CM_EA                     ' Adresse en Ecriture'
    gosub I2CWR
    gosub recep_acknowledge
    SSPBUF 
= data_1
    gosub I2CWR
    gosub recep_acknowledge
    
    gosub repeat_start
    SSPBUF 
= Pic2620_CM_la                       ' Adresse en Lecture'
    gosub recep_acknowledge
    data_1 
= SSPBUF
    gosub envoie_Acknowledge
    data_2 
= SSPBUF
    Gosub envoie_Acknowledge
    data_3 
= SSPBUF 
    Gosub envoie_Acknowledge
    data_4 
= SSPBUF
    gosub envoie_Non_Ack
    
    gosub I2CSTOP

    return  

'Intéruptions_Intéruptions_Intéruptions_Intéruptions_Intéruptions_Intéruptions_Intéruptions_Intéruptions_Intéruptions_'

Int:

    if INTCON.2 then   'interruption Compteur TMR0'
        
        t0
=t0+1
        if t1
>0 then t1=t1-1

        select case t0
            case 1
                bip
=1
                cli
=1
            case 32
                bip
=0
            case 64
                bip
=1
                cli
=0
            case 96
                bip
=0
            case 128
                t0
=0
                if t2
>0 then t2=t2-1
                if t3
>0 then t3=t3-1
                if t4
>0 then t4=t4-1
        end select
        INTCON.2
=0
    endif
    
    resume
    enable          
    End

Problème de séquence I2C entre deux PIC
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#59 Message par satinas » mar. 5 mai 2020 08:31 lien vers la Data-Sheet : Cliquez ici

Bonjour,
Essaie de décrire exactement ce qui ne fonctionne pas. Plus haut tu dis que c'est lorsque tu utilises l'interruption sur le maître qu'il y a des problèmes.
A quelle ligne cela coince ?
Cela veut dire que ça marche sans l'interruption ?
Parce que pour gérer des poussoirs et des leds clignotantes, on peut se passer de l'interruption, au moins pour les tests, je me répète, je me répète :)
Est-ce que les commandes qui ne font qu'envoyer des données à l'esclave marchent à tous les coups ?

Problème de séquence I2C entre deux PIC
Serge
Amateur
Amateur
Messages : 163
Enregistré en : septembre 2018

#60 Message par Serge » mar. 5 mai 2020 09:06 lien vers la Data-Sheet : Cliquez ici

Bonjour Satinas.

Bonjour à Tous.

J'ai peur de te répondre oui, car si celui-ci fonctionne correctement à tous les coups en écriture, (et pas du tout en lecture)
Le programme global dont j'ai extrait ces deux modules simplifiés, lui, plante aussi en écriture, si on sollicite une commande qui utilise l'I2c. (pas si on ne fait rien)
Mais oui, celui-ci ne plante pas en Ecriture.
Il reste la lecture à mettre au point.

Non, je ne pense pas avoir dit ça...Peux-tu me dire ou j'ai dit ça.. je m'y perd !

Non, je n'arrive pas à faire fonctionner sans la gestion des interruptions.

La led du Pic Esclave, qui fonctionne par l'I2c clignotte correctement .
Et dès que je fais une commande sur un BP du Pic Maitre pour faire un déplacement, la lecture i2c plante au relachement de la commande. (Entrees18 - 20 - 22 - 24)

Le module qui ne fonctionne pas c'est le RD_I2C:


Retourner vers « Le forum Fantas-PIC »

Qui est en ligne

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