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 =(
Version imprimable
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:
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:
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_runCode:
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:
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.hCode:
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:
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: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 = 1410Code:
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.
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:
1
2
3 void o_clock_init(struct o_clock *o, unsigned int _freq, unsigned int _period); o_clock_init(&clock,10000000,1000);