Je souhaite mesurer la durée d'un état haut avec un PIC16f886 et son Timer. Je rencontre quelques soucis d'imprécision et je voulais donc avoir vos avis et expériences.
J'utilise un Quarz 20Mhz.
Tout simplement, ma boucle principale est composé de :
Code : Tout sélectionner
while (1)
{
ms = 0;
TMR1H = 0x00;
TMR1L = 0x00;
PORTAbits.RA1 = 1;
T1CON = 0x01; // Start timer
for (i=0 ; i<30000 ; i++)
{
for (j=0 ; j<60 ; j++)
{
if (TMR1IF)
{
TMR1IF = 0;
ms++;
}
}
}
PORTAbits.RA1 = 0;
T1CON = 0x00; // Stop timer
SYS_CalculRetard (ms);
}
Et pour calculer la durée :
Code : Tout sélectionner
void SYS_CalculRetard (unsigned int millisecond)
{
unsigned int timer = 0;
unsigned int us = 0;
unsigned int ms = 0;
us = millisecond * (535/5);
ms = (millisecond * (65/5)) + (us / 1000);
us = us % 1000;
timer = ((TMR1H << 8) + TMR1L);
timer /= 5;
us = us + (timer % 1000);
ms = ms + (timer / 1000) + (us / 1000);
us %= 1000;
millisecond = 0;
}
Pour des petits délais je n'ai pas de soucis, j'arrive à avoir une précision qui se rapproche de la microseconde mais dès que je passe au seconde... c'est pas la même.
Exemple pour ce code :
A l'aide d'un analyseur logique avec un taux d’échantillonnage de 4MHz : voir Mesure1.png
Le programme lui me retourne ms = 6252 et us = 478
Maintenant, j'augmente la durée de mon état haut avec
Code : Tout sélectionner
for (j=0 ; j<80 ; j++) A l'aide d'un analyseur logique avec un taux d’échantillonnage de 4MHz : voir Mesure2.png
Le programme lui me retourne ms = 8227 et us = 97
Plus le delai est grand et plus l’imprécision est grande mais trop grande je trouve (je m'attendais à quelques centaine de us voir une milliseconde).
Est ce que mon calcul est efficace ? Un soucis avec l'oscillateur ou normal ?



