Forums

Problem with timer overflow

Started by nona...@yahoo.com November 23, 2010
Hi all,

I am trying to measure pulse width of a signal that is larger than the TCNT overflow value but without interrupts.. only by checking the TFLG2 and keep record of the number TCNT rollovers but it doesn't work. Here is what i am doing:

____________________________________________________________________
void init_timers()
{
TSCR1 = 0x90;
TIOS &= 0xFE; //enable input-capture0
TSCR2 = 0x07; //disable TCNT overflow interrupt,set prescaler to 128
TCTL4 = 0x03; //capture rising and falling egde of PT0
TFLG1 = 0x01; // clear the C0F flag by writing 1
}

void main (void) {

float Time_Contact,diff1,overflow=0;
int edge1,edge2,i;
char* no;
int *status;

init_lcd(); /*initialize LCD*/
init_timers(); /*initialize timers*/

clr_disp();

while(!(TFLG1 & C0F));//wait for the first rising edge
edge1 = TC0; //save the first captured edge and clear C0F flag

while(!(TFLG1 & C0F))//wait for the first falling edge {
if(TFLG2&TOF) //rollover occured
overflow++ ;
TFLG2= 0x80; //clear TFLG2
}

edge2 = TC0; /*save the edge and clear C0F flag*/

PORTB=0x00; //falling edge on Ch0

diff1 = edge2 - edge1;

if (edge2< edge1)
overflow -= 1;
Time_Contact = overflow * 65536u + diff1;
no=ftoa(Time_Contact, status);
lcd_print_txt(no, LINE1);

}
_________________________________________________________________________

Will really appreciate any kind of help

Thanks

What is the output you receive? Also, are you looping infinitely in your main? If the chip finished the main routine, it will just stop until it is reset.

Drew Heinrich
On Nov 23, 2010, at 11:59 AM, n...@yahoo.com wrote:

> Hi all,
>
> I am trying to measure pulse width of a signal that is larger than the TCNT overflow value but without interrupts.. only by checking the TFLG2 and keep record of the number TCNT rollovers but it doesn't work. Here is what i am doing:
>
> __________________________________________________________
> void init_timers()
> {
> TSCR1 = 0x90;
> TIOS &= 0xFE; //enable input-capture0
> TSCR2 = 0x07; //disable TCNT overflow interrupt,set prescaler to 128
> TCTL4 = 0x03; //capture rising and falling egde of PT0
> TFLG1 = 0x01; // clear the C0F flag by writing 1
> }
>
> void main (void) {
>
> float Time_Contact,diff1,overflow=0;
> int edge1,edge2,i;
> char* no;
> int *status;
>
> init_lcd(); /*initialize LCD*/
> init_timers(); /*initialize timers*/
>
> clr_disp();
> while(!(TFLG1 & C0F));//wait for the first rising edge
> edge1 = TC0; //save the first captured edge and clear C0F flag
> while(!(TFLG1 & C0F))//wait for the first falling edge {
> if(TFLG2&TOF) //rollover occured
> overflow++ ;
> TFLG2= 0x80; //clear TFLG2
> }
> edge2 = TC0; /*save the edge and clear C0F flag*/
>
> PORTB=0x00; //falling edge on Ch0
>
> diff1 = edge2 - edge1;
> if (edge2< edge1)
> overflow -= 1;
> Time_Contact = overflow * 65536u + diff1;
>
> no=ftoa(Time_Contact, status);
> lcd_print_txt(no, LINE1);
>
> }
> __________________________________________________________
>
> Will really appreciate any kind of help
>
> Thanks


i am getting no output
and no am not looping infinitely so that registers' values don't get overwritten..  

--- On Tue, 11/23/10, Drew Heinrich wrote:
From: Drew Heinrich
Subject: Re: [68HC12] Problem with timer overflow
To: "6..." <6...>
Date: Tuesday, November 23, 2010, 9:44 PM
 

What is the output you receive? Also, are you looping infinitely in your main? If the chip finished the main routine, it will just stop until it is reset.

Drew Heinrich

On Nov 23, 2010, at 11:59 AM, n...@yahoo.com wrote:

> Hi all,
>
> I am trying to measure pulse width of a signal that is larger than the TCNT overflow value but without interrupts.. only by checking the TFLG2 and keep record of the number TCNT rollovers but it doesn't work. Here is what i am doing:
>
> __________________________________________________________
> void init_timers()
> {
> TSCR1 = 0x90;
> TIOS &= 0xFE; //enable input-capture0
> TSCR2 = 0x07; //disable TCNT overflow interrupt,set prescaler to 128
> TCTL4 = 0x03; //capture rising and falling egde of PT0
> TFLG1 = 0x01; // clear the C0F flag by writing 1
> }
>
> void main (void) {
>
> float Time_Contact,diff1,overflow=0;
> int edge1,edge2,i;
> char* no;
> int *status;
>
> init_lcd(); /*initialize LCD*/
> init_timers(); /*initialize timers*/
>
> clr_disp();
>
>
> while(!(TFLG1 & C0F));//wait for the first rising edge
> edge1 = TC0; //save the first captured edge and clear C0F flag
>
>
> while(!(TFLG1 & C0F))//wait for the first falling edge {
> if(TFLG2&TOF) //rollover occured
> overflow++ ;
> TFLG2= 0x80; //clear TFLG2
> }
>
>
> edge2 = TC0; /*save the edge and clear C0F flag*/
>
> PORTB=0x00; //falling edge on Ch0
>
> diff1 = edge2 - edge1;
>
>
> if (edge2< edge1)
> overflow -= 1;
> Time_Contact = overflow * 65536u + diff1;
>
> no=ftoa(Time_Contact, status);
> lcd_print_txt(no, LINE1);
>
> }
> __________________________________________________________
>
> Will really appreciate any kind of help
>
> Thanks
>
>







