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

Besoin d'aide ! Problème de réglage d'horloge et interruptions - PIC18 -MPLABX XC8 - Proteus
florian.wyss
Membre
Membre
Messages : 12
Âge : 39
Enregistré en : septembre 2017
Localisation : Lausanne - Suisse

#1 Message par florian.wyss » mar. 12 sept. 2017 11:47 lien vers la Data-Sheet : Cliquez ici

Mots clefs: PIC18f4523; XC8; Proteus; UART; Programmation; baudrate; réglage fréquence horloge, interruptions.

Bonjour à tous,

Ce poste est la suite d'une question que j'ai posé sur futura-science et qui ne trouve pas réponse depuis quelques temps déjà. J'ai entendu dire qu'il y avait des personnes à même de m'aider sur ce site (merci Mr. Fantaspic :wink: )

En résumé j'ai un PIC18f4523 à faire tourner à 32 MHz afin de pouvoir exploiter 2 capteurs angulaires (quadrature incrémental) et un capteur de force (convertisseur AD 12 bits), il faut que je récupère leurs signaux à une fréquence de 2,5 MHz :roll: pour pouvoir filtrer et au final envoyer un "message" propre de 40 bits toute les milliseconde sur une UART configurée à 115.2 kbds ... Vous me suivez :-D

Alors mon problème est le suivant: Toute ma configuration de l'oscillateur est ok (selon moi), la configuration de mon UART est ok également (~2% d'erreur) et malgré ça mon programme tourne au ralentit sur mon simulateur (Proteus) j'ai une fréquence réelle (mesurée dans une boucle while d'attente) de 2 MHz. Premier truc bizarre Ma UART fonctionne normalement est mes messages sont visibles sur le terminal virtuel malgré cette fréquence visiblement trop faible !?!

Voici mon code de configuration de mon oscillateur:

Code : Tout sélectionner

/**
 * Bits de configuration:
 */
#pragma config CONFIG1H = 0X8       // Oscillateur interne avec RA6 et 7 en I/O
#pragma config IESO = OFF           // Pas de démarrage à deux vitesses
#pragma config FCMEN = OFF          // Pas de monitorage de l'oscillateur.
#pragma config MCLRE = ON           // RE3 est actif comme master reset.
#pragma config WDT = OFF            // Watchdog inactif (pour ICSP /ICD)
#pragma config LVP = OFF            // Single Supply Enable bits off.

...

