|
|
View previous topic :: View next topic |
Author |
Message |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Mar 15, 2005 8:45 am |
|
|
What are you trying to do? The counter will continue to count since you do not stop it. Also, quit using goto's. Stick it in a while loop. This is C not BASIC. |
|
|
bhyatyab
Joined: 26 Jan 2005 Posts: 13
|
Timer |
Posted: Wed Mar 16, 2005 1:51 am |
|
|
Hi
I want the counter to count to say 2hrs than to run the code below. In code, it works but then the counter stops counting for the duration it takes to complete the while loop.
Code: |
{
start:
while(secs==0 && hrs==2)
{
output_high(PIN_C2);
// i have a couple of delays and other code like the one above ( //output_high(PIN_C2);)
}
goto start;
}
}
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Mar 16, 2005 3:48 am |
|
|
I don't see any obvious errors in your code. What makes you think the clock stops counting? I mean, what did you see or measure?
I still have no clue as to what you want to achieve, but one thing that worries me in your code is the line: Code: | while(secs==0 && hrs==2) | This will loop for one second, but if your code is fast this loop may be executed many times. Is that what you intended? |
|
|
bhyatyab
Joined: 26 Jan 2005 Posts: 13
|
Timer |
Posted: Wed Mar 16, 2005 4:13 am |
|
|
Hi
Below is my exact code. All im doing is switching on and off relays at a specific time (secs==0 && mins==0 && hrs==1). After the 2nd time hrs == 1(after 24hrs), the program execute 34secs later.
Code: |
#include <18F452.h>
#fuses NOWDT, WDT128, HS, NOPROTECT, NOOSCSEN, NOBROWNOUT, BORV20, PUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use delay(clock=20000000)
#define INTS_PER_SECOND 76 // (4000000/(4*1*65536)) = 15 for a 4Mhz Crystal - 262144
int8 secs=0; // A running seconds counter
int8 mins=0;
int8 hrs=0;
int8 int_count=0; // Number of interrupts left before a second has elapsed
int8 loop_condition=0;
void reset_one_second_counter(void);
#INT_TIMER1 // This function is called every time
void clock_isr() { // timer 1 overflows (65535->0), which is
// approximately 19 times per second for
if(--int_count==0) { // this program.
++secs;
if(secs==60){
mins=mins+1;
secs=0;
}
if(mins==60){
hrs=hrs+1;
mins=0;
}
if(hrs==24){
hrs=0;
}
int_count = INTS_PER_SECOND;
}
}
#int_EXT
EXT_isr()
{
delay_ms(10000);
//if (!input(PIN_A4))
// {
// output_high(PIN_C2);
// delay_ms(100);
// output_low(PIN_C2);
// delay_ms(100);
// output_high(PIN_C2);
// delay_ms(100);
// output_low(PIN_C2);
// }
// else
// delay_cycles( 1 ); //clear
if (!input(PIN_B0))
{
output_high(PIN_A1);
delay_ms(5000);
output_low(PIN_A1);
delay_ms(1000);
output_high(PIN_A2);
delay_ms(500);
output_low(PIN_A2);
delay_ms(1000);
output_high(PIN_A2);
delay_ms(500);
output_low(PIN_A2);
delay_ms(1000);
output_high(PIN_A5); //call - menu
delay_ms(500);
output_low(PIN_A5);
delay_ms(15000);
output_high(PIN_A1); //end - menu - requesting
delay_ms(2000);
output_low(PIN_A1);
delay_ms(1000);
// delay_ms(10000); //delay to resend message
}
else
delay_cycles(250); //clear
}
#int_EXT1
EXT1_isr()
{
delay_ms(10000);
if (!input(PIN_B1))
{
output_high(PIN_A1); //clear
delay_ms(5000);
output_low(PIN_A1);
delay_ms(1000);
output_high(PIN_A2); //down
delay_ms(500);
output_low(PIN_A2);
delay_ms(1000);
output_high(PIN_A2); //down
delay_ms(500);
output_low(PIN_A2);
delay_ms(1000);
output_high(PIN_A5); //call - menu
delay_ms(500);
output_low(PIN_A5);
delay_ms(15000);
output_high(PIN_A1); //end - menu - requesting
delay_ms(2000);
output_low(PIN_A1);
delay_ms(1000);
// delay_ms(10000);
}
else
delay_cycles( 250 );
}
#int_EXT2
EXT2_isr()
{
}
void main() {
int_count = INTS_PER_SECOND;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
set_timer1(0);
enable_interrupts(INT_TIMER1);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
enable_interrupts(INT_EXT2);
enable_interrupts(GLOBAL);
reset_one_second_counter();
{
start:
//while (seconds < 10)
// {
// wait til 20 secs is up
// }
// seconds is now >= 20
//while(loop_condition==0)
while(secs==0 && mins==0 && hrs==1 )
{
output_high(PIN_C2);
delay_ms(3000);
output_low(PIN_C2);
delay_ms(1000);
output_high(PIN_C2);
delay_ms(2000);
output_low(PIN_C2);
delay_ms(10000);
output_high(PIN_A1);
delay_ms(500);
output_low(PIN_A1);
delay_ms(1500);
output_high(PIN_A2);
delay_ms(500);
output_low(PIN_A2);
delay_ms(1500);
output_high(PIN_A2);
delay_ms(500);
output_low(PIN_A2);
delay_ms(1500);
output_high(PIN_A2);
delay_ms(500);
output_low(PIN_A2);
delay_ms(1500);
output_high(PIN_A2);
delay_ms(500);
output_low(PIN_A2);
delay_ms(1500);
output_high(PIN_A5);
delay_ms(500);
output_low(PIN_A5);
delay_ms(12000);
output_high(PIN_A5);
delay_ms(500);
output_low(PIN_A5);
delay_ms(1500);
output_high(PIN_A1);
delay_ms(2000);
output_low(PIN_A1);
}
goto start;
}
}
void reset_one_second_counter(void)
{
int_count = INTS_PER_SECOND;
secs = 0;
}
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Mar 16, 2005 8:34 am |
|
|
Code: | #int_EXT
EXT_isr()
{
delay_ms(10000); |
NEVER put a large delay like this in an interrupt routine!!!!
Interrupt routines must be as fast as possible because while the interrupt is executing all other interrupts are disabled. So in your code, with the timer1 interrupt occurring 76 times a second, none of the other interrupts may take more than 1/76 part of a second or you will miss interrupts.
Quote: | After the 2nd time hrs == 1(after 24hrs), the program execute 34secs later. | You are counting 76 interrupts per second but to be exact there are 76.2939... interrupts per second which makes your clock 333 seconds per day too fast. The fact you have a smaller timing error might have to do with your large delays in the other interrupts.
The best RTC timer implementation I have seen was given by Neutone. Special in this routine is that despite the timer interrupt not being exactly accurate, the seconds have a zero long time drift.
Code: |
//RTC variables
#define XTAL_FREQUENCY 20000000
int32 Ticker;
int8 seconds=0, hours=0, minutes=0;
/*********************************************
* Initialize RTC *
*********************************************/
void Initialize_RTC(void)
{
Ticker = XTAL_FREQUENCY;
setup_timer_1( T1_INTERNAL | T1_DIV_BY_1 ); // initialize 16-bit Timer1 to interrupt about
// 76 times per second (exactly every 65536 clock cycles)
enable_interrupts( INT_TIMER1 ); // Start RTC
}
// Global Real Time Clock Information
#int_TIMER1 // Clock interrupt adjusted to occur ~ 76 times/second
void TIMER1_isr() // -=Process Zero Drift Real Time Clock Information=-
{
Ticker -= 65536; // Decrement ticker by clocks per interrupt
if ( Ticker < 65536 ) // If second has expired
{ Ticker += XTAL_FREQUENCY; // Increment ticker by clocks per second
seconds++; // Increment number of seconds
}
if(seconds == 60) {minutes++;seconds = 0;
if(minutes == 60) {hours++;minutes = 0;
if(hours == 24) {hours= 0;}}}
} |
Mark said: Quote: | Also, quit using goto's. Stick it in a while loop. This is C not BASIC. | I totally agree! Get rid of that ugly 'goto start' instruction. |
|
|
|
|
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
|