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 support@ccsinfo.com

Timer Questions

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



Joined: 17 Jun 2006
Posts: 12

View user's profile Send private message

Timer Questions
PostPosted: Wed Jul 12, 2006 9:48 am     Reply with quote

I have a couple of questions regarding the use of timers:

First, I want to read some sensor readings through the ADC for x amount of seconds. How do I use the timers to time my sensor reading period for the specified amount of time?

Second, I want to know how long it took for a sensor reading to occur. This is the opposite of what I wanted to do before. For example, when the sensor reading reaches a certain value, I want to read the timer so that I know the time it took for the event to happen.

I'm new to timers so I don't know if what I said is possible with the use of timers. If not, can anyone recommend something else to use? Thanks alot for your help.
rwyoung



Joined: 12 Nov 2003
Posts: 563
Location: Lawrence, KS USA

View user's profile Send private message Send e-mail

PostPosted: Wed Jul 12, 2006 1:28 pm     Reply with quote

A little clarifiacation:

Quote:
First, I want to read some sensor readings through the ADC for x amount of seconds. How do I use the timers to time my sensor reading period for the specified amount of time?


By this do you mean continuously read a sensor for X seconds or read a sensor once every X seconds? Both ways are doable.

The second item you ask about is possible.

One way would be to configure your timer for some reasonable resolution, some timers have prescalers. Clock the timer from the system clock. Then when you start your reading, read and remember the timer value. Then keep reading your ADC until you get your desired result. Read timer again. Caveat: timer can overflow and while you can detect and compensate for a single overflow with these two timer value reads, you can't tell the difference between one overflow and 100 overflows.

If your longest reading duration will guarantee multiple overflows, you should look at some of the real-time clock code on the forumn. You could modify it for the resolution you need and run the timer and its interrupt in the background to time your sensor's activity.
_________________
Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month!
STIX



Joined: 17 Jun 2006
Posts: 12

View user's profile Send private message

PostPosted: Wed Jul 12, 2006 1:47 pm     Reply with quote

Quote:
By this do you mean continuously read a sensor for X seconds.


Yes, this is what I mean. Is the approach here to start the timer and then after x seconds, generate an interrupt? Can it be done without any interrupt?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jul 12, 2006 4:40 pm     Reply with quote

You can poll an interrupt flag in a loop, to see if it's been set.
This way, you can tell if some hardware module has completed
an action, without having an isr. In some cases, this may be
an appropriate way to write the code. Here's an example
for the INT_EXT interrupt.
http://www.ccsinfo.com/forum/viewtopic.php?t=27167&start=4
rwyoung



Joined: 12 Nov 2003
Posts: 563
Location: Lawrence, KS USA

View user's profile Send private message Send e-mail

PostPosted: Fri Jul 14, 2006 6:54 am     Reply with quote

STIX wrote:
Quote:
By this do you mean continuously read a sensor for X seconds.


Yes, this is what I mean. Is the approach here to start the timer and then after x seconds, generate an interrupt? Can it be done without any interrupt?


If your duration and timing resolution is on the order of seconds then I would look in the Code section of the forum for the real-time code modules. You can have that running in the background, read the time at start and loop on your sampling routine, always checking the latest time and drop out of the sample routine when appropriate.

If, for example, your sampling duration was 2 seconds and you were OK with 2.0 or 2.1 or 2.01 or maybe 2.001 then the above will probably work.

PCM's suggestion too look at the INT_EXT example is good so that you can see an alternative to using an interrupt.
_________________
Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month!
STIX



Joined: 17 Jun 2006
Posts: 12

View user's profile Send private message

PostPosted: Fri Jul 14, 2006 11:46 am     Reply with quote

I did some experimenting and wrote a simple program to read my temperature sensor (LM35) for a period of 12 sec. I'm using Timer1 and internal clock with a prescaler value of 8 (timer overflow every: 1/1MHz * 8 * 65536 = 0.52 sec). However, I'm having trouble with the ADC reading. It's not reading the correct value coming from the temperature sensor. I'm suppose to sense room temperature (ie 24.6°C) and store the value in the EEPROM. Afterwards, when I check the value in EEPROM, it's not the correct temperature reading. I should be getting something like 24.6, instead I get something like 252 stored in EEPROM. Furthermore, when I tried to sense a higher temperature than 24.6°C, I get a number like 237 stored in the EEPROM. I don't know what I'm doing wrong, are the interrupts interferring with the ADC?

I'm using the code in the following link to convert the HEX numbers in EEPROM to decimal numbers: http://www.ccsinfo.com/forum/viewtopic.php?t=1831&highlight=pconvert.

Code:
#include <16f877a>
#device *=16
#device ADC=10
#include <math>
#fuses HS,NOWDT,NOPUT,NOPROTECT,NODEBUG,BROWNOUT,NOLVP,NOCPD,NOWRT
#byte TRISA    = 0x85
#byte TRISB    = 0x86
#byte ADCON0   = 0x1F
#byte ADCON1   = 0x9F
#byte ADRESH   = 0x1E
#byte ADRESL   = 0x9E
#bit  GO       = ADCON0.2

float meas, ref;
int seconds_count;
int1 time_reached;

#int_timer1
void timer1_isr (void)
{
   if (seconds_count++ == 23)  //12/0.52 = 23
      time_reached = 1;
}

void main (void)
{
   TRISA  = 0xff;  //Pin AN0 on PORTA set as input
   ADCON1 = 0x80;  //Right justify result
   seconds_count = 1;
   time_reached = 0;
   ref = 0.0;
   
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
   set_timer1(0);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   
   while (time_reached == 0)
  {
     ADCON0 = 0;         //Select AN0 input
     ADCON0 = 0x41;    //Turn A/D on in AN0, select FOSC/8 clock
     meas = read_ad (0x45);
     if (meas > ref)
        ref = meas;
   }
   
    if (time_reached == 1)
       write_eeprom_float(0, ref);
}

float read_ad (float chnl)
{
   float temp;
   long ad, v;

   ADCON0 = chnl;   
   while (GO == 1);
   ad = make16(ADRESH, ADRESL);
   v = 5.0*ad*(100.0/1024.0);  //Get actual temp. in °C
   temp = (float)v;
   return temp;
}

void write_eeprom_float (long int n, float data)
{
   int i;
   for (i = 0; i < 4; i++) {
      write_eeprom(i + n, *(((int *)&data) + i));
   }
   return;
}
rwyoung



Joined: 12 Nov 2003
Posts: 563
Location: Lawrence, KS USA

View user's profile Send private message Send e-mail

PostPosted: Fri Jul 14, 2006 12:18 pm     Reply with quote

1) Don't bother with floating point. Store either as a fixed point (use 32 bits) or just store the RAW adc reading.

2) You don't need to build up your own version of the adc reading from the two bytes. Since you have specified #device ADC = 10 you will be getting back a 16 bit number from the built in (consult your manual) read_adc(). Use that instead.

3) You don't need to explicitly include a "return" statement in a void function (ie subroutine). The "return" statement is implicit.

4) Consult your manual for the functions used to configure the ADC and select channels. By using those you have more portability between parts.
_________________
Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month!
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