Frequencemètre avec Timer X

Postby Guest » Wed May 30, 2007 12:00 am

Bonjour,
Je suis novice sur la programmation du R8C/13 et du C. J'essaie à titre personnel de concevoir un fréquencemetre avec l'utilisation du timer X. Seulement j'ai quelques soucis dans l'élaboration du programme. Je ne trouve pas de résultats concluants. Je rentre mon signal sur P1_7 (CNTRo) comme indiqué dans la doc. Si quelqu'un pouvait ainsi me guider sur l'utilisation du timer X en me proposant un programme simple réalisant un fréquencemètre sans l'utilisation des interruptions. J'ai de mon côté déjà lu les exemples sur l'utilisation des différents timers mais sans grand succès!!
Merci de votre aide!!
Bien cordialement!!
Tony
Guest
 

Postby grumly » Wed May 30, 2007 12:00 am

Salut Tony, je vois pas bien pourquoi tu ne veux pas utiliser les IT. Sauf exceptions cela n'a aucun interet, c'est bien l'avantage des timers qui bossent pdt que le Cpu fait autre chose.

enfin bon deja :

Si tu utiliser le debugger via uart, c'est normal que les resultats sont foireux, car le debugger casse le temps reel. Qd le µc est en pause, les timers continuent de tourner.

voici un extrait de mon code qui utilise les IT, pour mesurre des frequence de qq hz a 200 hz :

typedef signed char tS8;

typedef unsigned int tU16;
typedef signed int tS16;

typedef unsigned long int tU32;
typedef signed long int tS32;


typedef unsigned char Bool;
#define TRUE 1
#define FALSE 0

#define SYSCLK 20000000 /* Vitesste du CPU */

static tU16 Regime_T= ~0; // static tU16 Regime_Ucnt = 0; // Compteur d'underflow

/////////////////// PULSE PERIOD COUNTER /////////////////////
//*******************************************************************************
// FUNCTION : timerX_startPulseMes10us
// DESCRIPTION : This function start the timer X in Pulse period mode, with a step of 10µS
// PARAMETERS :
// : edge, TRUE is rising.
// RETURN : Void
// ALGORYTHM : configure pin direction and default value
// TimerX_INT will occur a each underflow or Edg detect
//*******************************************************************************
void timerX_startPulseMes10us( Bool edge)
{
/*-------------------------------------------------
- Setting main cycle timer -
- 20 MHz * 1/1 * 1/200 => 10 µs -
-------------------------------------------------*/
#if (SYSCLK != 20000000)
#error "Ce code est fait pour tourner a 20 Mhz"
#endif
txmr = 0x00; /* Timer or Pulse Perido mode for Timer X */
r0edg = (edge == TRUE ? 0 : 1); /* Rising Edge if true*/
txmod2 = 1; /* Pulse peeriod mode */

#if (SYSCLK != 20000000)
#error "Ce code est fait pour tourner a 20 Mhz"
#else
prex = 200-1; /* Set Prescaler X register */
#endif
tx = 0xFF; /* Set Timer X register to MAX */
txck0 = 0; /* Timer Count source = f1 */
txck1 = 0;
txic = 0x07; /* Timer interrupt priority level = 7 */
txs = 1; /* Timer X count start flag -> start */

return;
}


/////////////////// ALL MODE /////////////////////

//*******************************************************************************
// FUNCTION : timerX_getCount
// DESCRIPTION : This function get the Number of count event or measurement.
// MODE : All
// PARAMETERS : void
// RETURN : Void
//*******************************************************************************
tU8 timerX_getCount(void)
{
return (0xFF-tx);
}

//*******************************************************************************
// DON'T FORGET these lines into sec30.inc file
//*******************************************************************************

// .glb _Timer_X_int
// .lword _Timer_X_int ; vector 22

#pragma interrupt Timer_X_int;
/*-------------------------------------------------
- Timer X interrupt routine -
-------------------------------------------------*/

//*******************************************************************************
// FUNCTION : Timer_X_int
// DESCRIPTION : Routine d'IT appele lorsque le compteur fait un underflow ou un edg
// RETURN : Void
// ALGORYTHM : On incrmeent le compteur d'overflow, si on atteineds la max
// on leve le flag mloteur arrete
//*******************************************************************************