See below.

wrote:

> Hi all,
>
> I am trying to measure pulse width of a signal that is larger than the
> TCNT overflow value but without interrupts.. only by checking the TFLG2
> and keep record of the number TCNT rollovers but it doesn't work. Here is
> what i am doing:
>
> ____________________________________________________________________
> void init_timers()
> {
> TSCR1 = 0x90;
> TIOS &= 0xFE; //enable input-capture0
> TSCR2 = 0x07; //disable TCNT overflow interrupt,set prescaler to 128
> TCTL4 = 0x03; //capture rising and falling egde of PT0
> TFLG1 = 0x01; // clear the C0F flag by writing 1
> }
Arghhh. Please decifier these magic figures! Do you think everyone remembers
what bits are set to one here TSCR1 = 0x90; ?

>
> void main (void) {
> float Time_Contact,diff1,overflow=0;
> int edge1,edge2,i;
> char* no;
> int *status;
>
> init_lcd(); /*initialize LCD*/
> init_timers(); /*initialize timers*/
>
> clr_disp();
>
> while(!(TFLG1 & C0F));//wait for the first rising edge
> edge1 = TC0; //save the first captured edge and clear C0F flag
> while(!(TFLG1 & C0F))//wait for the first falling edge {
> if(TFLG2&TOF) //rollover occured
> overflow++ ;

^^ floating point operation is time consuming. You may be late servicing
flags on time.

> TFLG2= 0x80; //clear TFLG2

^^ this won't work in TFFCA=1 mode. You have to read TCNT to clear TOF
flag.

> }
> edge2 = TC0; /*save the edge and clear C0F flag*/
>
> PORTB=0x00; //falling edge on Ch0
>
> diff1 = edge2 - edge1;

I think you should take unsigned difference of capture register values. Even
if edge2 is <0x8000 and edge1 is >0x8000, unsigned difference will be always
>=0 . Will it make sense to receive negative time difference?

diff1 = (unsigned short)(edge2 - edge1);

> if (edge2< edge1)
> overflow -= 1;

Are you sure about this ^^ code?

what if time difference =0xE000 in all cases, but
a) edge2 = 0x1000(+); edge1 = 0x3000(+) - condition is true
b) edge2 = 0x7000(+); edge1 = 0x9000(-) - condition is false.
c) edge2 = 0x8000(-); edge1 = 0xA000(-) - condition is true
See 10.5.5 Measuring Long Time Periods with Input Capture and Overflow:
http://cache.freescale.com/files/microcontrollers/doc/ref_manual/M68HC11RM.pdf

Edward
> Time_Contact = overflow * 65536u + diff1;
> no=ftoa(Time_Contact, status);
> lcd_print_txt(no, LINE1);
>
> }
> _________________________________________________________________________
>
> Will really appreciate any kind of help
>
> Thanks
There are lots of problems with what you are doing. First, what happens if overflow occurs after the loop but before you read TC0? You will know you have one if TOF is set and edge2 is a small value at the time you do the diff1 calculation.

I'm also not sure about your math, particularly in using signed integers and floating point. As a general rule you want to avoid floating point in these microcontrollers. You should be able to do all the calculations declaring the variables as unsigned int or unsigned long as appropriate to the values the contain. In fact the diff1 calculation can be done as a simple assignment involving an addition, a subtraction, and a shift that the compiler will optimize out.

Tom Almy
Tualatin, Oregon USA
Internet: t...@almy.us
Website: almy.us

On Nov 23, 2010, at 8:59 AM, n...@yahoo.com wrote:

> Hi all,
>
> I am trying to measure pulse width of a signal that is larger than the TCNT overflow value but without interrupts.. only by checking the TFLG2 and keep record of the number TCNT rollovers but it doesn't work. Here is what i am doing:
>
> ____________________________________________________________________
> void init_timers()
> {
> TSCR1 = 0x90;
> TIOS &= 0xFE; //enable input-capture0
> TSCR2 = 0x07; //disable TCNT overflow interrupt,set prescaler to 128
> TCTL4 = 0x03; //capture rising and falling egde of PT0
> TFLG1 = 0x01; // clear the C0F flag by writing 1
> }
>
> void main (void) {
> float Time_Contact,diff1,overflow=0;
> int edge1,edge2,i;
> char* no;
> int *status;
>
> init_lcd(); /*initialize LCD*/
> init_timers(); /*initialize timers*/
>
> clr_disp();
>
> while(!(TFLG1 & C0F));//wait for the first rising edge
> edge1 = TC0; //save the first captured edge and clear C0F flag
>
>
> while(!(TFLG1 & C0F))//wait for the first falling edge {
> if(TFLG2&TOF) //rollover occured
> overflow++ ;
> TFLG2= 0x80; //clear TFLG2
> }
>
>
> edge2 = TC0; /*save the edge and clear C0F flag*/
>
> PORTB=0x00; //falling edge on Ch0
>
> diff1 = edge2 - edge1;
>
>
> if (edge2< edge1)
> overflow -= 1;
> Time_Contact = overflow * 65536u + diff1;
> no=ftoa(Time_Contact, status);
> lcd_print_txt(no, LINE1);
>
> }
> _________________________________________________________________________
>
> Will really appreciate any kind of help
>
> Thanks
>