CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

problem while reading timer1 value ...

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
deepakomanna



Joined: 06 Mar 2007
Posts: 92
Location: Pune,India

View user's profile Send private message AIM Address Yahoo Messenger

problem while reading timer1 value ...
PostPosted: Thu Sep 06, 2007 7:25 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Sep 06, 2007 8:15 am     Reply with quote

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







PostPosted: Thu Sep 06, 2007 8:23 am     Reply with quote

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

View user's profile Send private message AIM Address Yahoo Messenger

problem while reading timer1 value ...
PostPosted: Thu Sep 06, 2007 10:06 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Sep 07, 2007 3:58 am     Reply with quote

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

View user's profile Send private message AIM Address Yahoo Messenger

problem while reading timer1 value ...
PostPosted: Fri Sep 07, 2007 4:31 am     Reply with quote

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







PostPosted: Fri Sep 07, 2007 5:26 am     Reply with quote

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

View user's profile Send private message AIM Address Yahoo Messenger

problem while reading timer1 value ...
PostPosted: Fri Sep 07, 2007 6:18 am     Reply with quote

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







PostPosted: Fri Sep 07, 2007 6:52 am     Reply with quote

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

View user's profile Send private message AIM Address Yahoo Messenger

problem while reading timer1 value ...
PostPosted: Wed Sep 12, 2007 12:32 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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