Problème fréquence timer dspic33
Répondre à la discussion
Affichage des résultats 1 à 4 sur 4

Problème fréquence timer dspic33



  1. #1
    invite89ab9488

    Problème fréquence timer dspic33


    ------

    Bonjour,

    Je sollicite (encore) l'aide de connaisseurs en programmation de ucontrôleurs. Alors voilà, mon problème est le suivant. Je programme un dsPIC33FJ256GP710A monté sur une carte explorer 16 pour un stage. Mon algorithme est quasiment finalisé, avec ADC, UART, affichage LCD, mais surtout timers 3, 4 et 7.

    Et le problème vient de ces derniers. En effet, je veux qu'ils tournent à 10 kHz. Mais en fonction des calculs qui s'y trouvent, leur fréquence tend à diminuer et je dois alors la réajuster en diminuant la période dans le registre associé. Mais cela ne paraît pas très correct étant donnant qu'après cela la formule donnée dans la datasheet pour déterminer la période du timer en fonction du prédiviseur et du temps de cycle du MCU n'est plus correcte. Je contourne le problème mais je ne le comprend pas. Selon moi ça doit venir des timers car à priori quand je faisais les mêmes calculs dans le main, cadencés par un flag mis à 1 par le timer, je n'avais plus ce problème et les calculs se faisaient correctement à 10kHz.

    Pour info je vérifie les fréquences avec des LAT=~LAT. Si j'enlève un LAT=~LAT d'un timer je constate que la fréquence de l'autre timer augmente (à priori celle des deux timers mais je ne peux plus vérifier cela sur le premier timer sans LAT=~LAT). C'est comme si je lui demandais trop de calculs mais pourtant j'ai optimisé et pour une fréquence de 10 kHz ça ne me paraît pas très lourd. Je vous laisse le code du timer 3, dans lequel je fais un pseudo-calcul RMS, qui est sûrement plus "lourd" que l'algorithme du timer 4 dans lequel je fais seulement des comparaisons "if". Ce "calcul" RMS comporte une soustraction, une addition, une multiplication et le décalage d'un tableau de 28 cases, tout cela sur des "long". Ce n'est donc vraiment pas lourd en calcul selon moi. Je vous laisse aussi la fonction d'initialisation du timer 3 et celle de l'oscillateur. En revanche, je ne pourrai pas montrer certaines parties du programmes pour des raisons de confidentialité !

    De plus, mon collègues stagiaire a eu des problèmes similaires même avec un dspic différent de celui que j'utilise, mais avec une structure très proche notamment dans la configuration des timer et de l'oscillateur.

    J'espère avoir été assez clair, sinon n'hésitez pas ! Merci d'avance de votre aide
    Alexis


    Code:
    void init_osci(void)
    {
    	//--- configuration of internal oscillator  at 40Mhz ---//
    	// DSPic33FJ256GP710A datasheet --> page 146
    	// Fcy = Fosc / 2 ; Fosc = Fin(M/(N1 N2))
    	// Fin = 8Mhz --> Fosc = 80Mhz --> Fcy = 40Mhz
    	CLKDIVbits.PLLPRE 	= 0; 			// N1 = 2
            CLKDIVbits.PLLPOST 	= 0; 			// N2 = 2
    	PLLFBDbits.PLLDIV 	= 38;			// M = 40
    	__builtin_write_OSCCONH(0x03); 		// assembly code
    	__builtin_write_OSCCONL(0x01);		// clock commutation
    	while(OSCCONbits.COSC != 0b011);
            while(OSCCONbits.LOCK!= 1) {};          // Wait for PLL to lock
    }
    
    void __attribute__((interrupt,no_auto_psv)) _T3Interrupt( void )
    {
    
            IFS0bits.T3IF = 0; 		// remise à zéor du flag d'interruption
            AD1CON1 = 0x84E4;                    /* Force bits 4-7 for automatic sampling */
            t_counter++;
    
            if (t_counter>=10000)
                {t_total++;
                 t_counter=0;}
    
            t_trip++;
            _LATA1=~_LATA1;
            RMS();
    	TMR3 = 0;
    	T3CONbits.TON = 1;		// activer à nouveau le Timer
            
    }
    
    void init_timer3(void)
    {
    
    	T3CONbits.TON = 0; 			// desactivate timer 3 during configuration
    	T3CONbits.TCS = 0;
    	T3CONbits.TCKPS =0 ; 
    	TMR3 = 0;
    	PR3 = 3332; 				
    	//--- registres des configurations des interruptions liées au Timer3 ---//
    	_T3IP = 5; 			// interrupt priority
    	_T3IF = 0; 			// initialize flag
    	_T3IE = 1; 			// enable interruption
    	T3CONbits.TON = 1; 			// activate timer3
    
    }

    -----

  2. #2
    RISC

    Re : Problème fréquence timer dspic33

    Salut,

    Je te recommande de mesurer le temps d'exécution de tes fonctions.
    Si tu as un ICD3 ou Real-Ice, tu utilises la fonction Stopwatch

    Ton code d'interruption intègre une fonction dont il est impossible de savoir le temps d'exécution : RMS().
    C'est généralement le gendre d'erreur qui empèche un uC de fonctionner correctement...car on doit faire le MINIMUM dans une interruption et faire les calculs DANS la boucle principale..C'est une erreur basique et courante des débutants.

    autre problème : c'est une erreur de redémarrer le TIMER3 dans l'interruption...le timer3 continue à tourner y compris quand il déclenche une interruption

    Pour réduire le temps de traitement il faut préferrer LATA = LATA ^ 0x01; à LATA1 = ~LATA1 car les opérations sur les champs de bits sont lentes...comparées aux opérations logiques sur le registre complet (voir l'assembleur)

    a+
    Dernière modification par RISC ; 26/06/2015 à 22h54.

  3. #3
    invite89ab9488

    Re : Problème fréquence timer dspic33

    Salut,

    Tu viens de m'éclairer sur tous mes problèmes ! Merci beaucoup.

    En effet j'ai un ICD3, je vais essayer ça. Mais pourquoi ne peut-il pas connaître le temps d'exécution de cette fonction ? Parce que c'est dans une interruption ?
    En tout cas ça explique clairement pourquoi ça fonctionnait dans la boucle main et pourquoi j'avais des changements de fréquence lorsque je mettais dans les timers. Mais en revanche, mon programme fonctionne très bien au vu des essais que j'ai fait, excepté le fait que j'ai ce problème de fréquence qui m'empêche de compter le temps correctement dans les timers (erreur par rapport à la réalité puisque la fréquence n'est pas exacte) et donc qui nuit fortement à la fonction pour laquelle j'utilise l'uC.
    Mais j'ai choisi de mettre tous mes calculs dans les interruptions afin de pouvoir rendre ces calculs prioritaires par rapport à l'UART. Si je met dans le main, le problème que je ne sais pas résoudre c'est comment l'empêcher d'interrompre mon calcul RMS à 10 kHz et l'autre fonction qui suit. Mon système doit être robuste en temps réel et réagir au plus vite si besoin, et même si l'UART n'émet que toutes les secondes, il y a toujours une probabilité que ça tombe au moment ou mon programme doit réagir. Je devrais utiliser l'UART sans interruption ? Sinon je ne vois vraiment pas...
    Et du coup je comprend moins l'utilité des timers puisqu'on peut faire peu de calculs dedans.
    Et en ce qui concerne le redémarre du timer, tu parles du TMR3 = 0 ou bien du TON=1 ? A priori ça n'a pas posé de problème... A part peut-être que la fréquence est moins précise lors du réglage.
    Et je vais faire la modif pour le LAT !
    En tout cas sincèrement merci, tu viens de me faire faire un pas de géant dans mon travail, je vais enfin pouvoir expliquer mon problème à mon maître de stage et on va gagner en crédibilité !

    Alexis

  4. #4
    RISC

    Re : Problème fréquence timer dspic33

    Salut,
    Avec l'ICD3 on peut mesurer le temps d'exécution de n'importe quelle fonction, qu'elle soit dans l'interruption ou non.
    Avec un dsPIC33FJ256GP710A tu as une fréquence cycle maximum de Fcy = 40MIPS, c'est à dire que 95% des instructions durent 25ns (sauf les call et les goto).
    Pour les timers, la fréquence max à l'entrée est Fcy c'est à dire que le timer possède au mieux une résolution de 25ns.
    Il suffit d'utiliser les priorités, ou encore mieux le DMA car cela travaille en parallèle du CPU (2 bus distincts).
    Cela veut dire que tu peux recevoir des messages UARTS pendant que le CPU traite d'autres infos.
    Je te conseille de regarder l'exemple de code pour utiliser le DMA avec l'UART sur les dsPIC33FJ (CE114). C'est un peu pointu mais une fois que cela marche c'est un régal.
    L'exemple du DMA fonctionne sur la carte EXPLORER16
    a+
    PS : il ne faut jamais redémarrer un TIMER. C'est la source de plein de PB. ton PB se trouve ailleurs. Arrêter ou redémarrer le TIMER n'est qu'une rustine pour cacher un autre PB.
    D'autre part je crois me souvenir que l'UART à une FIFO de 4 niveaux. Sers toi s'en
    Dernière modification par RISC ; 29/06/2015 à 23h46.

  5. A voir en vidéo sur Futura

Discussions similaires

  1. commander un boost avec un DSPIC33
    Par invitecdc657e7 dans le forum Électronique
    Réponses: 3
    Dernier message: 14/04/2015, 20h49
  2. Timer sur attiny85 modifier fréquence
    Par invitef4c6670c dans le forum Électronique
    Réponses: 5
    Dernier message: 29/07/2014, 15h43
  3. Conversion analogique numérique dsPIC33
    Par invitec65d82c7 dans le forum Électronique
    Réponses: 1
    Dernier message: 18/03/2012, 21h32
  4. fixation de la fréquence d'échantillonnage à l'aide du timer
    Par invite32cc11f3 dans le forum Électronique
    Réponses: 0
    Dernier message: 20/05/2010, 12h56
  5. DsPIC33, FFT... Help me !!
    Par invite3b551566 dans le forum Électronique
    Réponses: 1
    Dernier message: 05/11/2006, 19h19
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...