Répondre à la discussion
Affichage des résultats 1 à 15 sur 15

aide



  1. #1
    agno

    Red face aide

    Bonjour , je suis débutante dans la programmation des pics et je voulais avoir de l'aide. Je veux régler la vitesse de deux moteurs à l'aide des sorties PWM de mon pic 18f452. Pouvez m'aider à faire le code.
    Merci

    -----


  2. Publicité
  3. #2
    umfred

    Re : aide

    Tout d'abord dans quel langage veut-tu programmer?
    Jette un coup d'oeil à la datashet du PIC pour te familiariser un peu avec lui, et regarde la partie traitant du PWM (Capture/Compare/PWM module en général chez les PICs).
    Regarde également les notes d'applications traitant du PWM (même si ce n'est pas pour ton PIC, ça peut aider à comprendre un peu son fonctionnement).
    Tu trouveras cette documentation sur http://www.microchip.com.
    Ensuite, pose toi ensuite les questions de savoir comment régler la vitesse des moteurs (quelle est la variable qui fait varier la vitesse). Quelles sont les fréquences que tu veux pouvoir créées sur le PWM.....

  4. #3
    agno

    Re : aide

    Bonjour, j'ai bien avancer dans mon projet, j'ai reussi à faire varier le PWM et à faire une conversion anologique et numérique sur le pic(18f2620) en c. Maintenant je suis confrntée à un petit problème. Je trvaille sur l'i2c en mode esclave et je veux faire une comparaison de l'adresse que le maitre m'envoie et l'adresse de ma carte. L'adresse de la carte sera lu sur trois pin du pic. Mon problème c'est comment récupérer cette adresse et la mettre dans une variable. Merci pour vos aide

  5. #4
    umfred

    Re : aide

    C'est pour l'adresse lu sur les pins du PIC que ça te pose problème?
    Si oui, met dans une variable l'adresse de base pour les 4 bits de poids fort de ton adresse I2C (une adresse I2C est codée sur 7 bits).
    Ensuite tout dépend sur quels pins sont reliés tes bits de poids faibles. Si elles sont totalement dispersées, le mieux est de regarder la valeur des bits individuels et de mettre à 1 le bit correspondant de l'adresse si on lit un 1.

    if portb.f2==1
    adresse_i2c= adresse_i2c or 0x02; // si le bit2 du portB code pour le bit 1 de l'adresse I2C.

  6. #5
    agno

    Re : aide

    Bonjour, j'ai peut etre mal expliqué mon problème ou je n'ai pas compris votre explication. Je me réexplique, au fait l'adresse de la carte sera mise via un microswicth cablé sur 3 pin du pic. Ce que je cherche à faire, je sais c'est pas si c'est possible ou pas, c'est de lire l'adresse que le maitre m'envoie (sur le buffer) et de le comparer à l'adresse de la carte. Mon probleme c'est la recuperation de l'adresse de la carte pour la comparaison. Merci

  7. A voir en vidéo sur Futura
  8. #6
    agno

    Re : aide

    Je viens d'avoir une idée je sais pas s'il ya pas plus simple. Vu que l'adresse de la carte est codé sur 3 bit on a donc 8 possibilés d'adressage, voici les test que j'ai fait. Merci de me donner votre opinion la dessus. Merci

    #define adress0 PORTCbits.RC5 // Bit de poids faible de l'adresse de la carte
    #define adress1 PORTCbits.RC6 // Bit 1 faible de l'adresse de la carte
    #define adress2 PORTCbits.RC7 // Bit de poids fort de l'adresse de la carte

    lastAdress = ReadI2C();
    if(adress0==1)
    {
    if(adress1=1)
    {
    if(adress2=1)
    {
    lastAdress_n &= 0x07;
    }
    else
    {
    lastAdress_n &= 0x06;
    }
    }
    else
    {
    if(adress2=1)
    {
    lastAdress_n &= 0x05;
    }
    else
    {
    lastAdress_n &= 0x04;
    }
    }
    }
    else
    {
    if(adress1=1)
    {
    if(adress2=1)
    {
    lastAdress_n &= 0x03;
    }
    else
    {
    lastAdress_n &= 0x02;
    }
    }
    else
    {
    if(adress2=1)
    {
    lastAdress_n &= 0x01;
    }
    else
    {
    lastAdress_n &= 0x00;
    }
    }
    }
    if(lastAdress==lastAdress_n)
    {
    ACkI2C();// activation du bit acquitement: l'esclave est pret a recevoir la donnée
    }
    else{}

  9. Publicité
  10. #7
    umfred

    Re : aide

    En fait, l'adresse I2C de l'esclave doit être configurer avant la mise sous tension. (Elle ne doit pas changer en cours d'application).

    Si tu utilise l'I2C matériel du PIC (pin PORTC3 et 4) en utilisant les interruptions I2C, tu as juste besoin de lire l'adresse au début et la mettre dans le registre SSPADD. Le PIC génèrera tout seule une interruption quand le maitre enverra cette adresse sur le bus.

    Si tu n'utilise pas les interruptions et les registres I2C, c'est le même principe: lire au début du programme l'adresse de la carte sur les switchs et récupérer la valeur envoyé par le maitre sur le bus I2C et regarder si il est identique avant de poursuivre.

    Pour la lecture de l'adresse, le plus simple est de faire:

    Code:
    lecture_mon_adresse()
    {
    Mon_Adresse= portc && 0xE0; // mon_adresse contient la valeur du portc avec les bits 0 à 4 à 0
    Mon_Adresse= Mon_Adresse >> 5; // on décale de 5 bits vers la droite
    }
    Par exemple si adress0=1, adress1=0, adress2=1 (ce qui correspond à une adresse I2C voulue de 0x05:
    - "Mon_Adresse= portc && 0xE0" donne Mon_Adresse = b'1010 0000'.
    - "Mon_Adresse= Mon_Adresse >> 5" donne Mon_Adresse = b'0000 0101.

  11. #8
    agno

    Re : aide

    Merci pour tous, ça marche

  12. #9
    agno

    Re : aide

    Bonjour, j'ai une autre question. J'ai lu ce petit bout de code pour les interruptions mais je sais pas comment on choisit le vecteur et où est ce qu'on place ce code dans le programme. Merci d'avance

    #pragma code high_vector=0x08
    void interrupt_at_high_vector(void)
    {
    _asm GOTO interruption _endasm
    }
    #pragma code /* return to the default code section */

  13. #10
    umfred

    Re : aide

    The RESET vector address is at 0000h and the
    interrupt vector addresses are at 0008h and 0018h.
    Donc le vecteur d'interruption se situe en 0008 (comme ce qui est écrit dans le code que tu as posté (high_vector = 0x08) (le low_vector se situe en 0x018).(remarque que tu peux activer ou pas un niveau de priorité des interruptions, le mieux étant, je pense, de le désactiver).

    Il te reste juste à écrire une routine d'interruption
    de type interrupt interruption(){} dans laquelle tu devra gérer l'origine de cette interruption par des tests sur les différents bits d'interuptions possibles (bits des différents INTCON).

  14. #11
    agno

    Re : aide

    ok merci, j'ai compris votre explication.

  15. #12
    agno

    Re : aide

    Bonjour, j'ai encore deux autres questions. Cette fois ci c'est une interruption du TIMER0 du pic 2620. Je veux qu'il interrupte ttes les 100µs.

    1- La fréquence du TIMER est-elle la meme que celle du pic ? j'ai ésséée dans la datasheet j'ai cru comprendre que c'était la même mais je pose la question pour etre sure.
    2- je veux qu'à chaque interruption du timer, j'exécute une tache. Voici mon algo il a l'aire long mais y'a des partie qie se ressemble, c'est une répétition. Je veux que vous me disiez si l'idée est bonne ou s'il ya un moyen plus simple. Merci

    #pragma interrupt TIMER0
    void TIMER0()
    {
    indexChanel=0;

    WriteTimer0(100);

    // Première conversion
    compteur_IT++;
    if(compteur_IT == 100) //permet d'avoir 10ms(100*100µs)
    {
    SetADCChannel(channel[indexChanel]);
    OpenADC(ADC_FOSC_RC & ADC_LEFT_JUST & ADC_2_TAD, channel[indexChanel] & ADC_INT_OFF, 10);
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    compteur_IT++;
    if(compteur_IT==200)
    {
    if( !BusyADC() )
    {
    ConvertADC();
    }
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    compteur_IT++;
    if(compteur_IT==300)
    {
    resultat_conversion[indexChanel]=( unsigned char )ReadADC();
    indexChanel++;
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    // Deuxième conversion
    compteur_IT++;
    if(compteur_IT == 400)
    {
    SetADCChannel(channel[indexChanel]);
    OpenADC(ADC_FOSC_RC & ADC_LEFT_JUST & ADC_2_TAD, channel[indexChanel] & ADC_INT_OFF, 10);
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    compteur_IT++;
    if(compteur_IT==500)
    {
    if( !BusyADC() )
    {
    ConvertADC();
    }
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    compteur_IT++;
    if(compteur_IT==600)
    {
    resultat_conversion[indexChanel]=( unsigned char )ReadADC();
    indexChanel++;
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    // Troisème conversion
    compteur_IT++;
    if(compteur_IT == 700) //permet d'avoir 10ms(100*100µs)
    {
    SetADCChannel(channel[indexChanel]);
    OpenADC(ADC_FOSC_RC & ADC_LEFT_JUST & ADC_2_TAD, channel[indexChanel] & ADC_INT_OFF, 10);
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    compteur_IT++;
    if(compteur_IT == 800)
    {
    if( !BusyADC() )
    {
    ConvertADC();
    }
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    compteur_IT++;
    if(compteur_IT == 900)
    {
    resultat_conversion[indexChanel]=( unsigned char )ReadADC();
    indexChanel++;
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    // Quatrième conversion
    compteur_IT++;
    if(compteur_IT == 1000) //permet d'avoir 10ms(100*100µs)
    {
    SetADCChannel(channel[indexChanel]);
    OpenADC(ADC_FOSC_RC & ADC_LEFT_JUST & ADC_2_TAD, channel[indexChanel] & ADC_INT_OFF, 10);
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    compteur_IT++;
    if(compteur_IT == 1100)
    {
    if( !BusyADC() )
    {
    ConvertADC();
    }
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    compteur_IT++;
    if(compteur_IT == 1200)
    {
    resultat_conversion[indexChanel]=( unsigned char )ReadADC();
    indexChanel++;
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    // Cinquième conversion
    compteur_IT++;
    if(compteur_IT == 1300) //permet d'avoir 10ms(100*100µs)
    {
    SetADCChannel(channel[indexChanel]);
    OpenADC(ADC_FOSC_RC & ADC_LEFT_JUST & ADC_2_TAD, channel[indexChanel] & ADC_INT_OFF, 10);
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    compteur_IT++;
    if(compteur_IT == 1400)
    {
    if( !BusyADC() )
    {
    ConvertADC();
    }
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }

    compteur_IT++;
    if(compteur_IT == 1500)
    {
    resultat_conversion[indexChanel]=( unsigned char )ReadADC();
    indexChanel=0;
    compteur_IT=0; // On remet le compteur à zero
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }
    }

  16. Publicité
  17. #13
    monnoliv

    Re : aide

    Juste en passant:
    Quand après un if, tu n'as qu'une instruction, tu n'es pas obligée de mettre les accolades, de plus indente ton programme.
    Ton code devient tout de suite plus clair:

    Avant:
    Code:
    compteur_IT++;
    if(compteur_IT==200)
    {
    if( !BusyADC() )
    {
    ConvertADC();
    }
    INTCONbits.TRM0IF=1; // activer le flag du timer0
    }
    Après:
    Code:
    compteur_IT++;
    if(compteur_IT==200)
     {
      if(!BusyADC()) ConvertADC();
      INTCONbits.TRM0IF=1; // activer le flag du timer0
     }
    Ne soldez pas grand mère, elle brosse encore.

  18. #14
    agno

    Re : aide

    Merci pour les remarques mais je préfère mettre des accolades partout pour ne pa oulblier là où il faut.
    De plus mon code est indenté dans mon programme sauf que je sais pas comment le faire sur le forum.

  19. #15
    umfred

    Re : aide

    Citation Envoyé par agno
    De plus mon code est indenté dans mon programme sauf que je sais pas comment le faire sur le forum.
    Il faut l'inclure entre des balise [ code ] et [ /code ] (sans les espaces).

    Concernant ton code, une interruption toutes les 10 ms serait plus judicieux. Et je ne vois pas l'intérêt de faire 6 fois la même séquence de suite (je n'ai pas vu de différence dans ces 6 séquences, mais si tu veux lire les 6 voies analogiques à la suite une seule séquence suffit), sachant qu'à la fin d'une séquence, tu peux remettre à zéro ton compteur Compteur_IT.
    Pour savoir si tu a fini de lire les 6 voies, tu veux regarder à la fin si ton index est égale à 6 (ou à 7 plutot à cause de l'incrémentation).

Sur le même thème :

Discussions similaires

  1. Aide UT
    Par biolycéen dans le forum Orientation après le BAC
    Réponses: 5
    Dernier message: 12/07/2007, 17h11
  2. aide
    Par khmis_dades dans le forum Électronique
    Réponses: 1
    Dernier message: 16/04/2007, 12h36
  3. Aide !
    Par Papy1 dans le forum Logiciel - Software - Open Source
    Réponses: 8
    Dernier message: 30/08/2006, 11h15
  4. aide dm
    Par elody34 dans le forum Mathématiques du supérieur
    Réponses: 5
    Dernier message: 05/10/2005, 13h32