problem in work with two external interrupt in atmega8

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include 
#include 
#include 
#include 
#include "integer.h"

#define DENTRY      2
#define DEXIT       3

WORD t0owf=0;
BYTE traffic_status=0,traffic_timer_start=0,traffic_timer=0,sec=0,min=0,ir1=0,ir2=0;

void inline InitPORTs(void);
void inline InitEXTInt0(void);
void inline InitEXTInt1(void);
void inline InitTimer0(void);
void inline Entry_Exit_Detection(void);

int main(void)
{
	InitPORTs();
	InitEXTInt0();
	InitEXTInt1();
	//InitTimer0();
	sei();
    while(1)
    {
		Entry_Exit_Detection();
			
    }
	return 0;
}

void inline InitPORTs(void)
{
	DDRC=0x07;
	PORTC=0x00;
	DDRD=0x00;
	PORTD=0x00;
}

void inline InitEXTInt0(void)
{
	GICR |= (1<<INT0); //sbi(GICR,INT0);
	MCUCR &= ~((1<<ISC01) | (1<<ISC00));
	MCUCR |= 0x03;
	//EXTINT_LEVEL_LOW			0x00		 Trigger on low level
	//EXTINT_EDGE_ANY			0x01		 Trigger on any edge
	//EXTINT_EDGE_FALLING		0x02		 Trigger on falling edge
	//EXTINT_EDGE_RISING			0x03		 Trigger on rising edge
	
}

void inline InitEXTInt1(void)
{
	GICR |= (1<<INT1); //sbi(GICR,INT1);
	MCUCR &= ~((1<<ISC11) | (1<<ISC10));
	MCUCR |= 0x03<<2;
	//EXTINT_LEVEL_LOW			0x00<<2		 Trigger on low level
	//EXTINT_EDGE_ANY			0x01<<2		 Trigger on any edge
	//EXTINT_EDGE_FALLING		0x02<<2		 Trigger on falling edge
	//EXTINT_EDGE_RISING			0x03<<2		 Trigger on rising edge
}

void inline InitTimer0(void)
{
	
	// Timer0 settings: ~ 16384 ticks (2.048 ms)
	TCCR0 = (1<<CS01) | (1<<CS00); // prescaler = 64
	// init counter
	TCNT0 = 0;
	TIMSK |= (1<<TOIE0); // Timer0 Overflow Interrupt Enable
	
}

void inline Entry_Exit_Detection(void){
	
	if (ir1 && !ir2)
	{
		while(!ir2);
		_delay_ms(200);
		traffic_status=DENTRY;
		ir1=0;
		ir2=0;
	}
	
	if (!ir1 && ir2)
	{
		while(!ir1);
		_delay_ms(200);
		traffic_status=DEXIT;
		ir1=0;
		ir2=0;
	}
	
	 if (traffic_status==DENTRY){
		 PORTC &= ~(1 << PC1);
		 PORTC |= 1 << PC0;
		 
	 }
	 
	 if (traffic_status==DEXIT){
		 PORTC &= ~(1 << PC0);
		 PORTC |= 1 << PC1;
		 
	 }

	
}

ISR(INT0_vect)
{
	ir1=1;
}

ISR(INT1_vect)
{
	ir2=1;
}



// Timer0 Overflow
ISR(TIMER0_OVF_vect)
{
	// reinit counter
	TCNT0 = 0;
	t0owf ++;
	if (t0owf==250){
		//PORTC ^= 1 << PORTC2;
		PORTC &= ~(1 << PC2);
	}
	if (t0owf==500){
		t0owf=0;
		if (traffic_timer_start==1)	traffic_timer++;
		sec++;
		PORTC |= 1 << PC2;
	}
	if (traffic_timer==255) traffic_timer=0;

	if (sec==60){
		sec=0;
		min++;
	}
	if (min==60){
		min=0;
	}
}

hello
In practice, only one of interrupts works and the program is locked in

while(!ir1);

or

while(!ir2);

why??????????????

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

http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_volatile

Do at least a minimum amount of searching, and many question marks does not speed things up...

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

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

thnx meolsen.

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

If this was a real security system, you wouldn't feed the inputs to interrupts. You would have a timer isr to read the inputs at a regular rate and debounce them. Sitting in while loops waiting for things to happen is not a good idea.
The root cause of your problem is that you have no declared the variables shared with isrs as volatile. I've written a couple of tutorials that you'll find in the tutorial section :
The traps when using interrupts
Multi-tasking part 1

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

I wrote this one about volatile and why you need it:

https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=97382

(can I just say what a PLEASURE it is to use Captcha?)

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

thnx kartman
but But I've added a timer to this code

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