tiny2313 resets(?) after INT1

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

Hi 'freaks,

I'm working on a LCD 16x1 for error codes. The LCD works pretty good so far, now I'm programming a data/clock 2-wire communication where INT1 functions as clock-input.

Problem is: When INT1 is finishes my program returns to the start of main(). It does this in reality and in the simulator.

I've put the ISR code above another function but the programm still jumps to the first line of main(). Here is the code without the LCD routines and defines.

Is my init() wrong? I've read the datasheet part about external interrupt more than once and can't find a flaw :(


//************************************************************************************
//                                includes and subroutines
//************************************************************************************
#include 
#include  
#include "my_bit.h"
#include "my_types.h"
//************************************************************************************
//                                  subroutines
//************************************************************************************
void init (void)
{
//[PortB]
    DDRB  = 0b11111111;     //PortB out
    PORTB = 0;
//[PortD]
    DDRD  = 0b01110000; 
    PORTD = 0;
//[Interrupts]
    setBit(PCMSK, Bit7);    //use PD3 as INT1 

    setBit(GIMSK, Bit7);    //INT1 is used as external interrupt
    setBit(GIMSK, Bit5);    //pin change interrupt enabled

    setBit(MCUCR, Bit2);    
    setBit(MCUCR, Bit3);    //INT1 triggers on rising edge
    sei();
}
//************************************************************************************
//                                     interrups
//************************************************************************************
ISR(INT1_vect)              //external interrupt
{
    volatile uInt uInt_IRQcounter;
    LCD_sendcommand(0x01);  //display clear
    LCD_setDDRAM(0x00);
    uInt_IRQcounter++;
    LCD_writedata(uInt_IRQcounter+0x30);

}
//************************************************************************************
//                                     main
//************************************************************************************
int main()
{
    init();
    LCD_init();
    LCD_writedata(0x30);

    while(1)
    {
   
    }
} 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
setBit(PCMSK, Bit7); //use PD3 as INT1

PCMSK has nothing to do with INT1, it controls the PCINTx interrupts.
Quote:
setBit(GIMSK, Bit5); //pin change interrupt enabled

Again, this is for the PCINT interrupt. Remove these two lines.

Regards,
Steve A.

The Board helps those that help themselves.

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

your interrupt init does not match your comments, your comments talk about INT1, but you are initializing for a PCINT (Pin-Change Interrupt) as well.

    setBit(PCMSK, Bit7);    //use PD3 as INT1

No, that line enables Pin PB7 as a pin-change interrupt source

    setBit(GIMSK, Bit7);    //INT1 is used as external interrupt
    setBit(GIMSK, Bit5);    //pin change interrupt enabled

These lines are enabling the bits as described, note you are also enabling the pin-change interrupt

    setBit(MCUCR, Bit2);   
    setBit(MCUCR, Bit3);    //INT1 triggers on rising edge

This is correct as well.

Problem is while you do have an interrupt handler defined for INT1, you don't have one for the PCINT, as a result any changes on PB7 will cause your AVR to try and execute an interrupt that is not there, resulting in the AVR resetting (in this case) [this is because there are no other interrupts defined in the vector table that appear after the PCINT entry]

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

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

Side note:

Quote:

I've put the ISR code above another function but the programm still jumps to the first line of main().

The order of your C functions in the source code has nothing at all to do with what executes first after a reset. The startup code that the linker inserts will always call main() no matter where it resides, and what possibly precedes it, in your source code.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

As you are using GCC then why on earth refer to control bits in SFRs simply as "Bit5" or "Bit7"? You, in 3 months, like us now, will have to dig out a datasheet to be able to understand what your code is doing.

    setBit(PCMSK, Bit7);    //use PD3 as INT1 

    setBit(GIMSK, Bit7);    //INT1 is used as external interrupt 
    setBit(GIMSK, Bit5);    //pin change interrupt enabled 

would be far more readable as:

    setBit(PCMSK, PCINT7);    //use PD3 as INT1 - error - you cannot reassign pins

    setBit(GIMSK, INT1);    //INT1 is used as external interrupt 
    setBit(GIMSK, PCIE);    //pin change interrupt enabled - error - no ISR and should not use

In which case your error of enabling two interrupts and providing just one ISR() would have been quickly obvious. See "catch all" on this page:

http://www.nongnu.org/avr-libc/u...

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

uh yeah, not using the GCC names was stupid. Thanks for all the corrections and hints :)

[edit]

The interrupt now works as wanted. But I'll have to change my macros. They don't work with the GCC names. They need a "1" for Bit0 and "2" for Bit1 etc..