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

Show Time on LCD Display

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
P. Frank
Guest







Show Time on LCD Display
PostPosted: Wed Apr 14, 2004 3:23 am     Reply with quote

Hi,
i want to write a program which measure time from pulses with the accuracy of 10ms. I wait for the first positive edge of my signal which i want to measure and then start the Timer 1 which give me an interrupt all 10ms. Now i count this interrupts until the edge is negative.
Then i want to show the actual value in the format hh:mm:ss:ms on the display. Additionaly i want to store the last 10 measured values in 10 variabels and calculate the average off this. After calculating i want also to show it on the display in the format hh:mm:ss:ms.

My problem is now that i am not sure which variables i should use to store the 10 average values and the actual value.

1. I can use 11 U32 Variables to save the value from the 10ms counter and change the format to hh:mm:ss:ms if i want to show it on the display.

2. I can use int8 hour[11], minute[11],second[11],millisecond[11] and refresh this variables every time the Timer 1 interrupt occur.

What would you do? I don`t know a really good way to make the format hh:mm:ss:ms from a U32 which counts every 10ms.

Pic is a 16F876@20MHz.

Best regards
Patrick Frank
Couch



Joined: 20 Jan 2004
Posts: 9
Location: Ottawa, Ontario Canada

View user's profile Send private message

PostPosted: Wed Apr 14, 2004 7:15 am     Reply with quote

Hello,

Use an int32 format to make your interrupt sequence (and your last 10 memory) as clean as possible. The downside as you mentioned is that the LCD formatting is a bit trickier, but not too bad - just perform some modulus math to extract the hour, then minute, then seconds (subracting their contribution from the int32 value as you go). If you make this a function, you can make this pretty compact to use for all 10 time values.

thanks
Dave
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Wed Apr 14, 2004 7:35 am     Reply with quote

This is the most accurate aproach using a crystle that is does not divide to an integer number of interupts per second. You could use what ever timer you wish by altering the number of instruction per interupt.

Code:

/*********************************************
*    Initialize RTC                          *
*********************************************/
void Initialize_RTC(void)
{  Ticker = XTAL_FREQUENCY;
   setup_timer_2 ( T2_DIV_BY_4, 0xff, 4 );   // initialize 8 bit counter/timer 2 to interupt every 16384 clock cycles
   enable_interrupts( INT_TIMER2 );          // Start RTC
}

// Global Real Time Clock Information
#int_TIMER2                                  // Clock interrupt adjusted to occurs ~ 1ms
void TIMER2_isr()                            //  -=Process Zero Drift Real Time Clock Information=-
{  tickmSec = 1;                             // set each MS very approximately
   Ticker -= 16384;                          // Decrement ticker by clocks per interupt
   if ( Ticker < 16384 )                     // If second has expired
   {  Ticker += XTAL_FREQUENCY;              // Increment ticker by clocks per second
      second++;                              // Increment number of seconds
      tickSec = 1;                           // set each Second very accuratly
   }
}
P. Frank
Guest







PostPosted: Fri Apr 16, 2004 1:54 am     Reply with quote

Hello,
thanks for the response. Now i am a big step ahead.

@Neutone
I use a pic 16F876@20MHz.
I setup my timer following:
Code:

setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // setup interrupts
set_timer1 (15536);//10ms(=65536-(0.01/(4/20000000))

This gives me a interrupt every 10ms. I need this accurate for a week.
Is this possible our should i use our function? I don`t have much experience with this.

@All
Now i use the U32 variables to save the timer values.
I have programmed a function which convert this in dd:hh:mm:ss:ms to show it on the LCD. Here is the function:

Initalisation:
Code:

int32 aktuelle=0;          //measured time
int32 maketime_1=0;   //temp
int32 maketime_2=0;   /temp

int8  ms;        //milliseconds
int8  s;           //seconds
int8  m;          //minutes
int8  h;           //hours
int8  d;           //days
void MakeTime (int32 zeit,short hours);

Program:
Code:

MakeTime(aktuelle,0);  //gives the U32 time to the function

