programmation PIC 16F877A
Répondre à la discussion
Affichage des résultats 1 à 10 sur 10

programmation PIC 16F877A



  1. #1
    rafik16

    programmation PIC 16F877A


    ------

    bonjour tout le monde. je veux réaliser un systeme d'alarme, qui contient 3 capteurs PIR, choc et détecteur des portes et il gère le verrouillage centralise et une siréne et un module GSM. tout sa sera contrôle par un PIC 16F877A qui a une horloge (Quartz) de 4MHz.
    pour la partie hard tout marche a merveille(chaque partie séparément) , mais mon plus grand probleme c'est la programmation de PIC. quand je le compile y'a aucune erreur quand je le transfert sur mon PIC rien ne marche.
    SI quelqu'un peut m'aide je lui sera très très très reconnaissant.
    je vous donne le programme.
    Code:
    //déclaration des variables
            int detection ;
    int raf   ;
    
    
    
    
    //assignation
     #define recepteur portb.f0
     #define buzz re1_bit
     #define verrou  ra3_bit
     #define pir rb4_bit
     #define choc rb1_bit
     #define dtp  rb2_bit
    
    
    
    void main(){
    option_reg=0x80 ;
    
    intcon = 0x10 ;
    pie1=0x0 ;  // aucun préphirique n'est autorise a faire une interuption
    pie2=0x0 ;  //
    adcon1=0x06; //tout les pin sont en  I/O numerique
    trisb=0xFF;
    trisa=0x0;
    trisc=0x80;
    trise=0x0;
    UART1_Init(9600);
    delay_ms(100);
    detection=0;
    verrou=0;
    recepteur=1;
    
    while(1)
    start :
    {
    if(recepteur==0)  //utilisation de la télécommande
    {
    if(verrou==0)   //Portes verrouillées??
    {
    if(dtp==1)      // portes fermées??
    {
    verrou=1;
    intcon=0x90;
    detection =1 ;
    }
    else                 //portes pas fermées
    {
    buzz=1;
    delay_ms(2000);
    buzz=0;
    }
    goto start;
    }
    else if(buzz==0 && verrou==1)     // déverrouiller les portes
    {
    verrou=0;
    intcon=0x10;
    detection=0;      // activé la détection
    }
    else if(buzz==1 && verrou==1)    // arreter la siréne
    {
    buzz=0;
    }
    }
    detec :                            // routine de détection
    while(detection==1)
    {
    if(pir==1 || dtp==0)
    {buzz=1;
    UART1_write_text("AT");    // Envoi de la commande AT
    UART1_write(13);    // Code ASCII equivalent pour ENTRE
    UART1_write(10);    // Code ASCII equivalent pour (CTRL+H)
    delay_ms(1000);
    UART1_write_text("AT+CSMS");   // Envoi de la commande "AT+CSMS" pour la selection de service de messagerie
    UART1_write(13);
    UART1_write(10);
    delay_ms(1000);
    UART1_write_text("AT+CMGF=1");   // Envoi de la commande "AT+CMGF=1" pour la selection du format du SMS le 1 pour le mode TEXT
    UART1_write(13);
    UART1_write(10);
    delay_ms(1000);
    UART1_write_text("AT+CMGS=");   // Commande pour l'envoi d'un SMS,on indiquant le numéro du destinataire
    UART1_write(34);  // code ASCII de (")
    UART1_write_text("0633825379");
    UART1_write(34);   // code ASCII de (")
    UART1_write(13);
    UART1_write(10);
    delay_ms(1000);
    UART1_write_text("alarme");  // le contenu de notre message
    UART1_write(13);
    UART1_write(10);
    delay_ms(1000);
    }
    if(choc==1)
    {raf++;
    if(raf==4)
    {buzz=1;
    UART1_write_text("AT");    // Envoi de la commande AT
    UART1_write(13);    // Code ASCII equivalent pour ENTRE
    UART1_write(10);    // Code ASCII equivalent pour (CTRL+H)
    delay_ms(1000);
    UART1_write_text("AT+CSMS");   // Envoi de la commande "AT+CSMS" pour la selection de service de messagerie
    UART1_write(13);
    UART1_write(10);
    delay_ms(1000);
    UART1_write_text("AT+CMGF=1");   // Envoi de la commande "AT+CMGF=1" pour la selection du format du SMS le 1 pour le mode TEXT
    UART1_write(13);
    UART1_write(10);
    delay_ms(1000);
    UART1_write_text("AT+CMGS=");   // Commande pour l'envoi d'un SMS,on indiquant le numéro du destinataire
    UART1_write(34);  // code ASCII de (")
    UART1_write_text("0633825379");
    UART1_write(34);   // code ASCII de (")
    UART1_write(13);
    UART1_write(10);
    delay_ms(1000);
    UART1_write_text("alarme");  // le contenu de notre message
    UART1_write(13);
    UART1_write(10);
    delay_ms(1000);
    raf=0;}
    else
    {buzz=1;
    delay_ms(3000);
    buzz=0;}
    }
    goto detec;
    }
    }
    }
    void interrupt()
    {
    if(buzz==1)              // arrete la siréne
    {
    buzz=0; 
    intcon=0x90 ;
    }
    else                       //déverouiller les portes et arrete la détection
    {
    verrou=0;
    detection=0;
    raf=0;
    intcon=0x10;
    }
    }
    je crois que j'ai oublie quelque chose au niveau des registres de réglage et de configuration.

    -----

  2. #2
    PIXEL

    Re : programmation PIC 16F877A

    peut on voir ton organigramme ?

  3. #3
    rafik16

    Re : programmation PIC 16F877A

    le voila l'organigramme en pièce jointe
    Images attachées Images attachées  

  4. #4
    invite03481543

    Re : programmation PIC 16F877A

    Bonsoir,

    tu devrais utiliser les interruptions, ce serait plus efficace.
    Un conseil egalement, si tu debutes une bonne methode est de mettre 2 ou 3 leds sur ta carte et tu peux les utiliser dans ton code pour espionner un peu les boucles ou les tests pour voir ou ca coince.
    Tu verras tu vas avancer bien plus vite pour debugger, ou tu peux utiliser le mode debug de ton compilo egalement en surveillant tes variables, si elles evoluent normalement ou pas.

  5. A voir en vidéo sur Futura
  6. #5
    invite03481543

    Re : programmation PIC 16F877A

    Enfin evite les "goto start" en C, c'est tres mal !

    Dans ton ordinogramme tu as deux fois "sirene 3 sec" et "portes ouvertes" ce n'est pas normal, il n'est donc pas optimise.
    Je vois egalement un usage de intcon dans ton code, mais rien de declare dans la routine d'interruption... aucun flag n'est teste...

    Forcement ca ne peut donc pas fonctionner.
    Dernière modification par HULK28 ; 03/05/2012 à 21h08.

  7. #6
    invite03481543

    Re : programmation PIC 16F877A

    Code:
    //assignation des ports
     #define recepteur PORTB.F0
     #define buzz      PORTE.F1
     #define verrou    PORTA.F3
     #define pir       PORTB.F4
     #define choc      PORTB.F1
     #define dtp       PORTB.F2
    
    //déclaration des variables globales
    int detection ;
    int raf ;
    
    void init_pic(void)
    {
    OPTION_REG=0x80 ;
    INTCON = 0x10 ;
    PIE1=0x0 ; // aucun préphirique n'est autorise a faire une interuption
    PIE2=0x0 ; //
    ADCON1=0x06; //tout les pin sont en I/O numerique
    TRISB=0xFF;
    TRISA=0x0;
    TRISC=0x80;
    TRISE=0x0;
    UART1_Init(9600);
    }
    void main()
    {
    init_pic();
    detection=0;
    verrou=0;
    recepteur=1;
    while(1)   // le programme tourne en boucle infinie a partir d'ici
      {
       if(recepteur==0) //utilisation de la télécommande
         {
         if(verrou==0) //Portes verrouillées??
           {
            if(dtp==1) // portes fermées??
              {
              verrou=1;
              intcon=0x90;
              detection =1 ;
              }
            else //portes pas fermées
              {
              buzz=1;
              delay_ms(2000);
              buzz=0;
              }
           }
        
        if(buzz==0 && verrou==1) // déverrouiller les portes
          {
          verrou=0;
          intcon=0x10;
          detection=0; // activé la détection
          }
        if(buzz==1 && verrou==1) buzz=0; // arreter la siréne
        }
        while(detection==1)
             {
              if(pir==1 || dtp==0)
                {
                buzz=1;
                UART1_write_text("AT"); // Envoi de la commande AT
                UART1_write(13); // Code ASCII equivalent pour ENTRE
                UART1_write(10); // Code ASCII equivalent pour (CTRL+H)
                delay_ms(1000);
                UART1_write_text("AT+CSMS"); // Envoi de la commande "AT+CSMS" pour la selection de service de messagerie
                UART1_write(13);
                UART1_write(10);
                delay_ms(1000);
                UART1_write_text("AT+CMGF=1"); // Envoi de la commande "AT+CMGF=1" pour la selection du format du SMS le 1 pour le mode TEXT
                UART1_write(13);
                UART1_write(10);
                delay_ms(1000);
                UART1_write_text("AT+CMGS="); // Commande pour l'envoi d'un SMS,on indiquant le numéro du destinataire
                UART1_write(34); // code ASCII de (")
                UART1_write_text("0633825379");
                UART1_write(34); // code ASCII de (")
                UART1_write(13);
                UART1_write(10);
                delay_ms(1000);
                UART1_write_text("alarme"); // le contenu de notre message
                UART1_write(13);
                UART1_write(10);
                delay_ms(1000);
              }
          if(choc==1)
            {
             raf++;
             if(raf==4)
               {
               buzz=1;
               UART1_write_text("AT"); // Envoi de la commande AT
               UART1_write(13); // Code ASCII equivalent pour ENTRE
               UART1_write(10); // Code ASCII equivalent pour (CTRL+H)
               delay_ms(1000);
               UART1_write_text("AT+CSMS"); // Envoi de la commande "AT+CSMS" pour la selection de service de messagerie
               UART1_write(13);
               UART1_write(10);
               delay_ms(1000);
               UART1_write_text("AT+CMGF=1"); // Envoi de la commande "AT+CMGF=1" pour la selection du format du SMS le 1 pour le mode TEXT
               UART1_write(13);
               UART1_write(10);
               delay_ms(1000);
               UART1_write_text("AT+CMGS="); // Commande pour l'envoi d'un SMS,on indiquant le numéro du destinataire
               UART1_write(34); // code ASCII de (")
               UART1_write_text("0633825379");
               UART1_write(34); // code ASCII de (")
               UART1_write(13);
               UART1_write(10);
               delay_ms(1000);
               UART1_write_text("alarme"); // le contenu de notre message
               UART1_write(13);
               UART1_write(10);
               delay_ms(1000);
               raf=0;
               }
            else
                {
                buzz=1;
                delay_ms(3000);
                buzz=0;
                }
           }
         }
       }
    }
    void interrupt()
    {
      if(buzz==1) // arrete la siréne  -> n'as rien a faire ici!
        {
        buzz=0;
        intcon=0x90 ;
        }
      else //déverouiller les portes et arrete la détection
        {
        verrou=0;
        detection=0;
        raf=0;
        intcon=0x10;
        }
    }
    J'ai retouche un peu ton code, il n'est pas encore fonctionnel mais j'ai enleve les goto.
    La compilation ne donne aucun defaut mais il y a encore des choses a corriger, notamment comme je le disais ce qu'il faut faire dans la boucle d'interruption, a savoir detecter les evenements avec les flags des ports interruptifs.
    On ne fait rien dans la routine d'interruption, on detecte et on gere dans le prog principal.
    Il faut liberer la routine le plus vite possible pour ne pas manquer un autre evenement.

    Pour cela j'ai besoin de savoir sur quels ports tu as mis tes differentes detections, en gros poste ton schema.
    C'est forcement sur les ports interruptifs RBx de toutes facons.

    @+
    Dernière modification par HULK28 ; 03/05/2012 à 22h08.

  8. #7
    invite03481543

    Re : programmation PIC 16F877A

    Voici ce que ca donnerait en utilisant la detection du flag d'interruption sur le PORTB:

    Code:
    //assignation des ports
     #define recepteur PORTB.F0
     #define buzz      PORTE.F1
     #define verrou    PORTA.F3
     #define pir       PORTB.F4
     #define choc      PORTB.F1
     #define dtp       PORTB.F2
    
    //déclaration des variables globales
    char detection ;
    char raf ;
    volatile char analyse_evenement;  // variable volatile de la routine d'interruption
    
    void init_pic(void)
    {
    OPTION_REG=0x80 ;
    INTCON = 0x10 ;
    INTCON.RBIF=0;
    INTCON.RBIE=0;
    PIE1=0 ; // aucun préphirique n'est autorise a faire une interuption
    PIE2=0 ; //
    ADCON1=0x06; //tout les pin sont en I/O numerique
    TRISB=0xFF;
    TRISA=0x0;
    TRISC=0x80;
    TRISE=0x0;
    UART1_Init(9600);
    INTCON.PEIE = 1;
    INTCON.GIE=1;
    INTCON.RBIE=1;
    }
    void main()
    {
    init_pic();
    detection = 0;
    verrou = 0;
    recepteur = 1;
    analyse_evenement = 0;
    while(1)   // le programme tourne en boucle infinie a partir d'ici
      {
      if(analyse_evenement == 1)
        {
         if(recepteur==0) //utilisation de la télécommande
           {
           if(verrou==0) //Portes verrouillées??
             {
              if(dtp==1) // portes fermées??
                {
                verrou=1;
                intcon=0x90;
                detection =1 ;
                }
              else //portes pas fermées
                {
                buzz=1;
                delay_ms(2000);
                buzz=0;
                }
             }
           }
        if(buzz==0 && verrou==1) // déverrouiller les portes
          {
          verrou=0;
          intcon=0x10;
          detection=0; // activé la détection
          }
        if(buzz==1 && verrou==1) buzz=0; // arreter la siréne
        }
        while(detection==1)
             {
              if(pir==1 || dtp==0)
                {
                buzz=1;
                UART1_write_text("AT"); // Envoi de la commande AT
                UART1_write(13); // Code ASCII equivalent pour ENTRE
                UART1_write(10); // Code ASCII equivalent pour (CTRL+H)
                delay_ms(1000);
                UART1_write_text("AT+CSMS"); // Envoi de la commande "AT+CSMS" pour la selection de service de messagerie
                UART1_write(13);
                UART1_write(10);
                delay_ms(1000);
                UART1_write_text("AT+CMGF=1"); // Envoi de la commande "AT+CMGF=1" pour la selection du format du SMS le 1 pour le mode TEXT
                UART1_write(13);
                UART1_write(10);
                delay_ms(1000);
                UART1_write_text("AT+CMGS="); // Commande pour l'envoi d'un SMS,on indiquant le numéro du destinataire
                UART1_write(34); // code ASCII de (")
                UART1_write_text("0633825379");
                UART1_write(34); // code ASCII de (")
                UART1_write(13);
                UART1_write(10);
                delay_ms(1000);
                UART1_write_text("alarme"); // le contenu de notre message
                UART1_write(13);
                UART1_write(10);
                delay_ms(1000);
              }
          if(choc==1)
            {
             raf++;
             if(raf==4)
               {
               buzz=1;
               UART1_write_text("AT"); // Envoi de la commande AT
               UART1_write(13); // Code ASCII equivalent pour ENTRE
               UART1_write(10); // Code ASCII equivalent pour (CTRL+H)
               delay_ms(1000);
               UART1_write_text("AT+CSMS"); // Envoi de la commande "AT+CSMS" pour la selection de service de messagerie
               UART1_write(13);
               UART1_write(10);
               delay_ms(1000);
               UART1_write_text("AT+CMGF=1"); // Envoi de la commande "AT+CMGF=1" pour la selection du format du SMS le 1 pour le mode TEXT
               UART1_write(13);
               UART1_write(10);
               delay_ms(1000);
               UART1_write_text("AT+CMGS="); // Commande pour l'envoi d'un SMS,on indiquant le numéro du destinataire
               UART1_write(34); // code ASCII de (")
               UART1_write_text("0633825379");
               UART1_write(34); // code ASCII de (")
               UART1_write(13);
               UART1_write(10);
               delay_ms(1000);
               UART1_write_text("alarme"); // le contenu de notre message
               UART1_write(13);
               UART1_write(10);
               delay_ms(1000);
               raf=0;
               }
            else
                {
                buzz=1;
                delay_ms(3000);
                buzz=0;
                }
           }
         }
       }
    }
    
    void interrupt(void)  // routine d'interruption
    {
       if(INTCON.RBIF)  // Si interruption sur portB detecte (RB4...RB7)
       {
       analyse_evenement = 1;  // la on autorise la gestion dans le main()
       INTCON.RBIF = 0;
       }
    }
    Il faut mettre tes capteurs sur le PORTB (PORTB.F4, PORTB.F5, PORTB.F6, PORTB.F7), ces 4 ports sont interruptifs sur variations de fronts.
    Ensuite ce sera facile pour toi de gerer les evenements, il faut tranformer tout ces if vilains et remplacer tout ca par un swicth(analyse_evenement) par exemple, plus propre et plus lisible.
    Le programme tel que je te l'ai poste se compile sans erreur, mais certainement pas fonctionnel en l'etat.
    Bonne prog.
    @+
    Dernière modification par HULK28 ; 03/05/2012 à 23h05.

  9. #8
    rafik16

    Re : programmation PIC 16F877A

    bonjour
    pour les interruptions, j'ai autorise qu'une seule et c'est de RB0 c'est pour sa que j'ai pas fait de teste sur les flags de registre INTCON. pour se qui concerne le schéma j'ai pas un sur la main mais tu peux voir comment je vais brancher les capteurs en voient les assignations dans le programme.
    Merci pour ton aide et excusez moi pour mon francais je suis pas un francophone .

  10. #9
    rafik16

    Re : programmation PIC 16F877A

    voila le nouveau code
    Code:
    //assignation des ports
     #define recepteur PORTD.F7
     #define buzz      PORTE.F1
     #define verrou    PORTA.F3
     #define pir       PORTB.F7
     #define choc      PORTB.F0
     #define dtp       PORTB.F4
     //déclaration des variables
     int raf;
     int SMS ;
     int varchoc ;
    void init (void)
    {
    option_reg=0Xc0;
    adcon1=0x06;
    intcon=0x18;
    trisb=0xff;
    trisa=0x0;
    trisc=0b10000000;
    trisd=0xFF;
    trise=0X0;
    //UART1_INIT(9600);
    }
    void main() {
    init();
    verrou=0;
    recepteur=1;
    while(1)
    {
    if(recepteur==0)    // si la télécommande est utilise
    {
    if(verrou==0)        // si les portes sont déverrouillées
    {
      if(dtp==0)          // si les portes sont ouvertées
      {
      buzz=1;
      }
      if(dtp==1)           //si les portes sont fermées
      {
       verrou=1;            // verrouiller les portes
       intcon=0x98;          // activer les interruption (la détection)
      }
    }
    else if(buzz==1)       // si la siréne est activée
    {
    buzz=0;                //désactiver la siréne
    }
    else if(verrou==1)     //   si les portes sont verrouillées
    {
    verrou=0;
    intcon=0x18;
    }
    }
    if(INTCON.GIE==1)      //Si les interruptions sont activées
    {
    if(varchoc=1)
    {
    buzz=1;
    delay_ms(2000);
    buzz=0;
    varchoc=0;
    }
    if(SMS=1)
    {
    
    }
    }
    }
    }void interrupt()
    {
    if(intcon.intf==1)      // si interruption sur RB0(détecteur de choc)
    {
    raf++;                   // raf est un compteur
    if(raf!=4)
    {
    varchoc=1;
    }
    else if(raf==4);
    {
    buzz=1;
    raf=0;
    }
    INTCON.INTF=0;
    }
    else if(INTCON.RBIF==1)
    {
    buzz=1;
    SMS=1;
    intcon.RBIF=0;
    }
    }
    j'ai changé un peux les branchement des capteurs et je les est met sur des branches qui sont des sources d'interruptions, comme sa je en désactivant les interruptions j'arrêterais la détection.
    y'a un petit truc que je ne comprend pas c'est la résistance de rappel sur le port B. moi je l es désactivé . a ce que je branche directement la sortie de mes capteurs avec les pins de PIC ou je met une résistance en parallèle avec les pin et la masse ??
    et encore Merci a vous pour votre aide )

  11. #10
    invite03481543

    Re : programmation PIC 16F877A

    Attention a une chose, tu as introduit des variables dans la boucle d'interruption donc il faut que tu les declares en "volatile" sans quoi ca ne fonctionnera pas tel quel.
    Donc raf, varchoc, buzz, etc doivent etre declarees en consequence:
    Code:
    volatile char varchoc, raf, buzz, SMS;
    inutile d'employer des int, ces variables se contentent de 8 bits donc utilises char.

Discussions similaires

  1. probleme de programmation d'un PIC 16F877A !!
    Par rafik16 dans le forum Électronique
    Réponses: 9
    Dernier message: 25/04/2012, 20h07
  2. pic 16F877A
    Par invite636b8579 dans le forum Électronique
    Réponses: 22
    Dernier message: 01/04/2009, 15h00
  3. CAN pic 16f877A
    Par invite85bfc8b3 dans le forum Électronique
    Réponses: 1
    Dernier message: 11/08/2008, 13h39
  4. pic 16f877a
    Par invited2ae1532 dans le forum Électronique
    Réponses: 3
    Dernier message: 01/02/2008, 10h49
  5. Programmation Pic 16F877A
    Par invitee45b5732 dans le forum Électronique
    Réponses: 16
    Dernier message: 15/10/2006, 10h57
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...