Interrupt not executing all code?

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

int main(void)
{
DDRD  |= 0x40;		//set PD6 as output (BLUE)
DDRB  |= 0x02;		//set PB1 as output (GREEN)
PORTD &= ~0x40;		//turns off PD6(motor drive fet)
PORTC &= ~0x02;		//turns off PC6(motor brake fet)
PORTC |= 0x04;		//enables pullup resistor on PC2(input)

sei();				//enable global interrupts 
PCICR  |= 0x02;		//enable PCIE1 for PCINT 14-8
PCMSK1 |= 0x04;		//enable PCINT10 on PC2 (Trigger), PCMSKx enables individual pin interrupts

ADCSRA |= 0x06;  	//ADC Prescalar set to 64 - 312.5kHz@20MHz 
ADMUX  |= 0x20;		//changes ADC to 8-bit resolution, read from ADCH		
ADCSRA |= 0x80;  	//enable ADC
DIDR0  |= 0xFF;		//disables digital input buffer on ADC's when reading analog signals to save power

	while(1)
	{

	}
}

ISR(PCINT1_vect)		//interrupt vector, detects trigger
{
		if(~PINC2)
		PORTD |= (1 << 6);
		else
		PORTD &= ~(1<< 6);
}

I do not understand why this does not work, when I push a button on PINC2(pullup resistor enabled on PC2 with button wired to ground so it pulls low), PD6 will turn on, but it never turns off after I release the button. The ISR will run twice, once when the button is pressed and held for an undetermined amount of time, then again it should run when released as the ISR runs on a pin change. Any ideas? I am new with interrupts so if there is something I am not understanding that is why.

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

You seem to have PORTD.6 active high.

So your ISR() will always set PORTD.6 high.

The expression (~2) is 0b1111111111111101.

You probably want to say:

    if ((PINC & (1<<2)) == 0) 
       ...

David.

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

Quote:
The ISR will run twice, once when the button is pressed and held for an undetermined amount of time, then again it should run when released

More likely, it is running several times each time the button is pushed or released since switches bounce.

PORTC &= ~0x02;      //turns off PC6(motor brake fet)

This makes no sense, the bit mask for PC6 would be 0x40, not 0x02. Also you haven't set that bit to output (or should this really be PORTB and PB2?).

Regards,
Steve A.

The Board helps those that help themselves.

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

ThEThInG wrote:

		if(~PINC2)

Check what exactly PINC2 is defined as. I suspect it's simply the constant 2 - and you meant something like if(!(PINC&_BV(PINC2))).

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

Thanks, several of those solutions worked, I had thought that PINC2 was the register value, a flat for that bit which would indicate whether it was high or low, so I thought by using that bit I could use it to determine the status of pin 2 on port C simply by reading its value.