Changing ISR depending on pin definition

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

I was writting a code for software uart.Now here,i defined pin PB2 as rx_pin.so,pin change interrupt is ISR (PCINT0_vect).Now what i want to do is,For say,if i define PC5 as rx_pin,the ISR should automatically change to ISR (PCINT1_vect) so that i don't have to change it manually every time I change rx pin.Look at my code.Please help!

Also,look that I defined PCINT depending on rx pin no.But writting the isr like ISR (PCINT_vect) is throwing warning  'PCINT_vect' appears to be a misspelled signal handler, missing __vector prefix.

 

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

#define swuart_port PORTB
#define swuart_pin PINB
#define swuart_ddr DDRB

#define tx_pin 1
#define rx_pin 2
#define swuart_getrxpin() (swuart_pin & (1<<rx_pin))

#define baud 9600

#if baud==9600
	#define ticks2half 13 //ticks to complete half bit period
	#define tick2full 26 //ticks to complete full bit period
	#define ticks2onenhalf 39//Ticks to complete one & half bit period
#endif	

#if rx_pin==0
	#define PCINT PCINT0
#elif rx_pin==1
	#define PCINT PCINT1
#elif rx_pin==2
	#define PCINT PCINT2
#elif rx_pin==3
	#define PCINT PCINT3
#elif rx_pin==4
	#define PCINT PCINT4
#elif rx_pin==5
	#define PCINT PCINT5
#elif rx_pin==6
	#define PCINT PCINT6
#elif rx_pin==7
	#define PCINT PCINT7
#endif

#define enable_pcinterrupt() {\
	PCICR |= (1<<PCIE0);\
	PCMSK0 |= (1<<PCINT);}

#define disable_pcinterrupt() {\
	PCICR = 0X00;\
	PCMSK0 = 0X00;}

#define enable_timerinterrupt() {\
	TCCR0A |= (1<<WGM01);\
	TCCR0B |= ((1<<CS01)|(1<<CS00));\
	TIMSK0 |= (1<<OCIE0A);\
	TCNT0 = 0X00;}

#define disable_timerinterrupt() {\
	TCCR0A = 0X00;\
	TCCR0B = 0X00;\
	TIMSK0 = 0x00;}

#define clear_timerinterrupt() {\
	TIFR0 |= (1<<OCF0A);}																								

typedef enum
{
	IDLE,
	TRANS,
	RECEIVE,
	PENDING_READ
}states;

states swuart_state = IDLE;//initialize as IDLE	

volatile uint8_t swuart_bitcount = 0x00;
volatile uint8_t swuart_byte = 0x00;

ISR (PCINT0_vect)
{
	//This ISR will be entered after the falling edge of the start bit will be detected
	//After that,disable the ISR
	disable_pcinterrupt();
	swuart_state = RECEIVE;//change the state to receive
	swuart_bitcount = 0x00;//reset the bit count
	OCR0A = ticks2onenhalf;//wait one & half bit period after first falling edge of the start bit is detected
	TCNT0 = 0X00;//reset counter
	enable_timerinterrupt();//start timer

};

ISR (TIMER0_COMPA_vect)
{
	switch(swuart_state)
	{
		case RECEIVE:
			OCR0A = tick2full;//from now on,wait one bit period & read the data
			if(swuart_bitcount<8)
			{
				swuart_bitcount++;
				swuart_byte  = (swuart_byte >> 1);//shift the data to right as getting D0 first.
				if(swuart_getrxpin() != 0x00)//if a logical 1 is received
				{
					swuart_byte |= 0x80;//
				}
			}
			else//done receiving
			{
				//readings of bits completed
				clear_timerinterrupt();//clear any pending timer interrupt
				disable_timerinterrupt();//disable the timer interrupt
				swuart_state = PENDING_READ;
			}
			break;

	}	

}

 

Last Edited: Sun. Sep 23, 2018 - 03:38 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The pin that you respond to is controlled by the PCMSK2 register. So, just change that in software. All Done.

 

You do NOT need to enable and disable interrupts inside the PCINT2 interrupt. For standard Mega/Tiny devices, that is all done for you by the chip, automatically.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

My appologies.I corrected in the first post!I wrongly mention it as PCINT2_vect.Here,Pin(PB0-PB5) shares the PCINT0 vector.But what if i choose from PC0-PC5 pins.That belongs to PCINT1....Am I right?So then i have to rewrite the ISR like : ISR (PCINT1_vect).How to overcome this for pins belongs to different PCINT group??What i am trying to do here,that the software will determine the PCINT group & the ISR vector will be changed depending on which pin i choose.The complexity is because different pins belongs to different PCINT vectors!

Last Edited: Sun. Sep 23, 2018 - 03:41 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First up, don't do this:

#define disable_pcinterrupt() {\
	PCICR = 0X00;\
	PCMSK0 = 0X00;}

What is the #define giving you?? Declare it inline if you're worried about the call/ret overhead. Write your code 'normally' and guide the compiler to do what you want.

 

As for your problem of isrs, you need an isr for each vector. If you need to choose one at compile time, use #ifdef/#else/#endif for conditional compile.

 

 

If you can accept the extra processing overhead, use a timer interrupt at 4 times the baudrate(8 or 16 times is better) to sample the input(s) and avoid using external ints. The same isr can be used for transmit and timing purposes as well.

Last Edited: Sun. Sep 23, 2018 - 06:01 AM