PORTA interrupting?

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

Hi Freaks,

I'm developing a stepper position controll for theater performance. The group has a special kitchen cabinet. It has 10 movable walls in it. Each wall carrys like 200 photo slides. At the back is a strong light which projects the photo slides to a wall.

The aim is to position the wooden walls via 5 pushbuttons. Each button represents one position. (yai, they'll have 50 buttons ... but it's needed fast and cheap)

While the motor moves to a position a busy LED is turned on and the buttons shall have no effect. I'm using 9V/1A 1,8° steppers and clock/direction drivers (SMC11). There will be 10 walls driven by 10 steppers and 5 micros.

µC: right now M644; final ones will be M16
language: C
board: now STK500, self and hand made ones later

I got everything pretty good working right now, but PORTA makes me problems. When I connect the STK500 switches to it the buttons do effect the µC while the motor moves. When I use PORTD everything is fine.

I'm pretty sure I disabled all PORTA alternate functions but well, this is my first AVR C-Project. Please have a look at my code, maybe you get it. Other comments on my code are welcome.

void init (void)
{
//[Timer1]
    PRR CLEAR_BIT3;      //clear Powerreduction for Timer1
    TCNT1  = 0x00;
    TCCR1A = 0x00;       //normal mode
    TCNT1 = 0xFF00;

    #define ON_T1 0x02   //define prescaler for TIM2 here 
                         //Set up timer at Fcpu/8

    
//[PortA]
    DDRA   = 0b11100000;  //PA0..4 switches for M0, PA5..7 LEDs for M0
    PINA   = 0x00;
//[ADC]
    ADCSRA = 0x00;       //
    DIDR0  = 0x00;       //disable ADC
//[Analog Comparator]
    ADCSRB = 0x00;       //
    ACSR   = 0b10010001; //disable analog comparator
    DIDR1  = 0x00;       //

//[...]
//some more init
//[...]

//[Interrupts]
    TIFR1  = 0xFF;      //clear TIM1 interrupt flags
    TIMSK1 = 0x01;      //Enable overflow interrupt 
    Timer1(ON_T1);
    sei();
}


ISR(TIMER1_OVF_vect)
{ 
//some code
}

int main()
{
    init();
     while(1)
    {
        if(ui8_PositionReady_M0 == READY)
        {    
            cli();//make writing to ui16_SCreq_M0 atomic
            switch ( ((~PINA) & 0b00011111) )//mask away LED Bits
            { 
                case (Bit0): 
                        ui16_SCreq_M0 = ui16_Pos0_M0;
                        LookBusy_M0();
                        Stepper_M0(ENABLE);
                        break;
                case (Bit1): 
                        ui16_SCreq_M0 = ui16_Pos1_M0;
                        LookBusy_M0();
                        Stepper_M0(ENABLE);
                        break;
                case (Bit2): 
                        ui16_SCreq_M0 = ui16_Pos2_M0;
                        LookBusy_M0();
                        Stepper_M0(ENABLE);
                        break;
                case (Bit3): 
                        ui16_SCreq_M0 = ui16_Pos3_M0;
                        LookBusy_M0();
                        Stepper_M0(ENABLE);
                        break;
                case (Bit4): 
                        ui16_SCreq_M0 = ui16_Pos4_M0;
                        LookBusy_M0();
                        Stepper_M0(ENABLE);
                        break;
                default:break;        
            }  
            sei();
        }
        else {}
    }
} 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PS:

LookBusy_M0(); 

sets ui8_PositionReady_M0 to NOT_READY. The TIM1 ISR sets it READY when position is arrived.

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

Quick notes:

Setting PINx to anything is useless. PINx is the input value from the port, while PORTx is the output value. It might make sense to set PORTx bit to 1 when a pin is defined as input, since most new AVR processors will then put a weak pull-up resistor to VCC.

There is not a DIDR1 register in the ATMega644. I'm surprised you are not getting a compiler error on that statement.

You don't show the definition of ui8_PositionReady_M0 - can it be changed inside an interrupt? If so, add the keyword volatile to it's definition. My guess is that this is the true problem.

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

Quote:

Setting PINx to anything is useless. PINx is the input value from the port,

Sorry to be a pedant but in modern AVRs writing 1 bits to PINA toggles the output state of the respective pins that are set to output in the DDRA. However I agree that "PINA=0x00" is pointless.

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

from ATmega644/V Preliminary, p.232

Quote:
20.3.3 DIDR1 – Digital Input Disable Register 1

All global variables are declared volatile (can this be a disadvantage?)

PINA writig deleted ^^