void hardwareInitialise(){

    // Configure le micro contrôleur pour 32MHz
    

    OSCCONbits
.SCS0 = 0;        // sélectionne l'oscillateur interne avec PLL
    OSCCONbits.SCS1 = 1;    
    OSCCONbits
.IRCF0=1;         // Fréquence de base: 8/1 = 8 MHz
    OSCCONbits.IRCF1=1;
    OSCCONbits.IRCF2=1;

    OSCTUNEbits.PLLEN = 1;      // active le PLL (x4) FOSC = 32 MHz.
    



Code : Tout sélectionner



    
//Configuration de l'UART pour une transmission à 115.2 kbd    
        // Pour une fréquence de 32 MHz, ceci donne 115200 bauds :
    TXSTA1bits.BRGH = 1;        // Mode haute vitesse.
    //BAUDCONbits.BRG16 = 1;    // Active la lecture de SPBRG sur 16 bits
    SPBRGH = 0x10;              // N = 16 = 0x10
    NOP();                      // Temps d'arrêt pour permettre l'enregistrement
    SPBRG = 0x22;               //Baudrate = FOSC / (16 * (N + 1)) = 117640 Bauds.
    // Configure RC6 et RC7 comme entrées digitales, pour que
    // la EUSART puisse en prendre le contrôle:
    TRISCbits.RC6 = 1;
    TRISCbits.RC7 = 1;
    // Configure l'UART:
    TXSTA1bits.SYNC = 0;         // Mode asynchrone.
    TXSTA1bits.TXEN = 1;         // Active l'émetteur.
    RCSTA1bits.SPEN = 1;         // Active l'UART.
    PIE1bits.TX1IE = 1;          // Acive les interruptions pour l'UART
    IPR1bits.TX1IP = 0;          // interruptions de basse priorité pour l'UART
    


Autre truc bizarre: La configuration de mes interruptions est comme inactive, quand je modifie TMRxH afin de changer la valeur du débordement cela n'a aucun effet sur la fréquence de mes interruptions (de nouveau mesuré sur la simulation) par contre si je modifie la valeur du prédiviseur je vois un effet sur cette fréquence ... C'est comme si le compteur TMRxH était inactif ... Et pourtant ma config m'a l'air à nouveau ok:

Code : Tout sélectionner


        
// Temporisateur 1: Échantillonnage du capteur de force
    T1CONbits.TMR1CS = 0;       // Raccordé sur Fosc/4 = 8 MHz (0)
    T1CONbits.T1CKPS = 0x2;     // Diviseur de fréquence TPS = 8 (ox2)= 1 MHz
    T1CONbits.T1RUN = 0;        // Le timer 0 ne dépend pas de timer 1
    T1CONbits.T1RD16 = 1;       // Temporisateur de 16 bits. (1)
    // Calcul: 1 MHz /2500, 2^16-400 = 65136 = 0xFE70
    TMR1H = 0x01;               // Etablit le compteur pour un débordement
    NOP();                      // Temps d'arrêt pour permettre l'enregistrement
    TMR1L = 0x90;               // à 400 -> T = 0.4 ms -> f = 2500 Hz
    T1CONbits.T1OSCEN = 0;       // pas d'activation de l'osc du timer 1 (32kHz))
    T1CONbits.TMR1ON = 1;       // Active le temporisateur 1 (1)
    PIE1bits.TMR1IE = 1;        // Active les interruptions.
    IPR1bits.TMR1IP = 0;        // Interruptions de basse priorité.
    
    
/*
     * Remarque: Malgré l'ajout d'un NOP entre TMRH et TMRL comme précisé dans
     * l'ERRATA du PIC18F4523, la fréquence d'envoi ne dépasse pas les 611 Hz.
     */
 
        
// Temporisateur 0: Envoi du message sur la UART
    T0CONbits.TMR0ON = 1;       // Active le temporisateur (1)
    T0CONbits.T0CS = 0;         // Source interne: FOSC / 4 => 8 MHz (0))
    T0CONbits.T0SE = 0;         // Incrémentation au flant montant du cpt (0)
    T0CONbits.PSA = 0;          // Active le diviseur de fréquence (0).
    T0CONbits.T08BIT = 0;       // Compteur de 16 bits.
    T0CONbits.T0PS = 0x2;     // Div. de fréquence /8 (0x2) TPS => 1MHz 
    // Calcul: 1MHz/1000 Hz = 1000, 2^16-1000 = 64536 = 0xFC18
    TMR0H = 0xFC;               // Établit le compteur pour (0xFC18)
    NOP();                      // Temps d'arrêt pour permettre l'enregistrement
    TMR0L = 0x18;               // un débordement à 1 ms -> f = 1 kHz
    INTCONbits.TMR0IE = 1;      // Active les interruptions pour timer 0.
    INTCON2bits.TMR0IP = 1;     // Interruptions de haute priorité.
    
    
// Active les interruptions générales:
    RCONbits.IPEN = 1;           // Interruptions de basse et de haute priorité
    INTCONbits.GIEH = 1;         // Interruptions de haute priorité activées
    INTCONbits.GIEL = 1;         // Interruptions de basse priorité activées

    // Configure les ports IO:
    TRISA = 0b11111111;  // Tous les bits du port A comme entrées
    TRISB = 0b11111101;  // Tous les bits du port B comme entrées sauf b1
    TRISC = 0b11000000;  // Tous les bits du port C comme sorties sauf TX et RX
    TRISD = 0b11111111;  // Tous les bits du port C comme entrées
    


Mon main ne m'a pas l'air trop surchargé, ces deux programmes récupèrent les miettes, mais normalement ça devrait aller, ils devraient tourner à plus de 2000 Hz chacun en sachant qu'ils font qqch à une fréquence max de 500 Hz (les autres passages sont des contrôles que rien n'a changé entre temps).

Code : Tout sélectionner



void main
(void) {

    // Initialise le hardware:
    hardwareInitialise();

   while(1) {
        Capt_genou();
        Capt_hanche();
    }

}



