external interrupt code

Go To Last Post
20 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear community,
I am having a small project, where the external interrupt is triggered and the code inside the interrupt polls for the commands I give through a joystick.

ISR(INT0_vect)
{

	cli();			//Disable interrupts
	GIFR|=(1<<INTF0); //Clear Flag;
	
	TCCR2 = 0;			//Stop Timer2
	//up and down must change value of digit
	//while left and right change the selected digit
		
	Position = 0;

	while (!STOP) 
	{
		if (bit_is_clear(PIND, PD2))//if Middle button is pressed
		{
			_delay_ms(DEBOUNCE_TIME);
            if (bit_is_clear(PIND, PD2))//if Middle button is pressed
				{
					STOP = 1;			//then setting is done!
				}	
		}
	
		if (bit_is_clear(PIND, PD6))//if Right button is pressed
		{
			_delay_ms(DEBOUNCE_TIME);
			if (bit_is_clear(PIND, PD6))//if Right button is pressed
			{
				++Position;
				if (Position>=7)
					Position = 7;
			}					
		}
		
		if (bit_is_clear(PIND, PD1))//if Left button is pressed
		{
			_delay_ms(DEBOUNCE_TIME);
			if (bit_is_clear(PIND, PD1))//if Left button is pressed
			{
				--Position;
				if (Position<=0)
					Position = 0;
			}					
		}
		
		if (bit_is_clear(PIND, PD3))//if Up button is pressed
		{
			_delay_ms(DEBOUNCE_TIME);
            if (bit_is_clear(PIND, PD3))//if Up button is pressed
				{
					switch (Position)
					{
						case 0:	++t.hour;
								ConvertToBCD(t.hour,t.minute);	
								//Show time to displays;
								break;
						case 1:	++t.minute;
								ConvertToBCD(t.hour,t.minute);	
								//Show time to displays;
								break;
						case 2:	++t.date;
								ConvertToBCD(t.date,t.month);	
								//Show time to displays;
								break;
						case 3:	++t.month;
								ConvertToBCD(t.date,t.month);	
								//Show time to displays;
								break;
						case 4:	
								++Y;
								t.year = 1000*Y;
								ConvertToBCD(t.year/100,t.year%100);	
								//Show time to displays;
								break;
						case 5:	
								++y;
								t.year = (1000*Y+100*y);
								ConvertToBCD(t.year/100,t.year%100);	
								//Show time to displays;
								break;
						case 6:	
								++X;
								t.year = (1000*Y+100*y+10*X);
								ConvertToBCD(t.year/100,t.year%100);	
								//Show time to displays;
								break;
						case 7:	
								++x;
								t.year = (1000*Y+100*y+10*X+x);
								ConvertToBCD(t.year/100,t.year%100);	
								//Show time to displays;
								break;
						case 8:	++alarm.hour;
								ConvertToBCD(alarm.hour,alarm.minute);	
								//Show time to displays;
								break;
						case 9:	++alarm.minute;
								ConvertToBCD(alarm.hour,alarm.minute);	
								//Show time to displays;
								break;
					}					
				}					
		}	
		
		if (bit_is_clear(PIND, PD0))//if Down button is pressed
		{
			_delay_ms(DEBOUNCE_TIME);
            if (bit_is_clear(PIND, PD0))//if Down button is pressed
				{
					switch (Position)
					{
						case 0:	--t.hour;
								ConvertToBCD(t.hour,t.minute);	
								//Show time to displays;
								break;
						case 1:	--t.minute;
								ConvertToBCD(t.hour,t.minute);	
								//Show time to displays;
								break;
						case 2:	--t.date;
								ConvertToBCD(t.date,t.month);	
								//Show time to displays;
								break;
						case 3:	--t.month;
								ConvertToBCD(t.date,t.month);	
								//Show time to displays;
								break;
						case 4:	
								--Y;
								t.year = 1000*Y;
								ConvertToBCD(t.year/100,t.year%100);	
								//Show time to displays;
								break;
						case 5:	
								--y;
								t.year = (1000*Y+100*y);
								ConvertToBCD(t.year/100,t.year%100);	
								//Show time to displays;
								break;
						case 6:	
								--X;
								t.year = (1000*Y+100*y+10*X);
								ConvertToBCD(t.year/100,t.year%100);	
								//Show time to displays;
								break;
						case 7:	
								--x;
								t.year = (1000*Y+100*y+10*X+x);
								ConvertToBCD(t.year/100,t.year%100);	
								//Show time to displays;
								break;
						case 8:	--alarm.hour;
								ConvertToBCD(alarm.hour,alarm.minute);	
								//Show time to displays;
								break;
						case 9:	--alarm.minute;
								ConvertToBCD(alarm.hour,alarm.minute);	
								//Show time to displays;
								break;
					}					
				}					 				
		}	
	} 
	
	t.second = 0;
	ConvertToBCD(t.hour,t.minute);	//Show time to displays;
	SET_TIME_FLAG = 1;	
	SET_ALARM_FLAG = 1;
	GICR|=(1<<INT1);				//Enable external interrupt INT1 so now "UP" toggles ALARM ON
	TCCR2 |= (1

My problem is that I do not get the expected behavior. As you can probably predict this is a digital clock. It is something I thought years ago, bought some components and left it there...now I know there are more efficient ways to do such a project...
Anyway, I use atmega8535 @ 16 MHz, and timer2 is clocked asynchronously with an exernal crystal of 32.768 kHz.
The real time clock works fine, but the external interrupt INT0 I use, is supposed to give me the opportunity to re-initialize the initial time, from where the rtc must start to count.

Here is the rest of the code

Last Edited: Tue. Jun 19, 2012 - 10:21 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
int main(void)
{                                
    STOP = 0;
	//Initialize port
    PortsInit();
	
    //Initialise the timer2
	t.year = 2012;
	t.month = 7;
	t.date = 17;
    RTCInit();
    //Enable global interrupts
    State = 0;
    while(1)
    {
		sei();

		if (bit_is_clear(PIND, PD6))//if Right button is pressed
		{
			_delay_ms(DEBOUNCE_TIME);
			if (bit_is_clear(PIND, PD6))//if Right button is pressed
			{
				++State;
				if (State>=3)
					State = 3;
			}					
		}
		if (bit_is_clear(PIND, PD1))//if Left button is pressed
		{
			_delay_ms(DEBOUNCE_TIME);
			if (bit_is_clear(PIND, PD1))//if Left button is pressed
			{
				--State;
				if (State<=0)
					State = 0;
			}					
		}

		switch (State) 
		{
		case 0:
			ConvertToBCD(t.hour,t.minute);
			break;
		case 1:
			ConvertToBCD(t.minute,t.second);
			break;
		case 2:
			ConvertToBCD(t.date,t.month);
			break;
		case 3:
			PORTD |= (1<<PD7);
			ConvertToBCD(t.year/100,t.year%100);
			break;

		}
    }
	return 0;          
}

For some reason I cannot paste my code because the server returns error 400 BAD REQUEST

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
void RTCInit(void)
{
    //Disable timer2 interrupts
    TIMSK  = 0;
    //Enable asynchronous mode
    ASSR  = (1<<AS2);
    //set initial counter value
    TCNT2=0;
    //set prescaller 128
    TCCR2 |= (1<<CS22)|(1<<CS20);
    //wait for registers update
    while (!(ASSR & ((1<<TCN2UB)|(1<<TCR2UB))));
    //clear interrupt flags
    TIFR  |= (1<<TOV2);
    //enable TOV2 interrupt
    TIMSK  |= (1<<TOIE2);
}
void PortsInit (void)
{
    int temp0,temp1;   
     
    for(temp0=0;temp0<4000;temp0++)   // Wait for external clock crystal to stabilize
    {
        for(temp1=0;temp1<0x4000;temp1++);
    }
    
	DDRA=0xFF;		//Packed BCD output for Minutes 7-segment displays
	PORTA=0x00;
	
	DDRB=0xFF;		//Packed BCD output for Hour 7-segment displays
	PORTB=0x00;
	
	DDRC|=(1<<PC2)|(1<<PC0);		
					//PC0 is for blinking the 7-segment displays as needing "SETTING"
					//PC2 is for alarm led ON or OFF
	PORTC|=(1<<PC2)|(1<<PC0);					
	
	DDRD|=(1<<PD4)|(1<<PD5)|(1<<PD7);		
					//PD0..3 & PD6 is for joystick input
					//PD4 PD5 for buzzer output
					//PD7 is for seconds "ticking" led
	PORTD|=(1<<PD7)|(1<<PD6)|(1<<PD3)|(1<<PD2)|(1<<PD1)|(1<<PD0);
	//Output PD7 high and enable pull-ups for joystick inputs

	GICR|=(1<<INT0);

	GIFR|=(1<<INTF0); //Clear Flag;
	//Enable external interrupt INT0 so now "PRESS" calls setting routine
	Y = 0;
	y = 0;
	X = 0;
	x = 0;
}
void ConvertToBCD(char HighData, char LowData)
{ 
HighBCD = (HighData / 10) << 4; 
HighBCD += (HighData % 10); 

LowBCD = (LowData / 10) << 4; 
LowBCD += (LowData % 10); 

PORTB = HighBCD;
PORTA = LowBCD;
} 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include 
#include 
#include 
//#include 
#include 
      
#define DEBOUNCE_TIME 125        /* time to wait while "de-bouncing" button */
#define LOCK_INPUT_TIME 250     /* time to wait after a button press */	  

char not_leap(void);
void init(void);

typedef struct{ 
unsigned char second;   //enter the current time, date, month, and year
unsigned char minute;
unsigned char hour;                                     
unsigned char date;       
unsigned char month;
unsigned int year;      
            }time;

 volatile time t, alarm;  
 volatile int Y,y,X,x;
 volatile signed char Position, State;
 volatile unsigned char STOP;
 volatile unsigned char SET_TIME_FLAG, SET_ALARM_FLAG, ALARM_ON_FLAG;
 unsigned char HighBCD, LowBCD;

I am really sorry but it doesn't work in the whole

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the rest goes here


ISR (TIMER2_OVF_vect) //overflow interrupt vector
{ 

    if (++t.second==60)        //keep track of time, date, month, and year
    {
        t.second=0;
        if (++t.minute==60) 
        {
            t.minute=0;
            if (++t.hour==24)
            {
                t.hour=0;
                if (++t.date==32)
                {
                    t.month++;
                    t.date=1;
                }
                else if (t.date==31) 
                {                    
                    if ((t.month==4) || (t.month==6) || (t.month==9) || (t.month==11)) 
                    {
                        t.month++;
                        t.date=1;
                    }
                }
                else if (t.date==30)
                {
                    if(t.month==2)
                    {
                       t.month++;
                       t.date=1;
                    }
                }              
                else if (t.date==29) 
                {
                    if((t.month==2) && (not_leap()))
                    {
                        t.month++;
                        t.date=1;
                    }                
                }                          
                if (t.month==13)
                {
                    t.month=1;
                    t.year++;
                }
            }
        }
    }  


//Toggle pin PD7 every second

    PORTD^=(1<<PD7);
	if (!SET_TIME_FLAG)
		PORTC^=(1<<PC0);	//Toggle all displays
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When the external interrupt is executed the number in the displays increase faster than a second, and Up or Down have no effect - just freeze the counting.

Any help or advice is appreciated.

P.S.
The software is not finished...needs some checking routines so please don't jugde me too heavily...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd revisit the overall design - doing everything in the ISR including delays and polling is a very bad idea. Far better to have an ISR that (taking the effect of contact bounce in to account) just sets a flag when a button changes state then have the main, none time critical code in main process the flag(s) that is/are set.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'll give it a try...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

By default, ISRs run with interrupts disabled: cli() was not necessary.
The clearing of the interrupt flag is also redundant.
I'm dubious about the value of stopping a clock.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

when we reset power, time goes to zero...
so the clock starts counting and sometime you want to change the time from 3:12:01 (ex. date 1/1/2000) to
the present time lets say 21:12:00 19/7/2012.
So I stop the timer2 until I finish setting the time and then I start it again.

I will remove cli() and the clearing of flag...thanks, I guess the compiler's optimization might take it out.
Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kakarot wrote:
I will remove cli() and the clearing of flag...thanks, I guess the compiler's optimization might take it out.
'Tisn't a matter of compiler optimization.
'Tis the way the hardware works.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My answer is supposing that the compiler knows how the hardware works and if some dummy user (like me) uses an extra command that is not necessary, it might take it out. But that is a guess!

I made some modifications to my code and it works better...I have to do some debugging and I believe the project will come to target...

Here is some code

ISR(INT0_vect)
{
	SETTING = 1;
	RUNNING = 0;
}

the rest code that used to be inside ISR is in a
while loop in main routine.
I cannot upload it for some reason...
but when I finish the whole project I will upload it.

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

But that is a guess!

Never guess/assume when programming - find out. You are misunderstanding what the optimiser will do - it would be as well to find out. (I have an article about some of this in the Tutorial Forum about Optimisation and the importance of volatile in gcc)
Quote:

I cannot upload it for some reason...
It almost certainly contains at least one % sign. Do one of thes things:

1) replace % with # - everyone here will recognise the substitution

2) add a space after each % sign (you'll notice that in this post so far I've been careful to make suer all % are followed by a space ;-))

