Triggering ISR(PCINT0_vect) Interrupts.

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

Hi i am doing a small test app learning how to use External Interrupts

and no mater how much different things i did to this code while debugging i can't trigger any of the 2 interupts

this code is meant for ATmega48 if that maters.

#define F_CPU 1000000UL // 1MHz;

#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>            // has to be added to use uint8_t
#include <avr/interrupt.h>

volatile unsigned int res, i;
volatile uint8_t port_b_history = 0xFF, port_c_history=0xFF; // start whith pulled-up pins ;

int main(void)
{
	DDRB = 0xFF;  //remove after debug
	PORTB = 0xFF; // PULL-UP enabled
	DDRB = 0x00;  // PortB as input

	DDRC = 0xFF;  //remove after debug
	PORTC = 0xFF; // PULL-UP enabled
	DDRC = 0x00;  // PortB as input

	DDRD = 0xFF;  // PortD as output

	PCIFR = 0x00;
	PCICR |= (1 << PCIE0);     // set PCIE0 to enable PCMSK0 scan (PORTB)
	PCICR |= (1 << PCIE1);     // set PCIE0 to enable PCMSK1 scan (PORTC)

        PCMSK0 |= (1 << PCINT1);   // set PCINT1 to trigger an interrupt on state change (pin pb1 (SW1 button))
	PCMSK0 |= (1 << PCINT4);   // set PCINT4 to trigger an interrupt on state change (pin pb4 (SW4 button))

	PCMSK1 |= (1 << PCINT10);   // set PCINT10 to trigger an interrupt on state change (pin pc2 (SW2 button))
	PCMSK1 |= (1 << PCINT13);   // set PCINT13 to trigger an interrupt on state change (pin pc5 (SW5 button))

        sei();		// turn on interrupts

	while(1)
	{
		//Just some logic to see that the process is alive
		if (PORTD == 0)
		{
			PORTD = 1;
		}
		else
		{
			PORTD = 0;
		}
	}
}

ISR (PCINT0_vect) // triggers by state change on PortB
{
	uint8_t changed_bits;

	changed_bits = PINB ^ port_b_history;
        port_b_history = PINB;

	if((changed_bits & (1<<PINB1))||(changed_bits & (1<<PINB4)))
	{
		if( (PINB & (1 << PINB0)) == 1 )
		{
			/* LOW to HIGH pin change */
		}
		else
		{
			/* HIGH to LOW pin change */
			res = 0;
			for (i=7; i>=0; i--)
			{
				res |= (1<<i);
				PORTD = res;
				//_delay_ms(3000);
			}
		}
	}
}

ISR (PCINT1_vect) // triggers by state change on PortC
{
	uint8_t changed_bits;

	changed_bits = PINC ^ port_c_history;
        port_c_history = PINC;

	if((changed_bits & (1<<PINC2))&&(changed_bits & (1<<PINC5)))
	{
		if( (PINC & (1 << PINC0)) == 1 )
		{
			/* LOW to HIGH pin change */
		}
		else
		{
			 /* HIGH to LOW pin change */
			res = 0;
			for (i=7; i>=0; i--)
			{
				res &= ~(0<<i);
				PORTD = res;
				//_delay_ms(1500);
			}
		}
	}
}

 

This topic has a solution.
Last Edited: Mon. Dec 11, 2017 - 01:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

scrap the crazy irq code for now...in the irq set a pin high, wait, then set it low

Then you'll be sure the irq's are triggering.

 

note your irq signals will be coming in on portd (into==pd2, int1=pd3), so set portd as an input, or there will be no reaction to your signal

 

Also, note portd is only setting 1 bit (pd0) hi/lo in main

When in the dark remember-the future looks brighter than ever.

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

avrcandies wrote:

note your irq signals will be coming in on portd (into==pd2, int1=pd3)

 

sorry can you tell me why?

 

the thing is this is an assignment i'm doing and by it there is 8 led's connected to portD,

2 buttons to portB and 2 buttons to portC, if any of the portB buttons is pressed there

