Input Capture - changing edge detection inside interrupt

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

Hy guys. Purpose of my program is to toggle a LED and to store value of ICRx when is detected an input capture, first on RISING edge, then on FALLING edge. First time it enters in interrupt and stores value of ICR1, but next time when i press it's not working.

 

my code:

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

volatile uint16_t timerCaptureRising[5];
volatile uint16_t timerCaptureFalling[5];

typedef enum
{
	TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5
}TimerNr;

typedef enum
{
   RISING, FALLING
}EdgeDetectionType;

struct
{
   EdgeDetectionType current;
   EdgeDetectionType next;
}edge;

void Init_InputCapture(TimerNr IC_Channel);
void Deinit_InputCapture(TimerNr IC_Channel);
uint16_t Get_InputCapture(TimerNr IC_Channel);

int main()
{
   Init_InputCapture(TIMER1);
   char value;
   
   DDRB = 0xFF;
   TCCR1B |= _BV(CS10); // clock select for timer1
   
   while(1)
   {
      value = Get_InputCapture(TIMER1);
      PORTB = value;
   }
   return 0;
}

void Init_InputCapture(TimerNr IC_Channel)
{
	sei();
	switch(IC_Channel)
	{
	case TIMER1:
		TCCR1B |= _BV(ICES1);	// Set Rising Edge detection
		TIMSK1 |= _BV(ICIE1);  // Activate Input Capture Interrupt
		break;
	default:
		break;
	}
}
void Deinit_InputCapture(TimerNr IC_Channel)
{
	switch(IC_Channel)
	{
	case TIMER1:
		TIMSK1 &=~_BV(ICIE1); // Deactivate Input Capture Interrupt
		break;
	default:
		break;
	}
}

uint16_t Get_InputCapture(TimerNr IC_Channel)
{
	switch(IC_Channel)
	{
	case TIMER1:
		return timerCaptureFalling[1];
	default:
		return -1;
	}
}

ISR(TIMER1_CAPT_vect)
{
   cli();
   DDRA = 0xFF;
   
   // is rising or falling edge?
   if(edge.current == RISING)
   // if is rising:
   {
      // get timer capt value
    timerCaptureRising[1] = ICR1;
      
    PORTA |= _BV(PINA1); // test if interrupt is called

      
      // change to falling
      TCCR1B &= ~ _BV(ICES1);
      edge.next = FALLING;
   }
      // if is falling

   if(edge.current == FALLING)
   {
      //get timer capt value
      timerCaptureFalling[1] = ICR1;
      
	PORTA &=~ _BV(PINA1); // to test if interrupt for falling edge is called

      // change to rising
      TCCR1B |= _BV(ICES1);
      edge.next = RISING;
   }
   edge.current = edge.next;
   
   sei();
}

 

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

Edit: Nonsense removed.

Stefan Ernst

Last Edited: Sun. Mar 18, 2018 - 11:16 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Datasheet wrote:
After a change of the edge, the Input Capture Flag (ICFn) must be cleared by software (writing a logical one to the I/O bit location).

 

BTW:

ISR(TIMER1_CAPT_vect)
{
   cli();
...   
   sei();
}

The cli() is superfluous, the sei() even dangerous. Interrupts are disabled by default during an ISR anyway.

Stefan Ernst

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

Contact bounce?

 

Jim

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

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

Logical one does not mean that the Flag is set?

I did as you said, but it still does not work

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

how are you testing it and how are you observing the results?

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

I use Proteus 8 for code writing and testing

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

That doesn't tell us much. I gather you need to tell proteus to actually do something. How are you instructing it to test the input capture?

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

I use a button connected to the ICPn pin, and to check if the interrupt was called again I set a counter, which, is incremented only once how much i would not press.

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

P47_R1ck wrote:
I use a button connected to the ICPn pin

 

Mechanical buttons are a very poor source of transitions, since they bounce.

 

Whenever you change the direction of the capture interrupt, you must always check the input pin, if it was still on the expected level.

 

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

danni wrote:

 

Mechanical buttons are a very poor source of transitions, since they bounce.

 

I simulate my program in Proteus, how the button will bounce??

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

P47_R1ck wrote:
I simulate my program in Proteus
   You need to take this question to Proteus support, after all you have paid for it!!!

 

Jim

 

Mission: Improving the readiness of hams world wide : flinthillsradioinc.com

Interests: Ham Radio, Solar power, futures & currency trading - whats yours?