3) the ultimate solution is to replace each % with % (seriously!) then it won't matter what follows the symbol and the code will look exactly right. I usually just do a Ctrl-H before posting and replace each % with % (which is not what I typed to get that into this message - but that's another story!)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

I cannot upload it for some reason...
He should have read the sticky.
Quote:
It almost certainly contains at least one % sign. Do one of thes things:
Quote:
3) the ultimate solution is to replace each % with % (seriously!) then it won't matter what follows the symbol and the code will look exactly right. I usually just do a Ctrl-H before posting and replace each % with % (which is not what I typed to get that into this message - but that's another story!)
Neither ctrl-h nor ctrl-shift-H does that for me.
If I'm quoting something with a lot of % signs, I have to paste it into vim to do the massive substitution.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Neither ctrl-h nor ctrl-shift-H does that for me.

You need a better editor - I use Notepad++ where Ctrl-H is the Find/replace.. command.

While IBM can be blamed for a lot of things their CUA wasn't a bad idea and Ctrl-H became the common command for replace:

http://en.wikipedia.org/wiki/Tab...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is the main code
after your clarifications considering mod %
but it has bugs ok?

                               
int main(void)
{     
	//Initialize port
    PortsInit();
	//set_sleep_mode(SLEEP_MODE_PWR_SAVE);
    //Initialise the timer2
	t.year = 2012;
	t.month = 7;
	t.date = 17;
    RTCInit();
    
    State = 0;
	STOP = 0;
	RUNNING = 1;
	SETTING = 0;
while(1)
{	
    while(RUNNING)
    {
		sei();
		//PORTA=0xF0;

		if (bit_is_clear(PIND, PD6))//if Right button is pressed
		{
			_delay_ms(DEBOUNCE_TIME);
			if (bit_is_clear(PIND, PD6))//if Right button is pressed
			{
				++State;
				if (State>=3)
					State = 3;
			}					
		}
		if (bit_is_clear(PIND, PD1))//if Left button is pressed
		{
			_delay_ms(DEBOUNCE_TIME);
			if (bit_is_clear(PIND, PD1))//if Left button is pressed
			{
				--State;
				if (State<=0)
					State = 0;
			}					
		}

		switch (State) 
		{
		case 0:
			ConvertToBCD(t.hour,t.minute);
			break;
		case 1:
			ConvertToBCD(t.minute,t.second);
			break;
		case 2:
			ConvertToBCD(t.date,t.month);
			break;
		case 3:
			PORTD |= (1<<PD7);
			ConvertToBCD(t.year/100,t.year % 100);
			break;
		}
		
//		if (t.hour % 3 && t.second>=1)
//			--t.second;
    }
	
	while(SETTING)
	{
		TCCR2 = 0;			//Stop Timer2
		//up and down must change value of digit
		//while left and right change the selected digit
		//The proper sequence is 
		//1. Hour_high
		//2. Hour_low
		//3. Min_high
		//4. Min_low
		//5. Alarm ON or OFF
		//Press down finishes the setting procedure.
	
		Position = 0;
		

		while (!STOP) 
		{
			
			if (bit_is_clear(PIND, PD2))//if Pressed button is pressed
			{
				//PORTA^=(0xFF);
				//_delay_ms(DEBOUNCE_TIME);
				//if (bit_is_clear(PIND, PD2))//if Pressed button is pressed
				//{
					STOP = 1;			//then setting is done!
					
				//}	
			}
	
			if (bit_is_clear(PIND, PD6))//if Right button is pressed
			{
				_delay_ms(DEBOUNCE_TIME);
				if (bit_is_clear(PIND, PD6))//if Right button is pressed
				{
					++Position;
					//PORTA^=(0xF2);
					if (Position>=7)
						Position = 7;
				}					
			}
		
			if (bit_is_clear(PIND, PD1))//if Left button is pressed
			{
				_delay_ms(DEBOUNCE_TIME);
				if (bit_is_clear(PIND, PD1))//if Left button is pressed
				{
					--Position;
					//PORTA^=(0x2F);
					if (Position<=0)
						Position = 0;
				}					
			}
		
			if (bit_is_clear(PIND, PD3))//if Up button is pressed
			{
				_delay_ms(DEBOUNCE_TIME);
				if (bit_is_clear(PIND, PD3))//if Up button is pressed
				{
					//PORTA^=(0x0F);
					switch (Position)
					{
						case 0:	++t.hour;
								//ConvertToBCD(t.hour,t.minute);	
								//Show time to displays;
								break;
						case 1:	++t.minute;
								//ConvertToBCD(t.hour,t.minute);	
								//Show time to displays;
								break;
						case 2:	++t.date;
								//ConvertToBCD(t.date,t.month);	
								//Show time to displays;
								break;
						case 3:	++t.month;
								//ConvertToBCD(t.date,t.month);	
								//Show time to displays;
								break;
						case 4:	
								++Y;
								t.year = 1000*Y;
								//ConvertToBCD(t.year/100,t.year% 100);	
								//Show time to displays;
								break;
						case 5:	
								++y;
								t.year = (1000*Y+100*y);
								//ConvertToBCD(t.year/100,t.year% 100);	
								//Show time to displays;
								break;
						case 6:	
								++X;
								t.year = (1000*Y+100*y+10*X);
								ConvertToBCD(t.year/100,t.year% 100);	
								//Show time to displays;
								break;
						case 7:	
								++x;
								//t.year = (1000*Y+100*y+10*X+x);
								ConvertToBCD(t.year/100,t.year% 100);	
								//Show time to displays;
								break;
						case 8:	++alarm.hour;
								//ConvertToBCD(alarm.hour,alarm.minute);	
								//Show time to displays;
								break;
						case 9:	++alarm.minute;
								//ConvertToBCD(alarm.hour,alarm.minute);	
								//Show time to displays;
								break;
					}					
				}					
			}	
		
			if (bit_is_clear(PIND, PD0))//if Down button is pressed
			{
				_delay_ms(DEBOUNCE_TIME);
				if (bit_is_clear(PIND, PD0))//if Down button is pressed
				{
					//PORTA^=(0x02);
					switch (Position)
					{
						case 0:	--t.hour;
								//ConvertToBCD(t.hour,t.minute);	
								//Show time to displays;
								break;
						case 1:	--t.minute;
								//ConvertToBCD(t.hour,t.minute);	
								//Show time to displays;
								break;
						case 2:	--t.date;
								//ConvertToBCD(t.date,t.month);	
								//Show time to displays;
								break;
						case 3:	--t.month;
								//ConvertToBCD(t.date,t.month);	
								//Show time to displays;
								break;
						case 4:	
								--Y;
								t.year = 1000*Y;
								//ConvertToBCD(t.year/100,t.year% 100);	
								//Show time to displays;
								break;
						case 5:	
								--y;
								t.year = (1000*Y+100*y);
								//ConvertToBCD(t.year/100,t.year% 100);	
								//Show time to displays;
								break;
						case 6:	
								--X;
								t.year = (1000*Y+100*y+10*X);
								//ConvertToBCD(t.year/100,t.year% 100);	
								//Show time to displays;
								break;
						case 7:	
								--x;
								t.year = (1000*Y+100*y+10*X+x);
								//ConvertToBCD(t.year/100,t.year% 100);	
								//Show time to displays;
								break;
						case 8:	--alarm.hour;
								//ConvertToBCD(alarm.hour,alarm.minute);	
								//Show time to displays;
								break;
						case 9:	--alarm.minute;
								//ConvertToBCD(alarm.hour,alarm.minute);	
								//Show time to displays;
								break;
					}					
				}					 				
			}	
		} 
	
		//PORTA=0x03;
		t.second = 0;
		//ConvertToBCD(t.hour,t.minute);	//Show time to displays;
		SET_TIME_FLAG = 1;	
		SET_ALARM_FLAG = 1;
		GICR|=(1<<INT1);				//Enable external interrupt INT1 so now "UP" toggles ALARM ON
		TCCR2 |= (1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is wrong here and the interrupt fires only once?
I don't get it for the last 5 hours, I've tried everything...

int main(void)
{    
	//Initialize port
    PortsInit();
	//set_sleep_mode(SLEEP_MODE_PWR_SAVE);
    //Initialise the timer2
	t.year = 2012;
	t.month = 7;
	t.date = 17;
    RTCInit();
    
    State = 0;
	STOP = 0;
	RUNNING = 1;
	SETTING = 0;
	sei();

	while(1)
	{	
    
		while(RUNNING)
		{
			//PORTA=(0x33);
			//sei();
			//PORTA=0xF0;

		}
	
		while(SETTING)
		{
			cli();
			TCCR2 = 0;			//Stop Timer2
			//up and down must change value of digit
			//while left and right change the selected digit
			//The proper sequence is 
			//1. Hour_high
			//2. Hour_low
			//3. Min_high
			//4. Min_low
			//5. Alarm ON or OFF
			//Press down finishes the setting procedure.
	
			Position = 0;
		

			while (!STOP) 
			{
			
				if (bit_is_clear(PIND, PD2))//if Pressed button is pressed
				{
					
					_delay_ms(DEBOUNCE_TIME);
					if (bit_is_clear(PIND, PD2))//if Pressed button is pressed
					{
						PORTA=(0x0F);
						STOP = 1;			//then setting is done!
					}	
				}
	
				if (bit_is_clear(PIND, PD6))//if Right button is pressed
				{
					_delay_ms(DEBOUNCE_TIME);
					if (bit_is_clear(PIND, PD6))//if Right button is pressed
					{
						++Position;
						//PORTA^=(0xF2);
						if (Position>=7)
							Position = 7;
					}					
				}
		
				if (bit_is_clear(PIND, PD1))//if Left button is pressed
				{
					_delay_ms(DEBOUNCE_TIME);
					if (bit_is_clear(PIND, PD1))//if Left button is pressed
					{
						--Position;
						//PORTA^=(0x2F);
						if (Position<=0)
							Position = 0;
					}					
				}
			} 
	
			//PORTA=0x03;
			t.second = 0;
			//ConvertToBCD(t.hour,t.minute);	//Show time to displays;
			SET_TIME_FLAG = 1;	
			SET_ALARM_FLAG = 1;
			GICR|=(1<<INT1)|(1<<INT0);				//Enable external interrupt INT1 so now "UP" toggles ALARM ON
			GIFR|=(1<<INTF1)|(1<<INTF0);	//Clear Flag;
			RTCInit();						//Start Timer2
			RUNNING = 1;
			SETTING = 0;
			sei();
//			PORTA=(0xFF);
		}

	}
	return 0;          
}


ISR(INT0_vect)
{
	//PORTA=(0xFF);
	SETTING = 1;
	RUNNING = 0;
}

ISR(INT1_vect)
{
	PORTC ^= (1 << PC2);		//Toggle ALARM ON led
	ALARM_ON_FLAG ^= (1<<0);	//Toggle ALARM FLAG
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry I've got it

I needed to re-make

STOP=0;
			t.second = 0;
			//ConvertToBCD(t.hour,t.minute);	//Show time to displays;
			SET_TIME_FLAG = 1;	
			SET_ALARM_FLAG = 1;
			GICR|=(1<<INT1)|(1<<INT0);				//Enable external interrupt INT1 so now "UP" toggles ALARM ON
			GIFR|=(1<<INTF1)|(1<<INTF0);	//Clear Flag;
			RTCInit();						//Start Timer2
			RUNNING = 1;
			SETTING = 0;
			STOP = 0;
			sei();
			PORTA=(0x0F);
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
         RUNNING = 1;
         SETTING = 0;
         STOP = 0;

If those are mutually exclusive states (and I suspect they are) then you'd be far better off with a single state variable such as:

typedef enum {
  STOP,
  SETTING,
  RUNNING
} state_type;

state_type state = STOP;

switch (state) {
 case STOP: // do some stuff
            state = SETTING;
            break;

 case SETTING: // do some stuff
            state = RUNNING;
            break;

 case RUNNING: // do some stuff
            state = STOP;
            break;
}

I'm not saying you have to use a switch(), though it's quite common when implementing a "steta machine" which is what I think you are writing here. But you can just treat "state" as a normal varibale (it is!) but one that instead of assigning 1, 37, 59 to it you can assign STOP, SETTING, RUNNING to it.

You may want to read about enum's in your C manual if you don't already know about them.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks