Passage d'un PIC 18F252 à un 18F4550
Répondre à la discussion
Affichage des résultats 1 à 16 sur 16

Passage d'un PIC 18F252 à un 18F4550



  1. #1
    inviteee2ce2b6

    Unhappy Passage d'un PIC 18F252 à un 18F4550


    ------

    Bonjour,

    Voilà, j'ai créé un prog sur un PIC18F252 et souhaite maintenant l'utiliser sur un 18F4550 (pour ajouter une fonctionnalité de dialogue par USB avec le PC),

    A code équivalent, pour le 18F4550, pour moi la seule chose qui change, c'est le registre ADCON1 qui doit être à 0b00111101 au lieu de 0b10001101 (gestion différente du choix de AN2 et AN3 comme références + et - des conversion AN.

    Seulement voilà, j'ai un problème :Le programme fonctionne sur le 4550, mais est SUPER LENT (sortie à 1Hz pour peut-être 600 Hz !) et je n'arrive pas à trouver pourquoi.

    Pour expliquer un peu le code : je génère sur RB0 à ,RB5 6 horloges dont la fréquence dépendent de la position en X et Y de 3 joysticks.

    Voici mon code sous le 18F252:
    Code:
    //Déclaration varibles
    int sens[6]; //sens rotation moteurs
    unsigned double JoyDZ[6][2]; //Limites des zones mortes
    unsigned double JoyBd[6][2]; //Mini et Maxi des joysticks
    unsigned int cnt[6]; //compteur moteurs
    unsigned double ANval[6]; //Val num sur RA0 et RA1
    unsigned double periode[6]; //Période liée à RA0
    unsigned double periode2[6]; //Période liée à RA0
    unsigned double tmp;
    unsigned int i; //var de boucle pour procédure autres que void
    unsigned int joy; //var de boucle pour main
    const int valTimer0 = 185;
    const double Pi = 3.14159;
    const double demiPi = 1.570796;
    //unsigned int j;
    
    #include "HeaderJoyboard.h"
    
    char text[13];
    
    
    void interrupt() {
      // Increment value of cnt on every interrupt
      if (!(sens[0]==0)) {++cnt[0];}
      if (!(sens[1]==0)) {++cnt[1];}
      if (!(sens[2]==0)) {++cnt[2];}
      if (!(sens[3]==0)) {++cnt[3];}
      if (!(sens[4]==0)) {++cnt[4];}
      if (!(sens[5]==0)) {++cnt[5];}
    
      //Front montant sortie si période atteint
      if (cnt[0] >= periode[0]) {PORTB.F0 = 1; cnt[0] = 0;}
      if (cnt[1] >= periode[1]) {PORTB.F1 = 1; cnt[1] = 0;}
      if (cnt[2] >= periode[2]) {PORTB.F2 = 1; cnt[2] = 0;}
      if (cnt[3] >= periode[3]) {PORTB.F3 = 1; cnt[3] = 0;}
      if (cnt[4] >= periode[4]) {PORTB.F4 = 1; cnt[4] = 0;}
      if (cnt[5] >= periode[5]) {PORTB.F5 = 1; cnt[5] = 0;}
    
      //Remise à 0 sortie sur interruption suivante
      if (cnt[0] >= periode2[0]) {PORTB.F0 = 0;}
      if (cnt[1] >= periode2[1]) {PORTB.F1 = 0;}
      if (cnt[2] >= periode2[2]) {PORTB.F2 = 0;}
      if (cnt[3] >= periode2[3]) {PORTB.F3 = 0;}
      if (cnt[4] >= periode2[4]) {PORTB.F4 = 0;}
      if (cnt[5] >= periode2[5]) {PORTB.F5 = 0;}
      
      //Réinitialiser le Timer0
      TMR0L   = valTimer0; //Délai=(256-PRC)*4*PRD*1/FH
      INTCON = 0x20; // Set T0IE, clear T0IF   0x20
    }
    
    
    void main() {
      initIO();
      initVars();
      initTimer0();
    
    //unsigned int joy; //numéro du joystick à lire
      do {
        //conversions AN
        for (joy=0; joy<3; ++joy) {
          if (joy==0) {PORTC.F0=1;}
          if (joy==1) {PORTC.F1=1;}
          if (joy==2) {PORTC.F2=1;}
    
          //delay_ms(10); //pour analyser le fonctionnement
          ANval[joy*2] = Adc_Read(1) + 1;
          ANval[joy*2+1] = Adc_Read(0) + 1;
          PORTC=0x00;
        }
        calcPeriodes();
      } while(1);
    }
    
    //Calcul périodes avec rapport cyclique à 50%
    void calcPeriodes() {
      for (i=0; i<6; ++i) {
        if (ANval[i] > JoyDZ[i][1]) {
          tmp = (ANval[i] - JoyDZ[i][1]) / (JoyBd[i][1] - JoyDZ[i][1]) * demiPi ;
          periode[i] = 1 / (0.03 * sin(tmp));   //tmp = sin(tmp);
          periode2[i] = periode[i] * 0.5;
          sens[i] = 1;
        }
        else if (ANval[i] < JoyDZ[i][0]) {
          tmp = (ANval[i] - JoyBd[i][0]) / (JoyDZ[i][0] - JoyBd[i][0]) * demiPi + demiPi;
          periode[i] = 1 / (0.03 * sin(tmp));   //tmp = sin(tmp);
          periode2[i] = periode[i] * 0.5;
          sens[i] = -1;
        }
        else {
          sens[i] = 0;
        }
      }
    }
    
    void initIO() {
      //initialisation RA0 et convertion A/N
      ADCON1 = 0b10001101; //0x80; //OxC0 RA0 et RA1 as A/N
      TRISA = 0b00001111; //PORTA = INPUT or OUTPUT
      TRISC = 0x00;
      PORTC = 0x00;
      TRISB = 0x00;
      PORTB = 0x00;
    }
    
    //init LCD sur portB
    void initLCD() {
      Lcd_Config(&PORTB, 4, 5, 6, 3, 2, 1, 0); // Initialize LCD connected to PORTB
      LCD_Cmd(LCD_CLEAR);       // Clear display
      LCD_Cmd(LCD_CURSOR_OFF);  // Turn cursor off
    }
    
    //Init du timer0 interruption unique
    void void initTimer0() {
      T0CON = 0b11000000; // PORTB pull-ups disabled, prescaler TMR0=1:2
      TMR0L  = valTimer0;      // Valeur de départ du timer
      INTCON = 0xA0;    // Enable TMRO interrupt
    
    }
    
    void initVars() {
      for (i=0; i<6; ++i) {
        JoyBd[i][1]=1024; //1024 maxi
        JoyDZ[i][1]=640; //maxi de la zone morte
        JoyDZ[i][0]=570; //mini de la zone morte
        JoyBd[i][0]=1; //au moins 0
        sens[i]=0;
        cnt[i]=0;
        periode[i]=2;
        periode2[i]=1;
      }
    }
    Si vous avez une piste...

    Mikaël

    -----

  2. #2
    inviteee2ce2b6

    Question Re : Passage d'un PIC 18F252 à un 18F4550

    J'ai repassé en revue les datasheets et je ne vois pas ce que j'oublie...

  3. #3
    gcortex

    Re : Passage d'un PIC 18F252 à un 18F4550

    sortie à 1Hz pour peut-être 600 Hz
    çà ressemble à un problème d'horloge -> programmation des "fusibles"


  4. #4
    inviteee2ce2b6

    Re : Passage d'un PIC 18F252 à un 18F4550

    Peut-être, je vais vérifier ce soir.
    En fait je programme avec MikroC de MikroElektronika et le réglage de la fréquence d'horloge et du type de PIC est paramétré dans une fenêtre du projet.
    Pour créer mon projet pour le PIC18F4550, j'ai en fait juste fait un copier/coller du projet sur 18F252 et ai changé le modèle du PIC (le quartz étant identique), et la valeur de ADCON1. Donc je ne vois pas ce qui peut être mal paramétré...

    A moins qu'il y ai une incidence par rapport au fait que le 4550 ait un port USB intégré et qu'il faille paramétrer les horloges, pré et post-diviseurs internes !?!

    Mikaël

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

    Re : Passage d'un PIC 18F252 à un 18F4550

    Va dans Projet > Edit projet
    et donnes-nous la config des fuz.

  7. #6
    invite219b5772

    Re : Passage d'un PIC 18F252 à un 18F4550

    N'utilise par MikroC c'est de loin le pire compilateur d'u fait qu'il cache pas mal tout (exemple les fusible).
    Il n'est pas certifier par Microchip
    http://www.microchip.com/stellent/id...e=wwwCompilers
    utilise soit C18 ou Hi-TECH

    -Nik-

  8. #7
    inviteee2ce2b6

    Re : Passage d'un PIC 18F252 à un 18F4550

    Les fusibles validés sont :
    _FOSC_INTOSC_HS_1H = $00FB
    _FOSC_HS_1H = $00FC
    _FOSC_HSPLL_HS_1H = $00FE
    _WDT_OFF_2H = $00FE
    _LVP_OFF_4L = $00FB
    _XINST_OFF_4L = $00FB

    Citation Envoyé par nhenri Voir le message
    N'utilise par MikroC c'est de loin le pire compilateur d'u fait qu'il cache pas mal tout (exemple les fusible).
    Il n'est pas certifier par Microchip
    http://www.microchip.com/stellent/id...e=wwwCompilers
    utilise soit C18 ou Hi-TECH

    -Nik-
    nhenri, j'ai choisi MikroC parce qu'il permet le débuguage avec EasyPIC5 et que les biblis sont faciles à utiliser...
    De plus, je ne suis qu'amateur, on verra plus tard pour optimiser...

    Mikaël

  9. #8
    inviteee2ce2b6

    Re : Passage d'un PIC 18F252 à un 18F4550

    petit up pour de l'aide, je n'arrive vraiment pas à trouver par moi-même...

  10. #9
    RISC

    Re : Passage d'un PIC 18F252 à un 18F4550

    Salut,
    Citation Envoyé par Platipu$ Voir le message
    Pour créer mon projet pour le PIC18F4550, j'ai en fait juste fait un copier/coller du projet sur 18F252 et ai changé le modèle du PIC (le quartz étant identique), et la valeur de ADCON1. Donc je ne vois pas ce qui peut être mal paramétré...

    A moins qu'il y ai une incidence par rapport au fait que le 4550 ait un port USB intégré et qu'il faille paramétrer les horloges, pré et post-diviseurs internes !?!

    Mikaël
    Le système d'horloge du PIC18F4550 est beaucoup plus sophistiqué que celui du PIC18F252.
    La valeur du quartz à l'extérieur ne préjuge pas de la fréquence interne car il existe effectivement des pré et post diviseurs qui déterminent les fréquences de l'USB et du CPU.
    Il y a une PLL x24 dans ce PIC qui fait qu'il faut un multiple de 4MHz à l'entrée de la PLL. Si tu as 8MHz, tu divises par 2.

    Le plus simple est de chercher un projet fait pour le PIC18F4550 et de vérifier les valeurs des bits de configuration

    a+

  11. #10
    invite5982407c

    Re : Passage d'un PIC 18F252 à un 18F4550

    Voici un exemple de paramétrage pour un PIC4550 (ou 4553) avec un quartz de 20Mhz au cas où ça pourrait t'aider


    'Configuration:
    ' Regler le MCU clock a 48Mhz ! (96Mhz/2)
    'CPU pre-scaler -> divisé par 5 pour obtenir 20/5=4 Mhz qui devient ensuite le 48Mhz de façon interne
    'CPU Systemclock Postscaler OSC1/OSC2 Src:/1 96Mhz PLL Src:/2
    'Full USB Clock source: Clock src from OSC1/OSC2
    'Oscillator: HSHS+PLL, USB+HS
    'Fail Safe Clock: Disable
    'Internal/Extarnal switch: Disabled
    'Power up timer: Disabled
    'Brown Out Detect: Enabled in hardware, SBOREN disabled
    'Brown out voltage: 2.0V
    'USB Voltage: Disabled
    'Watchdog Timer: Disabled-Controled by SWDTEN bit
    'Watchdog Poscaler: 1:32768
    'Port B A/D Enabled: PORTB configured as digital I/O on RESET
    'Master Clear Enable: MCLR enabled, RE3 Disabled
    'Stack overfow Reset: Enabled
    'Low voltage Program: Disabled
    'Boot Block Size Select 1KW

    'Reste: Disabled



    Ensuite le paramétrage du main (sous Mikrobasic):




    TRISA = %00010111 ' PORT A (1=entrée, 0=sortie)
    TRISB = %00000011 ' PORT B
    TRISC = %00110100 ' PORT C
    TRISD = %00000011 ' PORT D
    TRISE = %00000000 ' PORT E

    INTCON.INT0IE = 1 ' autorise INTO (=compteur vitesse)
    INTCON.INT0IF = 0 ' flag INT0 à zéro

    INTCON3.INT1IE = 1 ' autorise interruption INT1 (RFID)
    INTCON3.INT1IF = 0 ' flag INT1 à zéro
    INTCON3.INT1IP= 0 ' priorité basse

    INTCON.INTEDG0=1
    INTCON2.INTEDG1=1 ' selectionne front montant
    INTCON.GIE = 1 ' autorise interruptions
    UCON.USBEN = 0 'désactive l'USB sur port C4 et C5
    UCFG.UTRDIS = 1 'désactive le transmetteur USB sur port C4 et C5

  12. #11
    invite2de7076a

    Re : Passage d'un PIC 18F252 à un 18F4550

    Citation Envoyé par nhenri Voir le message
    N'utilise par MikroC c'est de loin le pire compilateur d'u fait qu'il cache pas mal tout (exemple les fusible).
    Il n'est pas certifier par Microchip
    http://www.microchip.com/stellent/id...e=wwwCompilers
    utilise soit C18 ou Hi-TECH
    Ou tu vois qu'il n'est pas certifié Microchip???
    Ce que tu donnes comme page c'est la page des compilateurs de Microchip.

    J'utilise MikroC et je le trouve très bien.

    Mikroelektronika est le Design partner de Microchip:
    http://www.mikroe.com/eng/home/index/
    (bas de page à gauche)

    Les fusibles de sont pas "cachés" mais juste mis en dehors du code.

  13. #12
    inviteee2ce2b6

    Re : Passage d'un PIC 18F252 à un 18F4550

    Merci à tous pour votre aide.

    J'ai tenté de configurer les fusibles comme il faut:
    comme mon quartz est à 20Hz, je valide le fusible _PLLDIV_5_1L pour obtenir les 4MHz nécessaires.

    Ensuite, comme je souhaite tester mon prog à l'identique, je programme les fusibles pour utiliser le quartz comme horloge du prog soit: _CPUDIV_OSC1_PLL2_1L et _FOSC_HS_1L

    Je valide aussi les fusibles suivants :
    _WDT_OFF_2H, le chien de garde
    _LVP_OFF_4L, parce que tjrs validé sur les progs de test et pas d'incidence visible sinon
    _XINST_OFF_4L, parce que tjrs validé sur les progs de test et pas d'incidence visible sinon

    Le problème est toujours présent, mais sous une autre forme :
    Le prog est plus rapide qu'avant, mais l'affichage sur les calculs sont plus lents...
    Par contre, j'ai l'impression que les sorties sont à la bonne fréquence (à vérifier par oscillo).

    En fait, maintenant, même si mes sorties semblent bonnes, le temps de réaction lorsque que bouge un joystick est de 2 secondes environ, contre quasi immédiat sur le 252...

    Une idée ?

  14. #13
    RISC

    Re : Passage d'un PIC 18F252 à un 18F4550

    Salut,

    Beaucoup sur ce forum (comme moi) utilisent le C18. On ne peut donc comprendre le paramétrage des fusibles que tu montres.
    Peux-tu faire voir une copie d'écran de MPLAB ( Configure > Configuration bits) ?

    a+

  15. #14
    invite219b5772

    Re : Passage d'un PIC 18F252 à un 18F4550

    nutilise pas les fuse dans l'interface tape les directement dans ton code, les configuration se trouve dans le .inc de ta chip

    exemple si tu utilise le pic18f26j50 et que C18 est installer directement sur le C: et bien

    C:\MCC18\mpasm\P18LF26J50.INC contient les config de fuse
    ensuite dans ton code tu ecrit de koi comme sa:

    #pragma config WDTEN = OFF //WDT disabled (enabled by SWDTEN bit)
    #pragma config PLLDIV = 2 //Divide by 3 (12 MHz oscillator input)
    #pragma config STVREN = ON //stack overflow/underflow reset enabled
    #pragma config XINST = ON //Extended instruction set enable
    #pragma config CPUDIV = OSC1 //OSC1 OSC4_PLL6 //No CPU system clock divide
    ETC ...

    -Nik-

  16. #15
    inviteee2ce2b6

    Question Pb execution code sur un 18F4550

    Bonjour,

    Nouveau rebondissement. Je suis passé de MikroC à MikroC Pro et maintenant, le prog marche au bon rythme. Seulement, un nouveau pb est apparu :

    Dans le code suivant, j'ai une condition qui, même si elle est vrai (vérifié par affichage des valeurs sur un LCD) ne permet pas de lancer le code correspondant. La condition est : "(ANval[i] < JoyDZ[i][0])"
    Le code de la fonction est le suivant :
    Code:
    void calcPeriodes() {
      for (i=0; i<6; ++i) {
        if (ANval[i] < JoyDZ[i][0]) {joy = 1;}
        if ( (ANval[i] >= JoyDZ[i][0]) && (ANval[i] <= JoyDZ[i][1]) ) {joy = 2;}
        if (ANval[i] > JoyDZ[i][1]) {joy = 3;}
        if (i<3) {
           WordToStr(ANval[i], text);
           LCD_Out(1,6*i,text);
           WordToStr(JoyDZ[i][0], text);
           LCD_Out(2,6*i,text);
        }
        switch (joy) {
          case 1:
            tmp = (ANval[i] - JoyBd[i][0]) / (JoyDZ[i][0] - JoyBd[i][0]) * demiPi + demiPi;
            periode[i] = 1 / (0.03 * sin(tmp));   //tmp = sin(tmp);
            //periode2[i] = periode[i] * 0.5;
            sens[i] = 1;
            switch (i) {
              case 0: motsens &=  0b11111110; break;
              case 1: motsens &=  0b11111101; break;
              case 2: motsens &=  0b11111011; break;
              case 3: motsens &=  0b11110111; break;
              case 4: motsens &=  0b11101111; break;
              case 5: motsens &=  0b11011111; break;
            }
            break;
          case 2:
            sens[i] = 0;
            break;
          case 3:
            tmp = (ANval[i] - JoyDZ[i][1]) / (JoyBd[i][1] - JoyDZ[i][1]) * demiPi ;
            periode[i] = 1 / (0.03 * sin(tmp));   //tmp = sin(tmp);
            //periode2[i] = periode[i] * 0.5;
            sens[i] = 2;
            switch (i) {
              case 0: motsens |= 0b00000001; break;
              case 1: motsens |= 0b00000010; break;
              case 2: motsens |= 0b00000100; break;
              case 3: motsens |= 0b00001000; break;
              case 4: motsens |= 0b00010000; break;
              case 5: motsens |= 0b00100000; break;
            }
            break;
        }
      }
    }
    En fait, le ANval sont les valeurs de position de certains joysticks, JoyDZ les valeurs de limite de zone morte de cde. Mot sens est le mot de gestion du sens de rotation de 6 moteurs.
    Concrètement, le code réagit si je pouse le joystick vers le haut, il reconait si celui-ci est au "point mort", mais pas de réaction s'il est vers le bas (comme si je le bougais pas).

    Je joint le code sous MikroC (projet et .c) et une image des fusible si ça peut être utile.

    SVP j'ai besoin de votre aide, j'ai essayé de résoudre ça tout le WE sans succès. Soit c'est une grosse erreur que je vois pas tellement elle est énorme, soit c'est une subtilité que je ne maitrise pas encore...

    Mikaël
    Images attachées Images attachées
    Fichiers attachés Fichiers attachés

  17. #16
    inviteee2ce2b6

    Re : Pb execution code sur un 18F4550

    Petit up... J'ai toujours pas trouvé. Et je suis sûr que c'est simple en plus !

Discussions similaires

  1. probleme 2 interruption pic 18f4550 pic ->plante
    Par invite4ec38ea0 dans le forum Électronique
    Réponses: 5
    Dernier message: 28/08/2010, 08h51
  2. Problème synchronisation SPI pic 18F252
    Par invite7ba2f4a0 dans le forum Électronique
    Réponses: 3
    Dernier message: 16/08/2010, 17h43
  3. pic 18f4550
    Par invite8a14e47c dans le forum Électronique
    Réponses: 3
    Dernier message: 06/04/2010, 22h41
  4. Pic 18f4550
    Par invitee0468afd dans le forum Électronique
    Réponses: 4
    Dernier message: 18/06/2009, 00h39
  5. Pic 18f4550
    Par Gérard dans le forum Électronique
    Réponses: 8
    Dernier message: 07/06/2006, 00h42
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...