Oups c'est une erreur, le registre T1CON doit bien être à 0x01 (en mode 2x8bits), et même en mode 16 bits ça ne fonctionne pas =(
Oups c'est une erreur, le registre T1CON doit bien être à 0x01 (en mode 2x8bits), et même en mode 16 bits ça ne fonctionne pas =(
Peux-tu vérifier la valeur de o->period avec ton debugger ?
Elle reste à zéro, mais je ne voit pas pourquoi =(
Par curiosité, peux-tu essayer ça :
o->period = 65535 - (unsigned int)reg;
Erreur de frappe ça ^^ Tjs le même problème =(
Le fait de mettre reg en double ne résoud rien, le calcul continue à être fait en entier et n'empêche pas le dépassement de capacité des int.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 double reg; .... reg = (_period * _freq) / 1000000;
Seul le résultat sera mis en double, ce qui dans ce cas ne sert à rien.
Si on veut faire le calcul en double, il faut caster en double au moins l'une des deux valeurs _period ou _freq
Je saisis la subtilité ^^
Mais j'en suis tjs au même point, je ne voit tjs pas pourquoi.. Le problème vient bien du calcul, car si je force period à 55535 tout fonctionne bien.
Tu apportes des modifications au code, ça ne marche pas mais tu ne donnes pas le nouveau code que tu utilises.
On n'est pas devin.
Oups pardon ^^
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 void o_clock_init(struct o_clock *o, unsigned int _freq, unsigned int _period) { o->ev = 0; double reg; reg = 0; IPEN = 0; GIE = 1; PEIE = 1; TMR1IE = 1; TMR1IP = 0; T1CON = 0x01; reg = ((double)_period *(double)_freq) / 1000000; o->period = 65535 - (unsigned int)reg; unsigned char lsb = (unsigned char) ((o->period) & 0x00FF); unsigned char msb = (unsigned char) (((o->period) >> 8) & 0x00FF); TMR1H = msb; TMR1L = lsb; TMR1IF = 0; }
Peut-on voir le bout de code qui fait appel à cette fonction ?
Voici le main
et le o_clock_run
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 void main(){ unsigned int count; count = 0; ADCON1 = 0x00000110; ecu_init(); o_clock_init(&clock,10000000,1000); TRISEbits.TRISE0 = 0; while(1){ o_clock_run(&clock); if(clock.ev == 1) { count++; if(count == 500) { if(LATEbits.LATE0 == 1) { PORTEbits.RE0 = 0; } else { PORTEbits.RE0 = 1; } count = 0; } } } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 void o_clock_run(struct o_clock *o) { if(o->ev == 1) { o->ev = 0; } if(TMR1IF==1) { o->ev = 1; unsigned char lsb = (unsigned char) ((o->period) & 0x00FF); unsigned char msb = (unsigned char) (((o->period) >> 8) & 0x00FF); TMR1H = msb; TMR1L = lsb; TMR1IF = 0; } }
Où est déclaré clock et comment ?
Le plus simple est de mettre l'intégralité de ton code s'il n'est pas très gros.
Est-ce que tu utilises le debugger sur la cible ou avec un simulateur ?
Quelle est la valeur lue sur reg ?
Voici l'intégralité du main
et le clock.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include <xc.h> #include "clock.h" #include "ecu.h" struct o_clock clock; void main(){ unsigned int count; count = 0; ADCON1 = 0x00000110; ecu_init(); o_clock_init(&clock,10000000,1000); TRISEbits.TRISE0 = 0; while(1){ o_clock_run(&clock); if(clock.ev == 1) { count++; if(count == 500) { if(LATEbits.LATE0 == 1) { PORTEbits.RE0 = 0; } else { PORTEbits.RE0 = 1; } count = 0; } } } }
Je débug avec l'ICD3 sur cible, mais je ne l'ai pas à coté de moi en ce moment, je teste ce soir, mais o->period ne veut pas décoller de 0, et je ne comprend pas pourquoi.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #ifndef CLOCK_H #define CLOCK_H #include <xc.h> struct o_clock { unsigned int period; // Periode de l'horloge temps reel en µs unsigned char ev; // }; void o_clock_init(struct o_clock *o, unsigned int _freq, unsigned int _period); void o_clock_run(struct o_clock *o); #endif /* CLOCK_H */
Si à la place du calcul je met:
et bien tout fonctionne, c'est vraiment au niveau du calcul que ça coince mais je ne comprend pas ou =(
Code : Sélectionner tout - Visualiser dans une fenêtre à part o->period = 55535;
Alors il y a vraiment un truc que je ne comprend plus ^^
Je met mon code suivant dans le main
Et il trouve que toto = 1410
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 unsigned long toto; toto = 0; toto = ((1000 * 10000000) / 1000000);
=/ Faut que je lui apprenne les maths je pense =)
Si un unsigned long fait 32 bits, alors c'est normal: 1,000 * 10,000,000 = 10,000,000,000 qui est supérieur à 4,294,967,295 (la plus grosse valeur non-signée qui tienne sur 32 bits).
10,000,000,000 modulo 4,294,967,296 donne 1,410,065,408 qui divisé par 1,000,000 donne 1,410.
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Je me suis aperçu de ça après avoir poster le message, je restait borné sur mon 10000.
J'ai fait la division en premier, et tout ce passe bien =)
Thank's
Et je pense que Médinoc a trouvé la solution à ton problème.
La valeur de _freq ne tient pas dans un "unsigned int" puisque celui-ci fait 16 bits sur ton implémentation.
Normalement, tu aurais dû t'en apercevoir puisque le compilateur doit te sortir un warning pour ce cas précis.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 void o_clock_init(struct o_clock *o, unsigned int _freq, unsigned int _period); o_clock_init(&clock,10000000,1000);
Partager