Enfin, si qqun s'y connait et qu'il arrive à me débloquer ça serait vraiment toppissime !!
Je dois dire que je suspect Proteus d'être mal configuré .. mais je n'ai rien trouvé de bizarre dans son paramétrage ... Ou cette histoire de paramétrage des interruptions, c'est comme si je ne pouvais pas aller plus vite sans augmenter la fréquence d'horloge de mon uc ...

à très bientôt et merci de m'avoir lu jusqu'au bout :bravo: Merci !

Besoin d'aide ! Problème de réglage d'horloge et interruptions - PIC18 -MPLABX XC8 - Proteus
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2595
Enregistré en : juillet 2016
Localisation : Terre

#2 Message par Temps-x » mar. 12 sept. 2017 13:33 lien vers la Data-Sheet : Cliquez ici

Bonjour florian.wyss, et bonjour tous le monde

et malgré ça mon programme tourne au ralentit sur mon simulateur (Proteus)


:sifflotte: Quelle version de Proteus as tu ?

Parce que la mienne est une version 8.1, et je peux te dire que mes programmes écrit en ASM fonction pas vraiment. :furieux:

Par contre(dans la vraie vie), quand je fais le montage ça fonctionne très bien, :roll: je pense que leurs logiciel ne doit pas
tourner bien rond.

ça aide, mais ça fait pas tous, essai sur plaque d'essai, le direct c'est mieux.

idea ! Et pour te le démontrer, je peux te passer un schéma, avec le programme que j'ai écrit, et tu verras comment ça déconne leurs
sof, :lol: pourtant c'est un truc tous simple.

A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Besoin d'aide ! Problème de réglage d'horloge et interruptions - PIC18 -MPLABX XC8 - Proteus
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » mar. 12 sept. 2017 20:15 lien vers la Data-Sheet : Cliquez ici

Bonsoir,

JE rejoins Temps-X , la simulation à ces limites.

AU pire essaye de faire un code plus simple et voit ce que ca donne ! puis tu le complexifie au fur et à mesure .
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Besoin d'aide ! Problème de réglage d'horloge et interruptions - PIC18 -MPLABX XC8 - Proteus
florian.wyss
Membre
Membre
Messages : 12
Âge : 39
Enregistré en : septembre 2017
Localisation : Lausanne - Suisse

#4 Message par florian.wyss » mar. 12 sept. 2017 23:46 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous et merci pour vos réponses Merci !

J'ai déjà commencé par réviser mes bits de configuration avec le petit outil de génération automatique et raccordé mon montage.

Code : Tout sélectionner

#pragma config OSC = INTIO67    // Oscillator Selection bits (Internal oscillator block, port function on RA6 and RA7)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 3         // Brown Out Reset Voltage bits (Minimum setting)

// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 1        // Watchdog Timer Postscale Select bits (1:1)

// CONFIG3H
#pragma config CCP2MX = PORTB   // CCP2 MUX bit (CCP2 input/output is multiplexed with RB3)
#pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

// CONFIG4L
#pragma config STVREN = OFF     // Stack Full/Underflow Reset Enable bit (Stack full/underflow will not cause Reset)
#pragma config LVP = OFF        // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L ...


C'est plus propre ...

Grace au montage je peux tester en temps réel et notamment envoyer une trame 0b1 sur l'uart à chaque débordement du timer 0. Ainsi je peux surveiller à l'oscilloscope ce qui sort en vrai de mon interruption et le résultat est sans appel: Un paquet est émis toute les 0,26 seconde en réel alors qu'avec le même code sur simulateur il est émis toute les 0.065 secondes :mur: :mur: :mur: donc c'est encore pire ! mon uc tourne 4x plus vite en simulation qu'en réalité ! :cry: :cry: :cry:

Et en réel également la modification des registres TMROH et TMROL n'a aucun effet...

... (2h plus tard)

J'ai avancé dans mes recherches (et surtout relis attentivement le cours que j'avais eus y a deux ans) et j'ai reconfigurer mes timers comme il faut (avec les mêmes calculs que dans mon cours) et surtout mis les TMRxH et TMRxL à l'intérieur des interruptions ! ça m'a changé complètement le comportement ! Maintenant mes interruptions se succèdent à 80 kHz sans jamais exécuter le programme qu'elles doivent faire ! :roll: :lol: :cry:

Et si je fais tourner uniquement mes interruptions haute priorité elle vont à 100 KHz oops

