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

Programme I2C PIC
ditame
Débutant
Débutant
Messages : 32
Enregistré en : avril 2017

#1 Message par ditame » mer. 28 juin 2017 18:49 lien vers la Data-Sheet : Cliquez ici

Bonjour,

J'essaye de faire un programme sur un PIC16f1703 qui utilise une communication I2C mais impossible de le réaliser. Il me met des warnings quand je veux lire dans le buffer et tester le flag (IOCIF).

Initialisation de l'I2C:

Code : Tout sélectionner

void I2C_Slave_Init(short address) 
{

  RA5PPS = 0b10001;
  RA4PPS = 0b10000;
  
  SSP1STAT
=0b11000100;
  SSP1CON1=0b00111111;
  SSP1CON2=0b10000000;
  SSP1CON3=0b00000000;
  SSP1ADD=0b00010100;
  


Commande pour lire la trame

Code : Tout sélectionner

  //If trame I2C
  if(IOCIF){
            z = SSP0BUF;
            real_steps_counter_256+=2500;
            IOCIF=0;
        }
 
Modifié en dernier par ditame le jeu. 29 juin 2017 10:58, modifié 1 fois.

Programme I2C PIC
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 » mer. 28 juin 2017 20:29 lien vers la Data-Sheet : Cliquez ici

 ! Message de modération :
Bonsoir ditame,
Pour avoir un maximum de réponse, il te faut inciter les membres à vouloir t'aider. Pour cela merci de mettre un lien vers la Data-Sheet de ton PIC en suivant cette petite procédure

Merci à toi
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Programme I2C PIC
ditame
Débutant
Débutant
Messages : 32
Enregistré en : avril 2017

#3 Message par ditame » jeu. 29 juin 2017 10:59 lien vers la Data-Sheet : Cliquez ici

Bonjour,
Je viens de la rajouter merci pour l'information.

Programme I2C PIC
ditame
Débutant
Débutant
Messages : 32
Enregistré en : avril 2017

#4 Message par ditame » jeu. 29 juin 2017 14:31 lien vers la Data-Sheet : Cliquez ici

Je vous joint mon code actuel pour tester le flag de réception I2C

Code : Tout sélectionner

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <pic16f1705.h>
#include <stdbool.h>



#define A RC0
#define B RC1
#define _XTAL_FREQ 16000000

#pragma config FOSC = INTOSC    // Oscillator Selection Bits (Internal HFINTOSC. I/O function on RA4 and RA5.)
#pragma config WDTE = OFF        // Watchdog Timer Enable (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = ON   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PPS1WAY = ON     // Peripheral Pin Select one-way control (The PPSLOCK bit cannot be cleared once it is set by software)
#pragma config ZCDDIS = ON      // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR)
#pragma config PLLEN = ON       // Phase Lock Loop enable (4x PLL is always enabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF      // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)

int new_state_A;// gestion front clock
int old_state_A;


int new_state_B;// gestion front data
int old_state_B;

bool edgeA =false;//flag front
bool riseA =false;//flag front montant
bool fallA =false;//flag front descendant

bool edgeB =false;//flag front
bool riseB =false;//flag front montant
bool fallB =false;//flag front descendant


typedef enum {
    COUNTER_CLOCKWISE,
    NONE,
    CLOCKWISE
} Direction;

Direction direction = NONE;
int real_steps_counter_256 = 0;


unsigned long motor_timing;
unsigned short motor_step_state;




void I2C_Slave_Init() {

  RA5PPS = 0b10001;
  RA4PPS = 0b10000;
  
  SSP1STAT
=0b11000100;
  SSP1CON1=0b10100110;
  SSP1CON2=0b10000000;
  SSP1CON3=0b00000000;
  SSP1ADD=0b00010100;
  
}

void initialisation (){
TRISC  = 0b11100011;
OSCCON = 0b01111010;
ODCONC = 0b00000000;
INLVLC = 0b00000000;
ANSELC = 0b00000000;
WPUC = 0b00000000;

old_state_A = PORTCbits.A;// detection de front data
old_state_B = PORTCbits.B;// detection de front clock

new_state_A = PORTCbits.A;// detection de front data
new_state_B = PORTCbits.B;// detection de front clock

// Enable motor
PORTCbits.RC4=1;
motor_step_state = 0x00;


// initialisation du timer 
OPTION_REG=0b00000100;
TMR0 = 40;
INTCON =0b10100000;



    
}

void step_moteur(int precompteur){
    
     
//gestion moteur
    
    
    if 
(TMR0IF == 1) {        
  
        if
(real_steps_counter_256<0){
            PORTCbits.RC3 = 0; // direction 
        }
         else{
             PORTCbits.RC3 = 1;// direction
        }
    
        if
(real_steps_counter_256 !=0){
            PORTCbits.RC2 = motor_step_state; // fait un pas quand passe deux fois dans la boucle  
            motor_step_state ^= 0x01; 
        
}

    TMR0 = precompteur;    
    TMR0IF 
= 0;
    }    
}


void New_Step(){
old_state_A = new_state_A;
    old_state_B = new_state_B;
    
    new_state_A 
= PORTCbits.A;
    new_state_B = PORTCbits.B;

    edgeA = new_state_A != old_state_A;  
    riseA 
= edgeA && new_state_A==1;
    fallA = edgeA && new_state_A==0;

    edgeB = new_state_B != old_state_B;  
    riseB 
= edgeB && new_state_B==1;
    fallB = edgeB && new_state_B==0;





    // Highly accurate direction change detection
    if (riseA) {
        direction = ( new_state_B == 0 ? CLOCKWISE : COUNTER_CLOCKWISE );
    }
    if (fallA) {
        direction = ( new_state_B == 1 ? CLOCKWISE : COUNTER_CLOCKWISE );
    }

    if (riseB) {
        direction = ( new_state_A == 1 ? CLOCKWISE : COUNTER_CLOCKWISE );
    }

    if (fallB) {
        direction = ( new_state_A == 0 ? CLOCKWISE : COUNTER_CLOCKWISE );
    }


    // Step counter
    // When CLOCKWISE : "A leads B" on rise AND fall edge
    // 'rise AND fall' because looking at chronograms page 23
    // Step/Dir-Mode chronogram shows LSB(aka steps) is triggered like that
    if (edgeA && direction == CLOCKWISE) {

        real_steps_counter_256+=25;
    }

    // When COUNTER_CLOCKWISE : "B leads A" on rise AND fall edge
    if (edgeB && direction == COUNTER_CLOCKWISE) {

        real_steps_counter_256-=25;
    }    
}


void main() {
    
initialisation
();
I2C_Slave_Init();
    
    while
(1){
        
    New_Step
();
    step_moteur(180);

        //If trame I2C
        if(INTCONbits.IOCIF){
            real_steps_counter_256+=2500;
            INTCONbits.IOCIF=0;
        }
       

    
}


}



Programme I2C PIC
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#5 Message par paulfjujo » jeu. 29 juin 2017 17:09 lien vers la Data-Sheet : Cliquez ici

bonjour Ditame et à tous,

Je vous joint mon code actuel pour tester le flag de réception I2C


flag I2C ?
ou flag detection de changement d'etat ou fronts des pins RC0 et RC1
voir 13.3 Interrupt Flags et 13.4 13.4 Clearing Interrupt Flags de la datasheet
INTCONbits.IOCIF=0; Ne peut pas etre remis à zero par programme

je ne vois pas ou sont les pins dediée à SCL et SDA d'une liaison I2C


J'avoue ne pas trop comprendre ton programme,
Que fait la liaison I2C dans ton programme ?
Lecture d'un encodeur sur RC0 et RC1 ?


mais ce qui m'etonne est que tu n'utilises pas les interruptions pour agir en fonction des flags IOCIF.
ainsi que le flag TMR0IF..
Difficile de maitriser les timmings en mode polling.
Aide toi, le ciel ou FantasPic t'aidera

Programme I2C PIC
ditame
Débutant
Débutant
Messages : 32
Enregistré en : avril 2017

#6 Message par ditame » jeu. 29 juin 2017 17:22 lien vers la Data-Sheet : Cliquez ici

Oui il y a un encodeur pour un retour de position moteur. Le but est juste de tester au moins qu'il reçoit la trame I2C sans lire dans le buffer et de faire bouger le moteur si le flag de la trame I2C est UP. Par la suite il lira une position moteur envoyé par L'I2C.

Pas de soucis du coté du moteur et de piloter celui ci avec les signaux. La je cherche juste a parametrer les registre I2C et faire tourner le moteur quand il reçoit une trame random.

Et je ne peux pas utiliser d'interupt si non le moteur se stop pendant qu'il analyse la trame.

Et j'ai supprimé les lignes suivantes de modification de pin pour remettre celle d'origine

Code : Tout sélectionner

  RA5PPS 0b10001;
  
RA4PPS 0b10000
Modifié en dernier par ditame le jeu. 29 juin 2017 17:36, modifié 1 fois.

Programme I2C PIC
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#7 Message par paulfjujo » jeu. 29 juin 2017 17:34 lien vers la Data-Sheet : Cliquez ici

si le flag de la trame I2C est UP.


mais IOCIF n'a rien à voir avec l'I2C !
et qui plus est , on ne peut pas le mettre à zero par programme.
Aide toi, le ciel ou FantasPic t'aidera

Programme I2C PIC
ditame
Débutant
Débutant
Messages : 32
Enregistré en : avril 2017

#8 Message par ditame » jeu. 29 juin 2017 17:36 lien vers la Data-Sheet : Cliquez ici

Comment je détecte qu'il est entrain de recevoir une trame du master ( qui est un arduino ) ?

Programme I2C PIC
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#9 Message par paulfjujo » jeu. 29 juin 2017 17:51 lien vers la Data-Sheet : Cliquez ici

si l'arduino est un MAITRE I2C
donc ton PIC doit etre en Esclave I2C
est la detection d'arrivée d'un message I2C dans l'esclave ( Le PIC) est beaucoup plus compliquée
necessite un protocole ...

si en plus, tu n'as aucune fenetre "temporelle" pour faire cela,
à tous les coups le moteur s'arrettera ou ralentira , pendant le traitement de l'arrivée de la trame ..
Seule une commande PWM hardware pour piloter ton moteur , pourrait s'affranchir
d'arrivée d'evenements externes.

à part RB0 , qui est une entree particuliere permettant une interruption levant le flag => INT0IF
que l'on peut remettre à zero par programme
(... j'ai pas verifié sur ton type de PIC)

mais qui ne resoudra en rien, le fait que tu doives etre en I2C esclave sur ton PIC pour accepter un message I2C arduino.
Aide toi, le ciel ou FantasPic t'aidera

Programme I2C PIC
ditame
Débutant
Débutant
Messages : 32
Enregistré en : avril 2017

#10 Message par ditame » jeu. 29 juin 2017 19:14 lien vers la Data-Sheet : Cliquez ici

Comment détecter que le buffer est plein du coup ? j'ai paramétré le pic en esclave avec l'adresse 10. Mais je ne sais pas si je l'ai fait correctement.


Retourner vers « Langage C »

Qui est en ligne

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