View previous topic :: View next topic |
Author |
Message |
SerialGmr8
Joined: 30 Nov 2007 Posts: 13
|
3 Minute interrupt required |
Posted: Mon Dec 03, 2007 12:09 am |
|
|
Greetings all,
im trying to get an approximate interupt rate of one second on timer0, using ccs compliler version 4.059, to a pic16f877a target chip running at 20Mhz
Code: | #include <16F877A.h>
#use delay(clock=20000000)
// The cycle time will be (1/clock)*4*t2div*(period+1)
// clock=20Mz and period=6144
// (1/20Mz)*4*1*6145=1.23MS (814Hz)
#int_TIMER0
int16 counter = 0;
void TIMER0_isr()
{
counter++ ;
if(counter == 814)
{
counter = 0;
OneSec = 1;
}
}
void main() {
setup_timer_0(T2_DIV_BY_1,6144,1);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
while(1)
{
}
}
|
not having much luck here. Ideally, I want to get to an interupt every three minutes to control a thermostat, but apparantly, im a long ways from there. Would greatly appreciate some assistance.
best regards |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 03, 2007 1:22 am |
|
|
Quote: | void main() {
setup_timer_0(T2_DIV_BY_1,6144,1);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
|
The CCS manual says setup_timer_0() only has one parameter, called 'mode':
Quote: | setup_timer_0 (mode) |
Look in the 16F877A.H file to see the list of constants that may be
used as the mode parameter. They all begin with 'RTCC'. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Dec 03, 2007 3:39 am |
|
|
Code: | #int_TIMER0
int16 counter = 0; <-- Don't do this !!!
void TIMER0_isr()
{ | Do not insert anything between the interrupt declaration (#int_xxx) and the function name. Maybe the compiler is not generating an error message but that doesn't mean it is correct syntax. |
|
|
SerialGmr8
Joined: 30 Nov 2007 Posts: 13
|
|
Posted: Mon Dec 03, 2007 5:57 am |
|
|
Thanks guys. i've updated my code to be similar to one of the examples with ccs. but this still doesnt work.
when i get my first three minute interrupt, would i have to restart a counter or something ?
Code: |
#define INTS_PER_SECOND 76 // (20000000/(4*256*256))
#int_rtcc // This function is called every time
void clock_isr() { // the RTCC (timer0) overflows (255->0).
//For this program this is apx 76 times
if(--int_count==0) { // per second.
++seconds;
int_count=INTS_PER_SECOND;
}
}
void main() {
int_count=INTS_PER_SECOND;
set_timer0(0);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
(while 1)
{
if(seconds == 180)
{
....
}
}
}
|
|
|
|
Foppie
Joined: 16 Sep 2005 Posts: 138 Location: The Netherlands
|
|
Posted: Mon Dec 03, 2007 6:28 am |
|
|
I think you should reset your second counter, like this:
Code: | if(seconds == 180)
{
....
seconds = 0;
} |
else the seconds keep increasing until it overflowes to 0. Depending on your declaration of seconds, this might take 75 seconds longer in case of a int8 declaration. But also much longer for int16 or int32 declaration.
I hope this helps |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Dec 03, 2007 8:10 am |
|
|
Also, from the CCS manual on Setup_counters(): Quote: | This function is provided for compatibility with older versions. setup_timer_0 and
setup_WDT are the recommended replacements when possible. |
|
|
|
SerialGmr8
Joined: 30 Nov 2007 Posts: 13
|
|
Posted: Mon Dec 03, 2007 9:26 am |
|
|
mcuh thanks. I will give this a try and let you all know how it goes. |
|
|
SerialGmr8
Joined: 30 Nov 2007 Posts: 13
|
Much thanks. |
Posted: Mon Dec 03, 2007 10:42 am |
|
|
Thanks to all for their most valued assistance.
The following code implements a 3 minute timer on timer0.
Code: |
#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#define INTS_PER_SECOND 76 // (20000000/(4*256*256))
int8 ledstate;
int8 seconds; // A running seconds counter
int8 int_count; // Number of interrupts left before a second has elapsed
#int_rtcc // This function is called every time
void clock_isr() { // the RTCC (timer0) overflows (255->0).
// For this program this is apx 76 times
if(--int_count==0) // per second.
{
++seconds;
int_count=INTS_PER_SECOND;
}
}
void main()
{
int_count=INTS_PER_SECOND;
set_timer0(0);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
output_low(pin_c7);
seconds = 0;
while(1)
{
if(seconds == 180)
{
if(ledstate==0) //this routine will keep switching the value of your
{ // each time the routine gets entered.
ledstate=1;
output_high(PIN_C7);
}
else
{
ledstate=0;
output_low(PIN_C7);
}
seconds = 0;
}
}
}
|
|
|
|
Foppie
Joined: 16 Sep 2005 Posts: 138 Location: The Netherlands
|
|
Posted: Tue Dec 04, 2007 1:51 am |
|
|
one comment:
Code: | if(ledstate==0) //this routine will keep switching the value of your
{ // each time the routine gets entered.
ledstate=1;
output_high(PIN_C7);
}
else
{
ledstate=0;
output_low(PIN_C7);
} |
could be replaced by just output_toggle(PIN_C7); |
|
|
SerialGmr8
Joined: 30 Nov 2007 Posts: 13
|
|
Posted: Tue Dec 04, 2007 6:21 am |
|
|
duely noted Foppie.
much thanks |
|
|
|