void MakeTime (int32 zeit,short hours) //calculates the Time from U32 Value.
   {
   h=0;d=0;                                                     //12345678=Value to Calculate
   maketime_1=zeit/100;     //Time in 10ms/100  =Seconds        //123456
   maketime_2=maketime_1*100;   //Time without ms*100           //12345600
   ms=zeit-maketime_2;      //Milliseconds                      //78=12345678-12345600     

   maketime_2=maketime_1/60;    //Time in Seconds/60 = Minutes  //2057
   zeit=maketime_2;                                             //2057
   maketime_2=maketime_2*60;                                    //123420 
   s=maketime_1-maketime_2;     //Seconds                       //36=123456-123420

   maketime_2=zeit/60;    //Time in Minutes/60 = Hours          //34
   maketime_1=maketime_2;                                       //34
   maketime_2=maketime_2*60;                                    //2040       
   m=zeit-maketime_2;     //Minutes                             //17=2040-2057

   if(hours)
   {
    maketime_2=maketime_1/24;    //Time in Hours/24 = Days       //1
    d=maketime_2;                //Days                          //1
    maketime_2=maketime_2*24;                                    //24
    h=maketime_1-maketime_2;     //Hours                         //10
   }           
    Anzeigen(); //shows the values on lcd.
   }

void Anzeigen (void)
    {
     LCD_SetPosition ( LINE_16_2);
     printf ( LCD_PutChar, "%02ud%02uh%02um%02us%02u",d,h,m,s,ms);
     }


It works :-) But i think it`s very time intensive. Is there another way?
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Fri Apr 16, 2004 7:40 am     Reply with quote

To get accuracy you must let the timer run freely. Never attempt to load it with a value to achieve accuracy. You can setup timer2 to interupt every 1mS with no error at all. The interupt would occure every 5000 instruction cycles. I don't think thats over taxing the program.
P. Frank
Guest







PostPosted: Mon Apr 19, 2004 1:18 am     Reply with quote

Neutone wrote:
This is the most accurate aproach using a crystle that is does not divide to an integer number of interupts per second. You could use what ever timer you wish by altering the number of instruction per interupt.

Code:

/*********************************************
*    Initialize RTC                          *
*********************************************/
void Initialize_RTC(void)
{  Ticker = XTAL_FREQUENCY;
   setup_timer_2 ( T2_DIV_BY_4, 0xff, 4 );   // initialize 8 bit counter/timer 2 to interupt every 16384 clock cycles
   enable_interrupts( INT_TIMER2 );          // Start RTC
}

// Global Real Time Clock Information
#int_TIMER2                                  // Clock interrupt adjusted to occurs ~ 1ms
void TIMER2_isr()                            //  -=Process Zero Drift Real Time Clock Information=-
{  tickmSec = 1;                             // set each MS very approximately
   Ticker -= 16384;                          // Decrement ticker by clocks per interupt
   if ( Ticker < 16384 )                     // If second has expired
   {  Ticker += XTAL_FREQUENCY;              // Increment ticker by clocks per second
      second++;                              // Increment number of seconds
      tickSec = 1;                           // set each Second very accuratly
   }
}

Hello Neutone,
i want to use your source code, but i don`t understand it complete.
Can you give me a little help?
I think i must use the function "Initialize_RTC" only one time. This function writes the XTAL_Frequency (20000000) in the variable Ticker (Int32 ?) and initalise the timer 2. That`s clear.
But what your are doing in the TIMER2_isr? I don`t no what i should do with the variables "tickSec","tickmSec" and in which format they are (INT8 or something?). What you doing with "Ticker" in the interrupt?

Best regards and thanks for the help

Patrick Frank
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Mon Apr 19, 2004 7:51 am     Reply with quote

In main wait to the input to change and then clear both seconds and mseconds. In main wait for it to change again and then print the time.

Code:

#int_TIMER2   
void TIMER2_isr()
{ mSecond++;           
   if ( mSecond > 999 ) 
   { second++;
      mSecond=0;
   }
}
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