Code : Tout sélectionner


void low_priority interrupt interruptionsBassePriorite
() {
    
     
// Traitement des conversions AD
    if (PIR1bits.TMR1IF){             //interruption sur débordement du timer 2
        
        PIR1bits
.TMR1IF = 0;
        
        
// Calcul: TMR1*div = 8 MHz / (4*2.5kHz) = 800 => div = 1
        // TMR1 = 2^16 - 800 = 64736 = 0xFCE0 
        TMR1H = 0xFC;               // Etablit le compteur pour un débordement
        NOP();
        TMR1L = 0xE0;               // à 400 -> T = 0.4 ms -> f = 2500 Hz   
        
        Capt_forceInterruptions
();
 
    
}
}

/**
 * Point d'entrée des interruptions haute priorité.
 */

/*
 * Remarque: J'ai ajouté un NOP entre TMRH et TMRL comme précisé dans
 * l'ERRATA du PIC18F4523
 */
void high_priority interrupt interruptionsHautePriorite() {

        // Envoi du paquet sur la UART
    if (INTCONbits.TMR0IF){
  
        INTCONbits
.TMR0IF = 0;
        
        
// Calcul: 1MHz/1000 Hz = 1000, 2^16-1000 = 64536 = 0xFC18
        TMR0H = 0xFC;               // Etablit le compteur pour (0xFC18)
        NOP();
        TMR0L = 0x18;               // un débordement à 1 ms -> f = 1 kHz
        
        
//envoiMessage(message_envoi);
        putch(0b1);
        
      
    
}

}


Donc oui, ça tourne plus vite mais ça ne m'avance pas beaucoup ...

Pffff j'ai vraiment l'impression d'apprendre à la dure ... Y a vraiment personne qui arrive à identifier mon erreur de config ?

Code : Tout sélectionner


      
// Temporisateur 1: Echantillonnage du capteur de force
    T1CONbits.TMR1ON = 1;       // Active le temporisateur 1 (1)
    T1CONbits.TMR1CS = 0;       // Raccordé sur Fosc/4 = 8 MHz (0)
    T1CONbits.T1CKPS = 0;       // Diviseur de fréquence inactif
    T1CONbits.T1RUN = 0;        // Le timer 0 ne dépend pas de timer 1
    T1CONbits.T1RD16 = 1;       // Temporisateur de 16 bits. (1)

    T1CONbits.T1OSCEN = 0;       // inactivation de l'oscillateur du timer 1
    PIE1bits.TMR1IE = 1;          // Active les interruptions.
    IPR1bits.TMR1IP = 0;          // Interruptions de basse priorité.
 
    
// Temporisateur 0: Envoi du message sur la UART
    T0CONbits.TMR0ON = 1;       // Active le temporisateur 0 (1)
    T0CONbits.T0CS = 0;         // Source interne: FOSC / 4 => 8 MHz (0)
    T0CONbits.T0SE = 0;         // Incrémentation au flant montant du cpt (0)
    T0CONbits.PSA = 0;          // Active le diviseur de fréquence (0)
    T0CONbits.T08BIT = 0;       // Compteur de 16 bits.
    T0CONbits.T0PS0 = 0;        // Div. de fréquence /8 TPS => 1MHz 
    T0CONbits.T0PS1 = 1;
    T0CONbits.T0PS2 = 0;
    T0CONbits.T0PS3 = 0;
    INTCONbits.TMR0IE = 1;      // Active les interruptions pour timer 0.
    INTCON2bits.TMR0IP = 1;     // Interruptions de haute priorité.




Je suis trop fatigué pour continuer mais si vous avez une piste à me proposer je suis preneur ... :-D

Allé bonne nuit à tous et à demain ..

Besoin d'aide ! Problème de réglage d'horloge et interruptions - PIC18 -MPLABX XC8 - Proteus
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#5 Message par Jérémy » mer. 13 sept. 2017 07:32 lien vers la Data-Sheet : Cliquez ici

Bonjour ,

J'ai regarder vite fait ton code.

Un truc me choc énormément !!!!! c'est que tu exécute une fonction dans une Interruption ....... Grosse erreur !!!!! Une interruption doit être le lus rapide possible, genre lever un drapeau . mais surtout pas exécuter une fonction qui peut être très longue et donc louper une autre interruption ou écraser al fonction ... .

