0
\$\begingroup\$

I've made a controller board of my own for a school project based on an ATMEGA2560-16AU mcu, and I'm working on programming it with AVR. I want to use PWM for motor control and external interrupts to read encoder pulses and positioning sensors. I've followed this tutorial and the datasheet to write the code below for testing and have setup a similar stand, with two led's connected but I use an induction sensor instead of a button (same effect really, I also tested with a button). A weird problem occurs though, namely that when I set either one of the led's (in this case PA0) to blink at 1.5 seconds intervals in the main loop and the other to toggle only when an external interrupt triggers, whenever I try to toggle PA1 with the sensor only PA0 toggles from the main loop somehow. I have no idea why this happens.

Any help is much appreciated.

EDIT 1: I've updated the code a bit.

#define F_CPU 16000000UL #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> int main(void) { DDRE &= ~((1 << DDE4) | (1 << DDE5) | (1 << DDE6) | (1 << DDE7)); PORTE &= ~((1 << PE4) | (1 << PE5) | (1 << PE6) | (1 << PE7)); DDRA |= (1 << DDA0); DDRA |= (1 << DDA1); //SETUP EXTERNAL INTERRUPTS cli(); EICRB |= (1 << ISC40); EIMSK |= (1 << INT4); sei(); while (1) { PORTA ^= (1 << PA0); _delay_ms(1500); } return(0); } ISR(INT4_vect){ if ((PINE & (1 << PINE4))) { PORTA |= (1 << PA1); } else { PORTA &= ~(1 << PA1); } } 

Principle schematic of how the sensor/button is wired

\$\endgroup\$
7
  • \$\begingroup\$ Are you saying that PA0 toggles correctly every 1.5 seconds, but PA1 never does? Or that when an interrupt occurs, PA0 toggles instead of PA1? Also, pictures of your schematic and setup would be very helpful \$\endgroup\$ Commented Jan 17 at 19:04
  • \$\begingroup\$ Well, sort of both. So PA0 toggles correctly every 1.5 seconds. PA1 never does anything though it's supposed to toggle when I activate the sensor, however when I do activate the sensor PA0 toggles and not PA1, and I can see that because I can toggle it even if it's in the delay, meaning it does trigger the ISR, but not for PA1. \$\endgroup\$ Commented Jan 17 at 19:21
  • \$\begingroup\$ Well then I'm back to pictures would be very helpful. \$\endgroup\$ Commented Jan 17 at 20:04
  • \$\begingroup\$ You can modify your ISR to check if you're correctly toggling PA1 based on the sensor state. You can add some debugging steps like toggling a different LED when the interrupt triggers or printing some state. \$\endgroup\$ Commented Jan 17 at 21:08
  • \$\begingroup\$ @liaifat85 if you would look at the tutorial I linked in my post, you'll see that's exactly what I've been trying to do. My setup is the same essentially. It's clear to me that my ISR is triggered and enabled, but I don't understand why the other led is powered when I trigger the interrupt and not the one I set in the ISR. \$\endgroup\$ Commented Jan 17 at 21:46

2 Answers 2

0
\$\begingroup\$

The code works exactly as it is written on each line and and what reads in the comments. There is no bug there. You only expect it to work in some other way.

You enable interrupts only on rising edge.

When interrupt triggers, it does not toggle anything, it simply sets PA1 output high or low based on what was read from PE4.

If your interrupt source is PE4, the every time there is a rising edge, interrupt triggers, and code sets PA1 low because PE4 is high.

If there is a falling edge on PE4, no interrupt happens, PE4 is not read, not PA1 state is not set low or high.

There is also a rarely happening race condition. When main code is toggling the PA0 with a read-modify-write operation, an interrupt may happen between read and write, and thus main code will restore the old PA0 state right after interrupt updated it with a read-modify-write operation. The main code and interrupt should take this kind of problem into account somehow, but for this example it should not matter.

\$\endgroup\$
7
  • \$\begingroup\$ I've changed the interrupt sense control to any logical change for all pins (I'm gonna need to use all the pins, that's why I activated all) and I've also reversed the led toggle order in the ISR function so that it would toggle on when the interrupt is requested and it reads 1 from PE4. Same results as before though, no changes. \$\endgroup\$ Commented Jan 17 at 20:35
  • \$\begingroup\$ @hdaniu I cannot see these changes to verify they are correct. Also if you don't define interrupt vectors for the other interrupts you enable, the code will reset on any undefined interrupt you enable. \$\endgroup\$ Commented Jan 17 at 20:42
  • \$\begingroup\$ I've updated the code above, but again same results as before, even if I enable only INT4. Is it possible that I'm missing something in my Microchip Studio buildchain or settings? Did I have to configure anything after installation? (I selected the right mcu for this project) \$\endgroup\$ Commented Jan 17 at 21:10
  • \$\begingroup\$ @hdaniu OK so can you even read the pin correctly in main loop? What you have connected to PE4? Pushbutton? Pull resistor? Something else? \$\endgroup\$ Commented Jan 17 at 21:31
  • \$\begingroup\$ yes, I can read the pin correctly in the main loop, and even set any of the leds to high or low just like in the ISR code. I use an induction sensor powered at 12V that's separated by an optocoupler on my prototype board, essentially works like a pushbutton (the electronics are working). However I also tested on an arduino mega 2560 with a pushbutton. Same results on both boards, which leads me to think that the issue is software related. \$\endgroup\$ Commented Jan 17 at 21:43
0
\$\begingroup\$

Alright, so I figured I'd answer this for anyone busting their heads with the same kind of problems. So interrupts and USART weren't working properly, but eventually I figured out it was a fuse related problem, namely, I had the BOOTRST bit of the HIGH fuse set and because of this my board was resetting. I changed my HIGH fuse from 0xD8 to 0xD9 to disable that bit and afterwards everything worked properly. Take this answer with a grain of salt as I still don't know much about fuses and setting them wrong can brick your board, but this was the solution in my case.

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.