should be led's lighting up 1 by 1, and if both buttons of portC pressed they should dim down 1 by 1.

 

the thing is i don't understand why the IST is not triggering

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

sorry can you tell me why?

 

Oh I see, you are using pin change irq's, OK...make sure your signals are connected to the pins as noted & that you measure the voltage at the pin going hi/lo as the button is pushed (use a meter).

 

Remember that when you push the button, it may cause rapid multiple pulses (button bounce).

For testing, simply try making one IRQ set a pin high & a different IRQ set the same pin low..once that works...move ahead with more complexity

 

 

 

 

When in the dark remember-the future looks brighter than ever.

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

Thanks for your input in the end i did scrap the irq crazy logic, it didn't work properly anyway,

checked irq's workability by simple pin change - it didn't work so i scraped the code went back

to youtube (this video https://www.youtube.com/watch?v=...) went step by step and 

got the new code working i still didn't understand where was the problem i'll do traicing of it later

and i'll post the finished code a bit later hope that will help someone.

By the way thanks again for your comments.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ye so this is the final result that ended up working for me

#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 1000000UL
#include <util/delay.h>

#define LED_ON	PORTB |= (1<<PB0)
#define LED_OFF	PORTB &= ~(1<<PB0)

#define SWITCH1_PRESSED !(PINB & (1<<PB1))
#define SWITCH4_PRESSED !(PINB & (1<<PB4))

#define SWITCH2_PRESSED !(PINC & (1<<PC2))
#define SWITCH5_PRESSED !(PINC & (1<<PC5)) 

volatile unsigned int i; 

//Interrupt Service Routine for PCINT0
ISR(PCINT0_vect)
{
	if (SWITCH1_PRESSED || SWITCH4_PRESSED)
	{
		for (i=8; i>0; i--)
		{
			//if for some reason some leds are already lightened up skip this cycle
			if (!(PORTD & (1<<(i-1)))){
				if (i<8)
				{
					//_delay_ms(3000);
				}
				PORTD |= (1<<(i-1));
			}
		}
	}
}

ISR(PCINT1_vect)
{
	if (SWITCH2_PRESSED && SWITCH5_PRESSED)
	{
		for (i=8; i>0; i--)
		{
			//if for some reason some leds are already dimmed down skip this cycle
			if (PORTD & (1<<(i-1))){
				if (i<8)
				{
					//_delay_ms(1500);
				}
				PORTD &= ~(1<<(i-1));
			}
		}
	}
}	

int main(void)
{
	//SETUP FOR PORT B
	DDRB = 0xFF;	// to be removed 3 lines of code needed to simulate pin-up
	PORTB = 0xFF;	//to be removed
	DDRB = 0x00;	//to be removed

	DDRB |= (1<<DDB0);
	PORTB &= ~(1<<DDB1);
	PORTB &= ~(1<<DDB4);

	//SETUP FOR PORT C
	DDRC = 0xFF;	//to be removed 3 lines of code needed to simulate pin-up
	PORTC = 0xFF;	//to be removed
	DDRC = 0x00;	//to be removed 

	PORTC &= ~(1<<DDC2);
	PORTC &= ~(1<<DDC5);

	//PortD as output
	DDRD = 0xff;

	//set the 1st and 4th bit to trigger PCINT0
	PCMSK0 |= (1<<PCINT1);
	PCMSK0 |= (1<<PCINT4);
	//set the 2nd and 5th bit to trigger PCINT1
	PCMSK1 |= (1<<PCINT10);
	PCMSK1 |= (1<<PCINT13);

	PCICR |= (1<<PCIE0);
	PCICR |= (1<<PCIE1);

	sei();				//Enable Global Interrupt

    while(1)
    {
		// Logic in here is just to keep the endless loop going for debugging purposes
		if (!(PORTB & (1<<PB0)))
		{
			LED_ON;
		}
		else
		{
			LED_OFF;
		}
    }
}

 

Last Edited: Mon. Dec 11, 2017 - 01:14 PM