Go Down

Topic: Confusion about none working Interrupt 2 on a ATMega644P/1284P (Read 6281 times) previous topic - next topic

1studio1

Bit of advice from the wise please,

I want to be able to use the external interrupt pins on a 40 pin PDIP ATMega such as the 1284p / 644p/pa uController in a standalone project.

What I have is three inputs wired individuality to digital 10, 11 and 2 (INT0(16), INT1(17) and INT2(3)). For the sake of simplicity we'll call them simple tactile buttons (GND when pushed) with pullup resistors (10k) going to VCC.

I should point out at before going further that this works on a Arduino Mega 2560 board ok in both the hardware set up and software - hence my confusion.

For some reason the ISR are being called for INT0 and INT1 but not on INT2. I have wired the test circuit that goes into INT2 into INT0 and the hardware circuit is working as in it triggers on INT0 as expected but the same circuit going to INT2 does not even trigger ( i put a temporary digitalWrite(27,HIGH) to a C.Ltd LED at the beginning of the ISR as a visual que)

I have the attachInterupt(ISR,FALLING) for all int calls .

I also tested that I can use the PIN D2 as a output and input in the usual manner and it works ok. I even tried a different ATMega Chip just in case.

Is there a fuse setting that needs to set so that INT2 works? Mine are currently set to Low=FF, HIGH=DA Ext=FF (note: I need JTAG OFF as I am using PORTC pins Digital 18,19,20 and 21). I see in the data sheet there is a Clock output on PORTB1 but surely that is not what I need turned on is it?

Many thanks in advance.

Steve  
PS I am uploading via an ISP if that is relevant

JChristensen

Well normally you'd probably get asked to post your code, but if it were me, I'd write a minimal sketch to exercise a single interrupt, prove to myself that it works on INT0 and INT1 and then try it on INT2.

1studio1

Yep Jack, That's what I did - it's a bit room 101 but here is the code
Code: [Select]

const int MotorLED1 = A5;
const int MotorLED2 = A7;
const int MotorLED3 = 13;

void setup()
{
pinMode(MotorLED1,OUTPUT);
pinMode(MotorLED2,OUTPUT);
pinMode(MotorLED3,OUTPUT);

attachInterrupt(0, Motor1, FALLING);
attachInterrupt(1, Motor2, FALLING);
attachInterrupt(2, Motor3, FALLING);
}

void loop()
{
delay (300);
digitalWrite(MotorLED1, LOW);
digitalWrite(MotorLED2, LOW);
digitalWrite(MotorLED3, LOW);
}

void Motor1()
{
    digitalWrite(MotorLED1, HIGH);
}
void Motor2()
{
    digitalWrite(MotorLED2, HIGH);
}
void Motor3()
{
    digitalWrite(MotorLED3, HIGH);
}

JChristensen

I'm just getting started with the 1284P myself but I do happen to have one right here, let me play a bit with it.

Which core are you using?

1studio1

Sorry Jack, do you mean what chip core? - it's a ATMega644p and a ATMega644PA have 3 of the later direct from Atmel and 1 of the former from a h/ware supplier which was meant to be pre bootloaded but wasn't as confirmed by AVRdude - not that that matters now I have a h/ware ISP and to be honest it runs better without the bootloader haha!

Thanks for having a look / play really appreciate it. boards.txt is attached

Regards

Steve

JChristensen

Hi Steve,

By core I meant the Arduino "core" code ... I'm using maniacbug's mighty-1284p core.

Anyway the following sketch works fine for INT0, 1 or 2. I'm just using a 1Hz square wave from an RTC as the signal to the interrupt pin, and toggling an LED.

Code: [Select]
const uint8_t ledPin = 7;

void setup(void)
{
    pinMode(ledPin, OUTPUT);
    attachInterrupt(2, intHandler, FALLING);
}

void intHandler(void)
{
    static bool ledState;
   
    digitalWrite(ledPin, ledState = !ledState);
}

void loop(void)
{
}

1studio1

Hi Jack,

umm Yes your (neater) code does a similar thing to the rubbish one I wrote :), I can't use that core as I have a USBtinyISP and I am not sure it will work with the 644 and can't get my Atmel Dragon working as Studio won't run at present (Atmel technical are working out why for me at the moment).

The core I do have is a modified sanduino, which seems old news from what I can see on the net. but at least it works ???? well maybe not as we might be finding out. Out of the box I had to edit it to use the 644P properly as it left the Jtag enabled and I need those pins.

Might it be a fuse setting?

Steve

JChristensen

I get mixed results using the USBtinyISP with the 1284P. Sometimes it seems to work, but I usually get an error message as well. Others here have reported better results.

BUT that's with a 1284P, if you have a 644P I would definitely give it a try.

retrolefty

I've used both the USBtiny and a cheap $5 Asian E-bay usbasp programmer to burn bootloaders and sketches to both 644P and 1284P chips. It always works but the USBtiny often reports a verify error upon completion but it appears to be a 'false positive' as the resulting bootloader and fuses always end up being fine. The USBasp has never reported an error. And I'm pretty sure I even used a arduino board running the arduinoISP sketch to burn a bootloader to a 1284P with no problems seen.

Lefty

larryd

Quote
And I'm pretty sure I even used a arduino board running the arduinoISP sketch to burn a bootloader to a 1284P with no problems seen.

I do this regularly with success.
No technical PMs.
If you are asked a question, please respond with an answer.
If you are asked for more information, please supply it.
If you need clarification, ask for help.

1studio1

