Avr-bit_is_clear macro not working as expected?

Status
Not open for further replies.

kgavionics

Full Member level 3
Joined
Jun 12, 2012
Messages
167
Helped
7
Reputation
14
Reaction score
11
Trophy points
1,298
Location
Alberta.Canada
Activity points
2,482
Hello guys
I have the following code, which uses 2 interrupts to determine if the Rotary encoder is rotated cw or ccw !
I have written an assembly code which was corrected in this thread and working like a charm!
I translated the code to C, but the result is the opposite to what expect! when I turn the RE clockwise, the output is CCW and vice versa!

I used the macro bit_is_set and bit_is_clear in another c code, and they were ok!
this is my C code:
C:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define FOSC 16000000
unsigned char counter=0;

//INT0 interrupt
ISR(INT0_vect )
{
    if(bit_is_clear(PIND, PD1))
    {
counter++;
PORTF=counter;

PORTC=0X01;

    }
    else
    {
counter--;
PORTF=counter;

PORTC=0X02;
    }
}

//INT1 interrupt
ISR(INT1_vect )
{
    if(bit_is_set(PIND, PD0))
    {
counter--;
PORTF=counter;

PORTC=0X02;
    }
    else
    {
counter++;

PORTF=counter;

PORTC=0X01;

    }
}

int main(void)
{

  /* set PD0 and PD1 as input */
  DDRD &=~ (1 << PD0);                /* PD0 and PD1 as input */
  DDRD &=~ (1 << PD1);       
  PORTD |= (1 << PD0)|(1 << PD1);   /* PD0 and PD1 pull-up enabled   */
  DDRF=0XFF;

  DDRC=0X03;

 EIMSK |= (1<<INT0)|(1<<INT1);        /* enable INT0 and INT1 */
 EICRA |= (1<<ISC01)|(1<<ISC11)|(1<<ISC10); /* INT0 - falling edge, INT1 - rising edge */

  /* enable interrupts */
  sei();


   while(1)
   {
    //do nothing ;)
    _delay_ms(1);
   }

  return 0;
}

Can someone tell me what I'm doing wrong?
 

Hi,

I don't ghink that "bit_is_set" is the problem.
I rather think the interrrupt polarity or the A/B vs B/A connection is the problem.

Mind: your counting is unequal:
When turning in one diriection you get 4 edges per pulse sequence:
* A rising: count
* B falling: count
* A falling: do nothing
* B rising: do nothing

Klaus
 

Thank you klausST for your help, I really appreciate it!
I changed accidentally both interrupts to this (both : bit_is_set, and it works, but I don't know the reason why!
C:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define FOSC 16000000
unsigned char counter=0;

//INT0 interrupt
ISR(INT0_vect )
{
    if(bit_is_set(PIND, PD1)) //---------------------------->change I have made
    {
counter++;
PORTF=counter;

PORTC=0X01;

    }
    else
    {
counter--;
PORTF=counter;

PORTC=0X02;
    }
}

//INT1 interrupt

ISR(INT1_vect )
{
    if(bit_is_set(PIND, PD0))
    {
counter++;
PORTF=counter;

PORTC=0X01;

    }
    else
    {
counter--;
PORTF=counter;

PORTC=0X02;
    }
}
int main(void)
{

  /* set PD0 and PD1 as input */
  DDRD &=~ (1 << PD0);                /* PD0 and PD1 as input */
  DDRD &=~ (1 << PD1);      
  PORTD |= (1 << PD0)|(1 << PD1);   /* PD0 and PD1 pull-up enabled   */
  DDRF=0XFF;

  DDRC=0X03;

EIMSK |= (1<<INT0)|(1<<INT1);        /* enable INT0 and INT1 */
EICRA |= (1<<ISC01)|(1<<ISC11)|(1<<ISC10); /* INT0 - falling edge, INT1 - rising edge */

  /* enable interrupts */
  sei();


   while(1)
   {
    //do nothing ;)
    _delay_ms(1);
   }

  return 0;
}
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…