Help: Input Capture to measure frequency

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Help: Input Capture to measure frequency

2,718 次查看
gda02
Contributor I
I started a project using a MiniDragon+ (MC9S12DP256) to measure the frequency off a Siemens Flex Fuel sensor found in current GM model vehicles.  The sensor outputs a linear frequency from 50Hz-150Hz, where 50Hz is 0%ethanol and 150Hz is 100%ethanol.  In lab, we are using a function generator with a frequency any where from 50-150Hz to simulate the sensors output. We are getting the same values in TC1 and TC2 in the terminal. What are the units of TCx stored as? Does that mean IOC1 and IOC2 are capturing the same edges of the squrewave? I am not really clear on initializing the edges in TCTL4 register. Also here is a picture of the scope measuring California 91octane (10%).Code:
#include "hcs12.h"#include "DBug12.h"#include "vectors12.h"#include "delay.c"main( ){      unsigned int time, first, second, frequency, total;            TSCR1 = 0x80;                    //Bit 7 = 1 ;  turns on timer sub system      TSCR2 = 0x03;                       //Overflow time      //Sets up IOC1      TIOS =0x00;                 //Enables IOC1      TCTL4 = 0x14;                       //Selects edge to capture      TFLG1 = 0x02;      //Sets up IOC2      TIOS = 0x00;   //Enables IOC2      TCTL4 = 0x14;                       //Selects edge to capture      TFLG1 = 0x04;               while(( TFLG1 & 0x02) == 0);        //waits for 1st rising edge      first = TC1;                        //Reads time of 1st edge      while(( TFLG1 & 0x04) == 0);        //waits for second rising edge      second = TC2;                       //Reads time of 2nd edge.      total = second - first;      frequency = 1/total;      DB12FNP->printf("TC1 = %d \n \n",first);      DB12FNP->printf("TC2 = %d \n \n",second);      DB12FNP->printf("total = %d \n \n",total);      DB12FNP->printf("frequency = %d \n", frequency);                  return 0;      }
 
We are using Embedded GNU and Introduction to HCS12 by Hwang.

Message Edited by gda02 on 2007-05-0207:20 AM

标签 (1)
0 项奖励
回复
2 回复数

1,042 次查看
bigmac
Specialist III
Hello,
 
The input capture values represent the timer count for each edge.  You will need to ascertain how many microseconds each timer increment represents.  Additionally, the prescale value should be such that the timer overflow period is greater than the period of the minimum frequency (20 ms).
 
There is a problem with the code -
total = second - first;
frequency = 1/total;
Since all variables are unsigned integer, all calculations will be of integer type.  The value of frequency will always be zero because the numerator has not been appropriately scaled.
 
For example, if the timer increment period was 1.0 microseconds, the value of total would lie between 6666 and 20000.  To get an integer frequency value in say, multiples of 0.1Hz, something like the following code would be required -
 
frequency = 10000000L / total;
 
This should give a result between 500 and 1500.
 
An additional point - if the output waveform from the sensor is as shown, I think this should be buffered and "squared up" before being applied to the capture input of the MCU.  Presumably you also need robust external protection against transient voltages.
 
Regards,
Mac
 
0 项奖励
回复

1,042 次查看
kef
Specialist I
     while(( TFLG1 & 0x02) == 0);        //waits for 1st rising edge
     first = TC1;                        //Reads time of 1st edge
TFLG1 = 4; // ADD this line here. Both captures are configured to capture the same egde, => both capture flags are set, you need to clea TC2 flag here

     while(( TFLG1 & 0x04) == 0);        //waits for second rising edge
     second = TC2;                       //Reads time of 2nd edge.

 
 
0 项奖励
回复