Well ISP aside, I'm gonna try the USBtiny with Jacks suggestion. Might just see if the fuse settings change anything, but I have downloaded the files mentioned.

Those that have used ISP successfully.. have you run sketches that use all three INTs without problems like Jack did? if you have what (as I know it now - thanks Jack) Core do/did you use (link if pos.) I am not keen on the sandy thing as it seems a bit hackerish rather than proven main stream ( I am inventing new words as well now) :).

I have looked though the pins_xxx.h files and other trying to see if there is something obvious to change but to no avail.

I would like to try and keep this in the Arduino spirit as learning another language for this project would not be time constructive, but I fully intend to switch over on other projects (current firmware is some (streamlined) 46k so pretty large by most sketch standards.) but I do like the arduino IDE because of its basic and non-techy approach to C - its really good at making our hobby popular and the more peeps that use it the better as it seems to NOT carry a frightening inroad than other languages do., but it is fair to say once you get into this stuff you do get drawn in, so well done Arduino for bring a seemingly difficult subject to the masses. - oww sorry advert over. :)

Thanks guys, Having not tried the suggestions yet  I am no further forward as of tonight (UK time) but have some options to explore in the morning which is encouraging.

Steve

1studio1

Well I have tried one or two things and put in an order for some ATMega1284P's (+ a couple of 2560s) the reason being there seems far more support for these MCUs than the 644PA.

Anyways. after much poking and prodding around I eventually gave up on INT2 and added in PinChangeInt and to my surprise this was really easy and gave me back the other interrupts I could have lived without but were useful (originally this project was written for a 2560 MEGA and I really need it to go stand alone). So in case others need it; the bits I added to make it work are:
Code: [Select]

#define NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts
#define NO_PORTD_PINCHANGES // to indicate that port d will not be used for pin change interrupts
#include <PinChangeInt.h> // you need to download the repository and install in libraries folder
..........
const int selectPin = 2;                      //Joystick and Rotary encoder press button
.........
void setup()
{
.........
  pinMode(selectPin, INPUT); digitalWrite(selectPin, HIGH);
  PCintPort::attachInterrupt(selectPin, toggle, FALLING);
.........
}
void loop() { /*some code*/ }
void toggle() { /*ISR code*/ }


And that solved it.. Ok so maybe it's not the most elegant way but Jack sparked a thought in something he wrote and I had a light bulb moment as I sat with my first cup of coffee this morning.

I would still like to know how to get this working using attachInterrupt though - just for the sake of knowing :)

Thanks guys. It's great to have so many great engineers around to bark ideas at.

Steve

JChristensen

Steve, glad to hear you made some progress. I'll add a couple things. First, the 644PA is basically the same chip as the 1284P, just with less memory. They share the same datasheet. I think the 644PA lacks the second 16-bit timer (Timer/Counter3) but I think that's the only difference. So given that, code that works on one should work on the other. (The price difference between the two is less than a dollar, so unless I was building dozens or hundreds of copies of something, I'd just stick with the 1284P.)

Second, I hardly ever use attachInterrupt(), reason being it is quite straightforward to set the registers directly. This code is equivalent to what I posted above. It just uses INT2 to toggle an LED. Maybe give that approach a try.

Code: [Select]
const uint8_t ledPin = 7;

void setup(void)
{
    pinMode(ledPin, OUTPUT);
    EICRA = _BV(ISC21);          //external interrupt on falling edge
    EIFR = _BV(INTF2);           //clear the interrupt flag (setting ISCnn can cause an interrupt)
    EIMSK = _BV(INT2);           //enable external interrupt
}

void loop(void)
{
}

ISR(INT2_vect)
{
    static bool ledState;
    digitalWrite(ledPin, ledState = !ledState);
}

1studio1

Hi Jack,

Yes you are absolutely right. there seems more support for the 1284p than it's smaller brother. I just saw the 644p advertised on a suppliers site advertised as a go between the 328 and 2560 so thought I would give it a try. but in hindsight should have opted to get some 1284's which I have now done.

After reading the datasheets (most of which went over my head) I realised that INT2 is not enabled by default and you need to set the port up. even then it only responds to a changing edge not a rising or falling like INT0 and INT1 (Can't find the web pages where I read that :( )

I'll certainly have a go with your code once I get Studio working lol - Atmel support sent me a patch today but that won't even install so the issue is on giong. I want to get more into this type of programming as I can see some advantages - like it doesn't limit you to using Arduino IDE  (which is still a great tool.

Thanks for your help and it has been great chatting with you.

All the Best Steve


CrossRoads

Quote
even then it only responds to a changing edge not a rising or falling like INT0 and INT1 (Can't find the web pages where I read that  )


Quote
13.2.1 EICRA - External Interrupt Control Register A

The External Interrupts 2 - 0 are activated by the external pins INT2:0 if the SREG I-flag and the corresponding interrupt mask in the EIMSK is set. The level and edges on the external pins that activate the interrupts are defined in Table 13-1.
Table 13-1
ISCn1 ISCn0 Description
0 0                The low level of INTn generates an interrupt request
0 1                Any edge of INTn generates asynchronously an interrupt request
1 0                The falling edge of INTn generates asynchronously an interrupt request
1 1                The rising edge of INTn generates asynchronously an interrupt request

Note: 1. n = 2, 1 or 0.
When changing the ISCn1/ISCn0 bits, the interrupt must be disabled by clearing its Interrupt Enable bit in the EIMSK Register. Otherwise an interrupt can occur when the bits are changed.

There is nothing to indicate INT2 is any different than INT1 or INT0
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up