void Timer_X_int(void)
{
// Is called every TimerX overflow, or Edg detect

if(txund == 1)
{ // Underflow is detected
txund = 0; // clear the flag

Regime_Ucnt ++;

}

if(txedg == 1)
{ // Edg is detected
txedg = 0;


tU8 tmp;

tmp = timerX_getCount();

Regime_T = tmp + Regime_Ucnt * 256; // On calcule la period mesure

}


grumly
 
Posts: 11
Joined: Fri Jan 17, 2014 4:37 pm

Postby grumly » Wed May 30, 2007 12:00 am

Explications :

ca a l'air volumineux, mais c'est tout simple :

la fontion start, demarre le Timer en X ds le bon mode, avec la Frequence de 20 Mhz (que tu aura configuré)

le prescaler est de de 200 et donc, Tx est donc decrementé a la frequence de 100 KHz, soit 10µs par unité.
tu peux evidemment changer ca en fct de ta plage de mesure.

getcount, permet juste de lire le TimerX


Ensuite, quand la mesure est faire l'IT pete, et tu a juste a lire Tx. Sauf, que je gere aussi les underflow qui sont comptés, ce qui te permet de compter des peridoe > 2560 µs


Voila, enfin tu peux rajouter a la fin de l'it du code pour mettre a jour ton affichage, ou mieux lever un flag qui permettra a la routine principale de le faire hors IT.
grumly
 
Posts: 11
Joined: Fri Jan 17, 2014 4:37 pm

Postby Guest » Wed May 30, 2007 12:00 am

Salut Grumly,
je te remercie d'avance pour tes explications. Je vais essayer de mettre ca en application et je te tiendrais au courant. En tout cas, merci beaucoup pour ton aide!!! C'est deja plus clair avec ton prog!!
@++
Guest
 

Postby Guest » Wed May 30, 2007 12:00 am

Salut,
voila mon programme pour le frequencemetre! Dans ce prog, j'ai réalisé plusieurs tests pour une frequence donnée et suivant les calculs théoriques, la valeur du tx est bonne mais il me reste un prob quand il y a un underflow!!! La valeur incrémenté "i" pour un underflow ne s'arrete jamais!! As tu deja eu ce genre de probleme et si oui as tu une idée pour y remedier?

Merci!!

////////////////////////////////////////////////////////
#include "sfr_r813.h";

void sfr_init(void); //fonction pour utilisation des registres
void Timer_X_int(void); //fonction pour lire le TimerX
typedef unsigned int tU16;
static tU16 periode=~0;
static tU16 i = 0; // Compteur d'underflow
unsigned char temps=0;
static tU16 t = 0;

main(){

asm("FCLR I"); /* Interrupt disable*/
/*-------------------------------------------------
- Change on-chip oscillator clock to Main clock -
-------------------------------------------------*/

prc0 = 1; /* Protect off */
cm13 = 1; /* Xin Xout */
cm15 = 1;
cm05 = 0; /* Xin on */
cm16 = 0;
cm17 = 0;
cm06 = 0; /* CM16 and CM17 enable */
asm("nop");
asm("nop");
asm("nop");
asm("nop");
ocd2 = 0; /* Main clock change */
prc0 = 0; /* Protect on */
prc2 = 1; /* Protection off pour ecrire sur p0 */

asm("FSET I");

while(t==0){
sfr_init();
t=1;
}

}

void sfr_init(void){

pd0 = 0xFF;
pd1= 0x7F;

txck0 = 0;
txck1 = 0;
prex = 50-1; /* Setting Prescaler X register */
tx = 255; /* Setting timer X register */

txmr = 0x00; /* Timer X : Pulse width measurement mode */
r0edg=0;
txmod2=1;
txic = 0x07; /* Interrupt priority level = 7 */
txs = 1; /* début du comptage */

}

#pragma interrupt Timer_X_int;
void Timer_X_int(void){


if(txund==1)
{ txund=0;
i++;
p1_3=1;
}

if(txedg==1)
{ temps=255-tx;
txedg=0;
p1_0=1;
if(i==180)
{p1_2=1;
}
if((temps>150)&(temps<160))
{ p1_1=1;
}
}

}

Guest
 

Postby Guest » Wed May 30, 2007 12:00 am

Salut,

Voilà mon prog !! J’ai réalisé plusieurs tests pour une frequence donnée, j’obtiens bien la bonne valeur en tx (cette valeur verifie la valeur theorique). Le probleme c’est au moment ou j’ai un underflow, la valeur incrementée « i » ne s’arrete jamais !! As tu deja eu ce prob et as tu une idée pour y remedier ?

#include "sfr_r813.h";

void sfr_init(void); //fonction pour utilisation des registres
void Timer_X_int(void); //fonction pour lire le TimerX
typedef unsigned int tU16;
static tU16 periode=~0;
static tU16 i = 0; // Compteur d'underflow
unsigned char temps=0;
static tU16 t = 0;

main(){

asm("FCLR I"); /* Interrupt disable*/
/*-------------------------------------------------
- Change on-chip oscillator clock to Main clock -
-------------------------------------------------*/

prc0 = 1; /* Protect off */
cm13 = 1; /* Xin Xout */
cm15 = 1; /* XCIN-XCOUT drive capacity select bit : HIGH */
cm05 = 0; /* Xin on */
cm16 = 0; /* Main clock = No division mode */
cm17 = 0;
cm06 = 0; /* CM16 and CM17 enable */
asm("nop"); /* Waiting for stable of oscillation */
asm("nop");
asm("nop");
asm("nop");
ocd2 = 0; /* Main clock change */
prc0 = 0; /* Protect on */
prc2 = 1; /* Protection off pour ecrire sur p0 */

asm("FSET I");

while(t==0){
sfr_init();
t=1;

}

}

void sfr_init(void){

pd0 = 0xFF; /* Set Port 0 be used for output
pd1= 0x7F; // port 1 bit 7 en entrée

txck0 = 0; /* Timer X count source = f1 */
txck1 = 0 ; /* selection de la fréquence f1 */

prex = 50-1; /* Setting Prescaler X register */
tx = 255; /* Setting timer X register */

txmr = 0x00; /* Timer X : Pulse width measurement mode */
r0edg=0;
txmod2=1;
txic = 0x07; /* Interrupt priority level = 7 */
txs = 1;

}

#pragma interrupt Timer_X_int;
void Timer_X_int(void){


if(txund==1)
{ txund=0;
i++;
p1_3=1;
}

if(txedg==1)
{ temps=255-tx;
txedg=0;
p1_0=1;
if(i==180)
{p1_2=1;
}
if((temps>150)&(temps<160))
{ p1_1=1;
}
}

}
Guest
 

Postby grumly » Wed May 30, 2007 12:00 am

Content que tu progresses.


Et ton probleme est tout a fait normal car tu ne remet jamais ton compteur i a zero. Si je m'etait pas gourré dans mon copier collé, tu aurias vu que dans le if(txedg == 1) je remet mon compteur d'overflow a zero apres l'avoir utilisé..... Donc rajout i = 0;

Ps:

une rmearque sur ton main() qui me parait etrange :

Generalement le main ressemble a ca :


main()
{

/// Phase d'initialization en tout genre
// init de la clock cpu
// init des sfr
// lancement de timer etc....

// Boucle de fond qui tourne sans fin

while(1)
{
// ici on fait les trucs hors it en fond de tache
// sinon rien


}
}

si t'as des questions...
grumly
 
Posts: 11
Joined: Fri Jan 17, 2014 4:37 pm

Postby Guest » Wed May 30, 2007 12:00 am

Salut,

enfin, ca tourne!! Merci beaucoup pour ton aide!!!
Merci aussi pour tes commentaires à propos du main().
Je vais continuer mon application!!
si j'ai des questions, je penserai à toi!!!
@++
Guest
 


Return to R8C/13 (01-2006)

Who is online

Users browsing this forum: No registered users and 1 guest