Pour regler tes tempos sans erreur tu peux utiliser ceci : Timer calculator

L'Interruption envoi de paquet sut l'UART me parait bizarre , tu n'as pas une librairie pour l'UART ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Besoin d'aide ! Problème de réglage d'horloge et interruptions - PIC18 -MPLABX XC8 - Proteus
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#6 Message par satinas » mer. 13 sept. 2017 07:39 lien vers la Data-Sheet : Cliquez ici

Bonjour,
Le mot de réglage du port série est sur 16 bits, SPBRGH:SPBRG.
Dans ton programme, tu as un diviseur de 0x1022, ce qui donne une vitesse de 484 bauds si FOSC = 32MHz.
Pour le 115200 bauds (à 2%), il faut mettre SPBRGH = 0 et SPBRG = 16

Besoin d'aide ! Problème de réglage d'horloge et interruptions - PIC18 -MPLABX XC8 - Proteus
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#7 Message par satinas » mer. 13 sept. 2017 13:49 lien vers la Data-Sheet : Cliquez ici

oups, j'avais pas vu que la ligne BRG16 = 1 était commentée.

Sinon, d'après ce que je lis ici, il faut mettre SCS1 et SCS0 à 0 quand on utilise la PLL avec l'oscillateur interne.
http://www.microchip.com/forums/m394573.aspx

Besoin d'aide ! Problème de réglage d'horloge et interruptions - PIC18 -MPLABX XC8 - Proteus
florian.wyss
Membre
Membre
Messages : 12
Âge : 39
Enregistré en : septembre 2017
Localisation : Lausanne - Suisse

#8 Message par florian.wyss » mer. 13 sept. 2017 14:41 lien vers la Data-Sheet : Cliquez ici

En effet ... C'est que je n'ai jamais fait de programme qui nécessitait des interruptions haute priorité ... 10 mots maximum pour pas écraser d'autres registres... ça limite.
Je sais pas trop comment modifier mon code du coup ... je pensais envoyer le message sur la UART toute les ms de façon +- contrôlée. Du coup comment je fais pour y arriver ... Je vais réfléchir à tout ça et je reviens vous donner des news Merci !

Besoin d'aide ! Problème de réglage d'horloge et interruptions - PIC18 -MPLABX XC8 - Proteus
florian.wyss
Membre
Membre
Messages : 12
Âge : 39
Enregistré en : septembre 2017
Localisation : Lausanne - Suisse

#9 Message par florian.wyss » mer. 13 sept. 2017 15:29 lien vers la Data-Sheet : Cliquez ici

Merci ! Merci ! Merci ! Merci !

Et bien ! autant la simulation que le montage réel me donne une fréquence d'envoi absolument très proche des 1kHz (~998 Hz)

Y a vraiment de l'amélioration ! Me reste "plus qu'à"
- Faire fonctionner ma carte Bluetooth HM-10 (une évolution de la HC-05 .. si qqun sais la configurer depuis le PIC je suis preneur, sinon je reçois un convertisseur USB TTL dans 4-5 jours pour le faire avec realterm) ...
- Faire en sorte que mon pc communique avec (pour pouvoir afficher le flux de données sur l'écran) ...
- Et finir mon rapport (60-100 pages + relecture + correction etc ...)
Le tout ça dans un délai de 14 jours ... (je suis pas dans la merde :roll: )

Si vous avez des anciens sujets à me suggérer à propos des deux premiers points (le rapport je sais faire :lol: ) ça serait vraiment très très cool de votre part ! :+1:
Modifié en dernier par florian.wyss le mer. 13 sept. 2017 17:37, modifié 1 fois.

Besoin d'aide ! Problème de réglage d'horloge et interruptions - PIC18 -MPLABX XC8 - Proteus
florian.wyss
Membre
Membre
Messages : 12
Âge : 39
Enregistré en : septembre 2017
Localisation : Lausanne - Suisse

#10 Message par florian.wyss » mer. 13 sept. 2017 15:46 lien vers la Data-Sheet : Cliquez ici

Enfin ... qqun peut me dire d'où vient ce problème :
PrtScr capture_7.jpg


Je vois pas trop d'où ça peut venir ...
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.


Retourner vers « Langage C »

Qui est en ligne

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