|
|
View previous topic :: View next topic |
Author |
Message |
deepakomanna
Joined: 06 Mar 2007 Posts: 92 Location: Pune,India
|
problem while reading timer1 value ... |
Posted: Thu Sep 06, 2007 7:25 am |
|
|
Dear Sir,
here i am using 12f629, MPLAB 7.5 Ver. & CCS PCM C Compiler, Version 3.249, 34534.
Here i have some problem with the following code.
here i am sensing two pulses at pin no.7 & 6.
Code: | void main()
{
while(TRUE)
{
while(pin7 == 1); //wait till pin7 becomes goes low
var1 = get_timer1(); //read timer1 value;
making timer1 = 0;
again start timer1;
while(wait >= get_timer1());
making pin5 high;
while(pin6 == 1); //wait till pin6 becomes goes low
making pin5 low;
var2 = read timer1 value // again reading timer1 value
calculation(); //calling function
}
}
void calculation()
{
if(var2 < 10msec) //compare time between two pulses
{
// consider var1 = 5000;
ON_TIME = var1 - 10msec + var2;
while(ON_TIME > get_timer1());
//this is giving unexpected result,but if i add following statement
var2 = (var1/360)*45;
//insted of (in main)
// var2 = = read timer1 value // again reading timer1 value
//it works fine
}
else
{
///// other statements ////////
}
} |
could u help me to solve this difficulty. _________________ Thank You,
With Best Regards,
Deepak. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Sep 06, 2007 8:15 am |
|
|
Your pseudo code is diffcult to follow and full of inconsistencies, like Code: | while(wait >= get_timer1());
making pin5 high; <-- why is this line indented? | The indentation of the second line suggests you want it to be in the loop but the ';' at the end of the previous line is the end of the loop.
Please post real code. A small, complete and compilable program that we can copy paste in our compiler (including #fuse statements, etc.).
Saying you are getting an 'unexpected result' is not very helpful. Tell us:
- what your program is supposed to do
- the behaviour you expect to see
- what you do see now. |
|
|
Ttelmah Guest
|
|
Posted: Thu Sep 06, 2007 8:23 am |
|
|
The obvious 'problem', is wrapping. Since he is not 'making timer1 = 0', though he says this, there is a good chance it will have wrapped when it is next read, givinga faulty result, unless this is allowed for.
Best Wishes |
|
|
deepakomanna
Joined: 06 Mar 2007 Posts: 92 Location: Pune,India
|
problem while reading timer1 value ... |
Posted: Thu Sep 06, 2007 10:06 pm |
|
|
Dear sir,
depending upon RPM i have to make pin high & low.
So for this i have to wait till while (INPUT(PIN_A0) == 1);
& while(INPUT(PIN_A1)); becomes 0
& have calculate time between these to pulses,
if it is greater than 5ms there is no problem, but if becomes less than 5 ms i have to do some calculation & here is problem occuring.
Quote: | if(flag1 == 0)
{
OUTPUT_LOW(PIN_A2);
// TRANSISTOR_ON_TIME = GET_TIMER1();
TRANSISTOR_ON_TIME = (RPMC/360)*45 - 5;
}
|
in this routine i am rading timer1 value in TRANSISTOR_ON_TIME variable and used this value in called function. so if did this, making of PIN_A2 high & low are not contineous as i did this,it becomes at randomly
here is my part of code
Code: |
#if defined(__PCM__)
#include<12F629.h>
#fuses INTRC_IO,NOWDT,PUT,NOMCLR,PROTECT,NOCPD,BROWNOUT
//Internal RC Osc, no CLKOUT,No Watch Dog Timer,Power Up Time ON,Internal MCLR,Code Protect ON,No EE protection,Brownout detect ON,
#use delay(clock = 4000000) // INTERNAL 4 MHz FREQ.
#define FIVE_MS 625 // TIMER1 HAS 8 usec = 1 COUNT , so for 5 msec = 625 counts
void init_CPU(); // FUNCTION TO INITIALISE THE CPU SETTINGS
void CALCULATION_FUNCTION(unsigned int16); // to make calculations
const unsigned int16 RPM[16] ={4167,3750,3125,2500,2027,1829,1667,1500,1364,1071,1000,882,750,682,652,625};
int16 TRANSISTOR_ON_TIME;
int1 flag1 = 1;
void main()
{
unsigned int16 RPMC;
RPMC = 0;
init_CPU();
while(TRUE)
{
while(INPUT(PIN_A0)); //wait for 1st PULSE
SETUP_TIMER_1(T1_DISABLED); // TIMER_1 count OFF
RPMC = GET_TIMER1(); // get timer1 count in RPMCount
SET_TIMER1(0); // set timer1 = 0;
SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_8); //TIMER 1 ON.
if(flag1 == 1)
{
OUTPUT_HIGH(PIN_A2);
flag1 = 0;
}
while(INPUT(PIN_A1)); // wait for 2nd PULSE
if(flag1 == 0)
{
OUTPUT_LOW(PIN_A2);
// TRANSISTOR_ON_TIME = GET_TIMER1();
TRANSISTOR_ON_TIME = (RPMC/360)*45 - 5;
}
CALCULATION_FUNCTION(RPMC);
}
}
void CALCULATION_FUNCTION(unsigned int16 TIMER_COUNT)
{
if((TIMER_COUNT > 4167) ||(TIMER_COUNT== 0))
{
flag1 = 1;
if(TRANSISTOR_ON_TIME < FIVE_MS)
{
TRANSISTOR_ON_TIME = TIMER_COUNT - FIVE_MS + TRANSISTOR_ON_TIME ;
while(TRANSISTOR_ON_TIME >= GET_TIMER1()); // wait till TIMER1 reaches to TRANSISTOR_ON_TIME
OUTPUT_HIGH(PIN_A2);
flag1 = 0;
}
}
else
{
// making some operations using RPM array
}
}
void init_CPU()
{
/**************** PORT SETTINGS ***********************/
PORT_A_PULLUPS(0X03);
SET_TRIS_A(0X03); // I/P = RA0,RA1. O/P = RA2,RA3,RA4,RA5.
/**************** COMPARATOR SETTINGS ***************/
SETUP_COMPARATOR(NC_NC_NC_NC);
/**************** INTERRUPT SETTINGS *****************/
ENABLE_INTERRUPTS(GLOBAL);
ENABLE_INTERRUPTS(INT_TIMER1); //enable timer1 interrupt
/*************** END OF CPU INIT ******************/
}
#INT_TIMER1
void TIMER1_isr()
{
flag1 = 1; // zero dgree fire
}
|
if any queries let me know _________________ Thank You,
With Best Regards,
Deepak. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Sep 07, 2007 3:58 am |
|
|
On program startup you do not reset timer1 to 0, so the first time you go through the loop the results will be unpredicatable.
Don't use 'magic' numbers, they make the code hard to read. Code: | if((TIMER_COUNT > 4167) ||(TIMER_COUNT== 0))
| 4167 == 33.33ms Use a nice define like you did for the 5ms constant.
Can you give more details about your input signal? What is connected to A0 and A1? And what timing do you expect?
Can you explain the used formula? Code: | TRANSISTOR_ON_TIME = (RPMC/360)*45 - 5; |
My guess is that the timing for PIN_A1 is different from what you are expecting. |
|
|
deepakomanna
Joined: 06 Mar 2007 Posts: 92 Location: Pune,India
|
problem while reading timer1 value ... |
Posted: Fri Sep 07, 2007 4:31 am |
|
|
In my setup i am using motor to measure RPM & On the rotor there is a disc having
1 slot of 45mm.On this slot there are two sensors which sense start & end of slot.
so whenever start of slot pulse comes low signal to Pin A0.Therefore making pin A2 = HIGH.
when end of slot pulse comes it gives low signal to pin A1.Therefore making pin A2 = LOW.
And i have to measure time between these two.
so if this time greater than 5msec no problem but if it is less than 5mec i have
make pin A2= HIGH before start of slot pulse.so that i am using this formula.
Quote: | TRANSISTOR_ON_TIME = (RPMC/360)*45 - 5;
RPMC = which gives total time for 360 degree.
45 = here the slot is 45mm.i.e. 45 degree.
| So, RPMC gives total time for 360 degree and i have calculate time for 1 degree.
there fore 1degree time * 45 = 45 degree time
by using this formula it works but not getting accurate result so i want avoid this.
thats why i want to timer1 value after end of slot pulse comes. _________________ Thank You,
With Best Regards,
Deepak. |
|
|
Ttelmah Guest
|
|
Posted: Fri Sep 07, 2007 5:26 am |
|
|
First comment. Don't fiddle around disabling and enabling the timer.
Simply set it up once, before the loop, and reset it to zero on the first pulse.
Then, read it's value at the second pulse, and this is the number of counts between the pulses.
Perform your maths the other way round. A present, you perform RPMC/360, which is done in int16 arithmetic, and you immediately have lost all the fractional parts. So, use:
TRANSISTOR_ON_TIME = ((int32)RPMC*45)/360 - 5;
Here, you generate RPMC*45, stored and calculated in an int32. Then divide this by 45.
Even better (since 45/360 = 1/8), just use:
TRANSISTOR_ON_TIME = (RPMC/8) - 5;
Which will be calculated about 50*faster...
There is a problem in all cases, if RPMC is below 40, since the arithmetic will then wrap, and give silly numbers.
The solution to this, is:
TRANSISTOR_ON_TIME = (RPMC>40)?(RPMC/8)-5:0;
Which will substitute '0' for the silly values.
Best Wishes |
|
|
deepakomanna
Joined: 06 Mar 2007 Posts: 92 Location: Pune,India
|
problem while reading timer1 value ... |
Posted: Fri Sep 07, 2007 6:18 am |
|
|
Dear sir,
But i have to read timer1 two times.
1st will give RPM &
2nd will give time between two pulses. Thats why have to read timer1 two times.
Many Thanks for give some hints to me _________________ Thank You,
With Best Regards,
Deepak. |
|
|
Ttelmah Guest
|
|
Posted: Fri Sep 07, 2007 6:52 am |
|
|
Ok, then just read it, and reset it to zero.
The count read, will be the period between the last 'initial' pulse, and the current one, while the time read at the seocnd point, will be the gap between the first and second pulses.
The problem is that reprogramming the timer, can lead to unexpected counts, and adds extra delays after sensing your edges, which won't help the accuracy.
Yor big problem though is the maths. As written, it'll destroy the accuracy.
Best Wishes |
|
|
deepakomanna
Joined: 06 Mar 2007 Posts: 92 Location: Pune,India
|
problem while reading timer1 value ... |
Posted: Wed Sep 12, 2007 12:32 am |
|
|
I removed the two statements,
Quote: | SETUP_TIMER_1(T1_DISABLED); // TIMER_1 count OFF
TRANSISTOR_ON_TIME = (RPMCount/360)*45 ;
|
from my programe and used only,
Quote: | TRANSISTOR_ON_TIME = GET_TIMER1(); |
Also i was started timer1 before the pulse comes i.e. in the init_CPU()
function.
But still it has problem _________________ Thank You,
With Best Regards,
Deepak. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|