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

AVR ATTiny25 et fonction "attente" d'un cycle de Timer



  1. #1
    Exelandre

    Lightbulb AVR ATTiny25 et fonction "attente" d'un cycle de Timer


    ------

    Bonjour à tous,

    Je programme actuellement sur µC un processus qui doit identifier, et lire les informations enregistrer dans un tag RFID (Radio Frecency IDentification).
    La RFID est la technologie utilisé pour les cartes de transport, certains forfaits de ski ou encore dans les passeports.

    Mon problème est très simple, mais je galère dessus depuis deux jours.
    Je veux créer une sous-fonction qui attend la fin d'un cycle du Timer 1, une sorte de fonction delay ou wait.
    Je travail avec un Atmel ATTiny25 sous AVR Studio.
    J'ai bien essayer de me servir du registre TCNT1 dans lequel le programme écrit la valeur du Timer 1,
    en créant une fonction qui attend la remise à zéro de ce registre (TCNT1=0x00),
    mais ça ne fait rien, comme si le registre ne prenait jamais cette valeur.
    Pourtant, il la prend puisque le Timer passe par zéro à chaque fin de cycle.
    J'ai aussi essayer de me sychroniser sur le PWM qui résulte du Timer 1, mais c'est un .
    Peut-être que l'interruption Timer1_Overflow pourrait marcher mais je ne sais pas m'en servir.

    Donc voilà, un petit casse tête...

    Merci par avance de votre aide.

    Exel

    -----

  2. #2
    Eric0269

    Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Salut,
    T'as trouvé quelque chose ?
    Eric.

  3. #3
    Exelandre

    Unhappy Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Bonjour,

    J'ai essayé de me servir des interruptions, mais je crois que AVR Studio ne les simule pas, parce que rien ne se passe.

    Je ne comprends toujours pas pourquoi la lecture du registre d'écriture du Timer 1 ne s'effectue pas :
    Normalement if(TCNT1==0x00) devrait fonctionner quand le registre est remis à zéro, mais rien ne se passe (au niveau de la simulation).

    Donc je ne sais toujours pas.
    à suivre...

  4. #4
    Eric0269

    Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Bonjour,
    A quoi ressemble ton code ?
    E.

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

    Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Bon, un p'tit bout de code pour mettre en oeuvre ton timer1 avec interruption sur débordement :
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define R_LEDON (PORTB |= _BV(PB3))
    #define R_LEDOFF (PORTB &= ~_BV(PB3))
    #define G_LEDON (PORTB |= _BV(PB4))
    #define G_LEDOFF (PORTB &= ~_BV(PB4))
    
    static volatile uint8_t blink;
    static volatile uint8_t timeout;
    
    ISR(TIM1_OVF_vect)
    {
      timeout = 0x00;
      blink = ~ blink;
      if (blink) {
        R_LEDOFF;
      } else {
        R_LEDON;
      }
    }
    
    int main(void)
    {
      TCNT1 = 0x00;
      DDRB |= _BV(PB3) | _BV(PB4);
      blink = 0;
      timeout = 0xFF;
      TIMSK |= _BV(TOIE1);;
      sei();
      TCCR1 |= _BV(CS13) | _BV(CS12) | _BV(CS11) | _BV(CS10);
      while (1) {
        /* On attend timeout == 0*/
        while (timeout)
          ;
        G_LEDON;
        timeout = 0xFF;
        /* On attend timeout == 0 */
        while (timeout)
          ;
        G_LEDOFF;
        timeout = 0xFF;
      }
      return 0;
    }
    Bien entendu, tu l'arranges à ta sauce.
    Attention au fuse CKDIV8 qui est par défaut programmé => 8Mhz / 8 = 1Mhz pour F_CPU.
    Dans mon cas, j'ai une interruption toutes les (1/8000000)*256*16384 => 0,524288 sec.
    Eric.

  7. #6
    Exelandre

    Wink Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Bonjour,

    Merci Eric pour ton aide.
    Voici mon code.

    Code:
    #define F_CPU 64000000UL
    
    #include <stdint.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <avr/eeprom.h>
    #include <avr/interrupt.h>
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <avr/sleep.h>
    #include <avr/wdt.h>
    #include <util/delay.h>
    #include <ctype.h>
    
    #define up(bit) (_SFR_BYTE(PORTB) |= _BV(bit))
    #define down(bit) (_SFR_BYTE(PORTB) &= ~_BV(bit))
    #define upp(reg,bit) (_SFR_BYTE(reg) |= _BV(bit))
    #define downn(reg,bit) (_SFR_BYTE(reg) &= ~_BV(bit))
    
    
    
    
    
    void wait() //attent début d'un cycle horloge
    {
    
    }
    
    int ConvertModuleToData()
    {
    	wait();
    	int result=-1,clock,module;
    	if(bit_is_set(ACSR,ACO)) module=1;
    	if(bit_is_clear(ACSR,ACO)) module=0;
    	if(TCNT1<=125) clock=1;
    	if(TCNT1>125) clock=0;
    	//fonction OU exclusif//
    	//if((module==1 && clock==0)||(module==0 && clock==1)) result=1;
    	//if(module==clock) result=0;
    	result = clock ^ module;
    	return result;
    }
    
    void Comp(int *p)
    {	
    	int data,i=0;
    	int *q=p;
    
    	do
    	{
    		data=ConvertModuleToData();
    		if(data==1) i++;
    		else i=0;
    	}
    	while(i<9);
    	for(i=0;i<=7;i++)
    	{
    		wait();
    		*q=ConvertModuleToData();
    		q++;
    	}
    }
    
    int main(void)
    {
    	/*initialisation horloge*/
    	//OSCCAL = 0x7F;
    	
    	/*initialisation timer 1*/
    	TCCR1 = _BV(CS11); //facteur de division de l'horloge
    	GTCCR = _BV(PWM1B) |_BV(COM1B0); //mise en marche du PWM et mode toggle
    	PLLCSR = _BV(PCKE)| _BV(PLLE) |_BV(PLOCK);	//choix de la féquence à diviser
    	OCR1B = 128;
    	OCR1C = 255;
    	upp(TIMSK,TOIE1);
    
    	/*initialisation comparateur*/
    	downn(ACSR,ACD); //comparator allumé
    	downn(ADCSRB,ACME); //AIN1 sélectionné
    	downn(ACSR,ACBG); //AIN0 sélectionné
    	upp(ACSR,ACIE); //interrution comparateur autorisée
    	DIDR0 = _BV(AIN1D) |_BV(AIN0D);//mise à 0 de la conversion AN
    	sei();//interruption général autorisée
    
    	/*initialisation port*/
    	DDRB = _BV(PB4) |_BV(PB2) |_BV(PB4);
    	
    
    	int BIT[8]={-1};
    
    
    	for(;;)
    	{
    		Comp(BIT);
    	}
    }
    Je vais essayé de mettre en oeuvre le morceau de code que tu m'as donné.
    Pourrais-tu me précisé quelle est ce type de variable :static volatile uint8_t ?
    je l'ais vu souvent mais je vois pas quelle est son intérêt.

    Je ne comprends pas non plus la fonction de la variable "blink"
    qui est utilisé dans l'interruption.

    Merci.

    Exel

  8. #7
    Exelandre

    Question Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Bon ok, alors uint8_t c'est un octet, d'après ce que j'ai lu.
    Alors serais-tu me dire comment déclarer un bit ?

    Merci.

    Exel

  9. #8
    Eric0269

    Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Il n'y a pas de type bit, par contre tu peux utilser ça :
    Code:
    volatile union io_status
    {
        unsigned char status;
        struct
        {
            unsigned char bit0:1;
            unsigned char bit1:1;
            unsigned char bit2:1;
            unsigned char bit3:1;
            unsigned char bit4:1;
            unsigned char bit5:1;
            unsigned char bit6:1;
            unsigned char bit7:1;
        };
    } io_status_info;
    Pourquoi volatile ? Par défaut, ton code est compilé avec l'option -s pour avoir un binaire le plus petit possible; le problème avec ce genre d'optimisation et surtout si on utilise des interruptions, les variables sont placées dans des registres qui peuvent à tout moment servir à autre choses; pour éviter ce genre de chose, il faut indiquer au compilo de ne pas optimiser certaines variables en plaçant volatile devant ces dernières.
    Pour le la variable blink, à chaque blink =~blink, elle sera égale à son comlèment (0xFF,0x00,0xFF). C'est pas propre, mais fonctionnel, et selon l'inspiration du moment pour répondre à ta question.

  10. #9
    Exelandre

    Angry Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Bonjour,

    Merci pour ton morceau de code,
    j'ai essayé de l'adapter, mais ça ne faisait rien.
    donc j'ai refait un petit bout de code pour testé si ça fonctionnait,
    mais toujours rien ! raaahhh

    Code:
    #define F_CPU 64000000UL
    
    #include <stdint.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <avr/eeprom.h>
    #include <avr/interrupt.h>
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <avr/sleep.h>
    #include <avr/wdt.h>
    #include <util/delay.h>
    #include <ctype.h>
    
    #define up(bit) (_SFR_BYTE(PORTB) |= _BV(bit))
    #define down(bit) (_SFR_BYTE(PORTB) &= ~_BV(bit))
    #define upp(reg,bit) (_SFR_BYTE(reg) |= _BV(bit))
    #define downn(reg,bit) (_SFR_BYTE(reg) &= ~_BV(bit))
    
    
    static volatile uint8_t timeout = 0x00;
    
    ISR(TIMER1_OVF_vect)
    {
      timeout = 0x00;
    }
    void ini()
    {
    	up(2); _delay_ms(500);
    	up(3); _delay_ms(500);
    	down(2); down(3);	
    }
    
    int main(void)
    {
    	/*initialisation timer 1*/
    	TCCR1 = _BV(CS11); //facteur de division de l'horloge
    	PLLCSR = _BV(PCKE)| _BV(PLLE) |_BV(PLOCK); //choix de la féquence à diviser
    	OCR1B = 128;
    	OCR1C = 255;
    	upp(TIMSK,TOIE1);//interruption par débordement autorisé
    	TCNT1 = 0x00;
    	upp(TIFR,TOV1);
    	sei();
    
    	/*initialisation port*/
    	DDRB = _BV(PB2) |_BV(PB3);
    
    	while(1)
    	{		
    		ini();	
    
    		timeout = 0xFF;
    		while(timeout);
    		up(PB2); down(PB3);
    		_delay_ms(1000);
    
    		timeout = 0xFF;
    		while(timeout);
    		up(PB3); down(PB2);
    		_delay_ms(1000);
    	}
    	return 1;
    }
    Pourtant je pense qu'il est bon, mais quand je le test, il bloque sur l'instruction while(timeout), et quand je le fais tourner sur l'µC,
    il met PB2 à 1, et c'est tout.

    Bon, je me met en pause.
    C'est trop bien les interruptions, mais que quand ça marche !

  11. #10
    Eric0269

    Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Salut Exelandre,
    Quelques erreurs à signaler :
    • F_CPU est une macro indiquant la fréquence à la laquelle travaille ton cpu (ici 64Mhz, ce qui veut dire que tes fonctions _delay_ms se basent sur cette fréquence, ce qui n'est pas le cas puisque ton Attiny tourne à 1Mhz, donc F_CPU=1000000UL (8Mhz/8 voir plus haut pourquoi), et l'Attiny au max ne tournera jamais à 64Mhz (cf Datasheet).
      Je pense qu'il est possible de le définir dans les propiétés du projet sous AvrStudio.
    • OCR1A/B/C = registre de comparaison, pas nécessaire dans ton cas puisque tu travailles en débordement sur TCNT1
    • PCK est utilisé comme horloge source (64 Mhz dans ton cas), divisée par 2 (TCCR1 = CS11) => interruption déclenchée toute les (1/64000000) x 2 x 256 = 8µs.
    Ta tempo doit être de combien ?
    E.

  12. #11
    Exelandre

    Post Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Salut Eric,

    Alors pour la fréquence, là je sais plus ! Parce que dans la doc. page 86, ils disent que la fréquence du périphérique est de 64 ou 32 MHz,
    donc je me suis basé sur ça pour mon timer.

    Petite explication, dans mon prog au début, j'initialise les registres du timer 1 pour qu'il me donne de façon ininterrompu un signal carré de 125KHz, soit une période de 8µs, et de rapport cyclique 50%.
    oui, oui, c'est bien ce que tu as vu.
    Donc si tu veux, ça c'est sur que ça fonctionne puisque je l'ai vérifié à l'oscillo.

    Maintenant, il faudrait que je crée deux choses :
    -La première, c'est une interruption en front montant du comparateur.
    -La deuxième, c'est une fréquence de 2KHz qui démarre lors de l'interruption.
    Pour cette fréquence, il ne reste plus que le timer 0.

    Voilà, ça c'est le travail de fond.

    Mais alors tu te dis, pourquoi il nous casse les pieds avec ces interruptions à débordement ?
    Et ben parce que mon but est de parvenir à faire fonctionner une interruption, ici, je me suis intéressé à l'Overflow pour tester. Et aussi parce qu'à vrai dire, dans le cade de mon expérimentation de la RFID, il y a une semaine, je ne voyais pas encore comment traité le signal que je recevais.

    Merci pour ton aide, parce que je pense avoir compris la différence entre F_CPU et PCK.
    Donc F_CUP=1MHz et PCK=64MHz, ils sont tous deux indépendants !
    Voilà qui est plus cohérent.

    Donc le problème reste entier pour les interruptions car même une interruption ANA_COMP ça ne fait rien...
    enfin, je vais quand même vérifier les registres du comparateur.

    Bon, désolé, c'est un peu fouillis mais j'ai le cerveau en ébullition!

    Exel

  13. #12
    Exelandre

    Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Bonjour,

    Et voilà, un truc qui ressemble à quelque chose !!
    Cette fois les interruptions fonctionnent très bien.
    Désolé pour la longueur du programme, mais il faut c'qu'il faut...

    Code:
    #define F_CPU 1000000UL
    
    #include <stdint.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #include <avr/eeprom.h>
    #include <avr/interrupt.h>
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <avr/sleep.h>
    #include <avr/wdt.h>
    #include <util/delay.h>
    #include <ctype.h>
    
    #define up(bit) (_SFR_BYTE(PORTB) |= _BV(bit))
    #define down(bit) (_SFR_BYTE(PORTB) &= ~_BV(bit))
    #define upp(reg,bit) (_SFR_BYTE(reg) |= _BV(bit))
    #define downn(reg,bit) (_SFR_BYTE(reg) &= ~_BV(bit))
    
    
    static volatile uint8_t clock;
    static volatile uint8_t timer0ON;
    
    
    
    	//Fonction ON|OFF du timer0 et du comparateur//
    
    void Timer0_ON()
    {
    	TIMSK = _BV(OCIE0A) |_BV(TOIE0);
    	TCCR0A = _BV(WGM00);
    	TCCR0B = _BV(CS00);
    	OCR0A = 0xFF;
    }
    void Timer0_OFF()
    {
    	TIMSK = 0x00;
    	TCCR0A = 0x00;
    	TCCR0B = 0x00;
    	OCR0A = 0x00;
    }
    
    void InteruptComp_ON()
    {
    	ACSR = _BV(ACIE) |_BV(ACIS1) |_BV(ACIS0);
    }
    void InteruptComp_OFF()
    {
    	ACSR = ~_BV(ACIE);
    }
    
    
    	
    	//Interruptions//
    
    ISR(ANA_COMP_vect)
    {
    	timer0ON = 0xFF;
    	Timer0_ON();
    }
    
    ISR(TIMER0_OVF_vect)
    {
    	timer0ON = 0x00;
    	clock = 0xFF;
    }
    
    ISR(TIMER0_COMPA_vect)
    {
    	clock = 0x00;
    }
    
    
    
    	//Décodage Code Manchester//
    
    int ConvertModuleToData()
    {
    	int result;
    	uint8_t module;
    
    	if(bit_is_set(ACSR,ACO)) module=0xFF;
    	if(bit_is_clear(ACSR,ACO)) module=0x00;
    
    	/*fonction OU exclusif*/
    	if((module==0xFF && clock==0x00)||(module==0x00 && clock==0xFF)) result=1;
    	if(module==clock) result=0;
    
    	return result;
    }
    
    	//Fonction identification d'en tête//
    
    int Comp()
    {	
    	int i=0, j=0, result;
    	uint8_t data = 0x00;
    
    	do
    	{	
    		while(!clock);
    		result = ConvertModuleToData();
    		while(clock);
    
    		if(result==1)
    		{
    			data = data + (2^i)*(ConvertModuleToData());
    			i++; j--;
    		}
    		else {i=0; j++;}
    
    		if(j>64) return 0;
    	}
    	while(i<8);
    	return 1;
    }
    
    int main(void)
    {
    	/*initialisation timer 1*/
    	TCCR1 = _BV(CS11); //facteur de division de l'horloge
    	GTCCR = _BV(PWM1B) |_BV(COM1B0); //mise en marche du PWM et mode toggle
    	PLLCSR = _BV(PCKE)| _BV(PLLE) |_BV(PLOCK);	//choix de la féquence à diviser
    	OCR1B = 128;
    	OCR1C = 255;
    	
    	
    	/*initialisation comparateur*/
    	downn(ACSR,ACD); //comparator allumé
    	downn(ADCSRB,ACME); //AIN1 sélectionné
    	downn(ACSR,ACBG); //AIN0 sélectionné
    	DIDR0 = _BV(AIN1D) |_BV(AIN0D);//mise à 0 de la conversion AN
    	
    	sei();//interruption général autorisée
    
    	/*initialisation port*/
    	DDRB = _BV(PB4) |_BV(PB2);
    	
    	int s=-1;
    	timer0ON=0xFF;
    	
    
    
    	while(1)
    	{
    		InteruptComp_ON();
    		while(timer0ON);
    		InteruptComp_OFF();
    		s=Comp();
    		Timer0_OFF();
    
    		if(s==1)
    		{
    			up(PB2);
    			_delay_ms(2000);
    			down(PB2);
    		}
    		if(s==0)
    		{
    			for(int i=0;i<=2;i++)
    			{
    				up(PB2);
    				_delay_ms(500);
    				down(PB2);
    				_delay_ms(500);
    			}
    		}
    			
    	}
    }
    Juste un truc que je trouve bizarre, c'est que dans la simulation,
    le programme ne passe pas dans la fonction de décodage "ConvertModuleToData".
    Je ne vois pas pourquoi ?


    Exel

  14. #13
    Eric0269

    Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Salut,
    Pour passer dans ISR(TIMER0_COMPA_vect), il faudrait que ton timer soit configuré avec le mode CTC (WGM=1 du registre TCCR0A).
    Essaies ces modifs, je regarde si il n'y a pas autre chose.

  15. #14
    Exelandre

    Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Bonjour,

    C'est une très bonne idée surtout pour du décodage Manchester !

    A ce sujet, je connais le temps d'un bit, mais je me demande comment s'assurer que le signal est synchroniser correctement avec le timer ?


    Exel

  16. #15
    Eric0269

    Re : AVR ATTiny25 et fonction "attente" d'un cycle de Timer

    Salut,
    Regardes sur http://www.atmel.com/dyn/products/ap...?family_id=607 , tu y trouveras certainement des infos intéressantes.
    Des adaptations sont nécessaires, mais les idées sont là.

Discussions similaires

  1. fonction "recherche" disparue d'un vista
    Par Cornemuse dans le forum Logiciel - Software - Open Source
    Réponses: 3
    Dernier message: 19/03/2009, 10h00
  2. question de définition entre "fonction" et "application linéaire"
    Par bendesarts dans le forum Mathématiques du supérieur
    Réponses: 3
    Dernier message: 19/02/2009, 15h52
  3. Réponses: 9
    Dernier message: 30/10/2008, 08h19
  4. [Thermique] Clim Panasonic GK en défaut "Timer" : [ résolu ]
    Par guerinca dans le forum Dépannage
    Réponses: 7
    Dernier message: 22/05/2008, 13h20
Découvrez nos comparatifs produits sur l'informatique et les technologies.