External Interrupt Atmega32

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

Hey guys, I'm working on a project involving encoders and I'm trying to get an external interrupt going. This should be a pretty simple task, I feel like I'm missing something really key. I have a stepper drive sequence in the section of code below the conditional loop, since I'm not running any sort of debugguer I have just put the conditional loop above that will essentially be skipped if that variable is set in the ISR(This is just to test if its getting into the ISR). If I remove the conditional loop the motor runs fine, right now I have a little push button connected to PORTD.2 for testing purposes. I have put a scope on and its going from 0-5v when I press it. Any help would be awesome.

#include 
#include 
#include 
#include 

//Global Variables
int t=0;
float signal;

int main(void)
{
int step, rot;

init();
step = 10;
rot = 1000;
sei();

do
{
}while(t==0);

while(1)
{
	//	     +-+-
	PORTC =0b00111000; //0
	_delay_ms(step);
	PORTC =0b00111010; //1
	_delay_ms(step);
	PORTC =0b00110010; //2
	_delay_ms(step);
	PORTC =0b00110110; //3
	_delay_ms(step);
	PORTC =0b00110100; //4
	_delay_ms(step);
	PORTC =0b00110101; //5
	_delay_ms(step);
	PORTC =0b00110001; //6
	_delay_ms(step);
	PORTC =0b00111001; //7
	_delay_ms(step);
}
return(0);
}

ISR(INT0_vect)
{
t=1;
return(0);
}

init()
{
DDRC   =0b00111111;
MCUCSR =0b10000000;             
MCUCSR =0b10000000;
MCUCR  =0b00000011;
GICR   =0b01000000;

}

Attachment(s): 

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

Var t should be declared volatile. Have a read of my tutorial "the traps when using interrupts". Clawson also has a tutorial on the use of volatile.

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

I changed it to a volatile variable. It still doesn't work. I have looked over the code for hours now and read the datasheet, I still can't find anything. Does anyone have any idea?

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

1) You don't need return() in your ISR(), there's only ONE execution path for it to take.

2) Learn to use the named constants, so people that help you can read your code ALOT easier, binary's hard on the eyes, and checking bit positions eats up volunteers' unpaid time:

MCUCR = 1<< ISC00;// etc...

3) Use an 8 bit var for 't', since using 2 bytes is just a waste and takes more time for the var to be handled and an ISR() should be as short as possible.

4) What do you mean, "doesn't work..." ? Never gets into the ISR(), never gets out of the loop...Be specific about your problem(s) when you post.

5) You need to debounce a switch and using INTx for a switch is a bad idea because of switch bouncing. Usually one uses a timer and code that checks the switch pin like every 10ms or whatever and if it's in same changed state for a number of times ( 2-4 ), then switch has uhm...switched. I don't have the links but you can search "debounce lee" or "debounce danni" to get good code.

One thing that's most probably happening is it gets into the ISR() and GIFR bit is auto-cleared, but since it's bouncing, when it comes out of the ISR() it goes back in again...repeating some number of times until no more rising edges left and just a 'high' on the pin until you release.

Hook a PWM pin to INT0, and do some low freq. squarewave. It should trigger INT0, as a test.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

Quote:
1) You don't need return() in your ISR(), there's only ONE execution path for it to take.
And you certainly don't want to return a value.

init() 
{

This should be:

void init(void)
{

and you need to either move the definition of it before the definition of main() or put a declaration of it before main (and you need to pay attention to warnings, they are there for a reason).

Regards,
Steve A.

The Board helps those that help themselves.

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

indianajones11 wrote:

MCUCR = 1<< ISC00;// etc...


Thanks for your reply, I was taught to use binary so that's what I'm use to. When I post code on the forum I'll try my best to use this method. A question about it, is "ISC00" #define 0x00, so this essentially shifts one to the left by 0x00 and stores it in the register? So:

MCUCR = 0b00000001

Then if you go

MCUCR = 1<< ISC01;//

Wont the register then contain:

0b00000010?

So the proper way; if you want to set both bit would be:

MCUCR = 1<< ISC01 | 1<< ISC00;

indianajones11 wrote:
4) What do you mean, "doesn't work..." ? Never gets into the ISR(), never gets out of the loop...Be specific about your problem(s) when you post.

It never get into the ISR because that int never gets set, therefore it gets stuck in the top loop and the motor never runs. If I comment out the top loop the motor runs fine.

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

Quote:
So the proper way; if you want to set both bit would be:
You are correct.

"t" needs to be declared "volatile".

Regards,
Steve A.

The Board helps those that help themselves.

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

Quote:

void init(void)
{

Bingo, you the man.