Tutorial über Interrupts

vor 2 years 40 weeks von NCC-1701-M

Hallo,

gibt es ein gutes (am besten noch deutsches) Tutorial über Interrupts bei einem atmega328? Ich suche vorallem infos darüber, wie man interrupts für die Serielle Schnittstelle einrichtet. Möchte aber generell mal genau über die interrupts (avr/interrupt.h) bescheid wissen.

Danke schon im vorraus.

Gruß
NCC-1701-M

=/\=

Ähnliche Posts

7 Antworten auf “Tutorial über Interrupts”


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
  1. spirou sagt:

    Hi Enterprise museum, ich kann da das AVR-Interrupt Tutorial vom microcontroller.net empfehlen. Das Tutorial bezieht sich auf AVR-Assembler die prinzipiellen Schritte für die Initialisierung einzelner Interrupts und die Benutzung der Interrupt-Vektoren gilt aber auch für die Programmierung unter AVR-GCC. Auf microcontroller. net gibt es auch ein AVR-GCC Tutorial, das sich auch mit der Benutzung von Interrupts unter C beschäftigt. Wenn du in der Arduino Umgebung arbeitest, sind die Interrupts für den UART des 328 von dem Serial Objekt belegt ( siehe Arduino-Firmware: HardwareSerial.h & HardwareSerial.cpp) falls du es mit Serial.begin aktiviert hast. - Spirou

    Login or register to post comments

  1. NCC-1701-M sagt:

    Hallo spirou, danke für deine Antwort. Das Tutorial ist wirklich sehr gut. Ich habe allerdings ein Problem, das ich nicht gelöst bekomme. Der Interrupt wird scheinbar nicht aufgerufen. Ich habe folgendes kleines Test-Programm: [code} #include <avr/interrupt.h> #include <avr/io.h> #define FOSC 1843200 // Clock Speed #define BAUD 9600 #define MYUBRR F_CPU/16/BAUD-1 int led = 3; int button = 2; char sendChar = 'A'; void USART_Init( unsigned int ubrr) {/*Set baud rate */ UBRR0H = (unsigned char)(ubrr>>8); UBRR0L = (unsigned char)ubrr; /* Enable receiver and transmitter */ UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0); /* Set frame format: 8data, 2stop bit */ UCSR0C = (1<<USBS0)|(3<<UCSZ00); } void USART_Transmit( unsigned char data ) {/* Wait for empty transmit buffer */ while ( !( UCSR0A & (1<<UDRE0)) ) ; /* Put data into buffer, sends the data */ UDR0 = data; } unsigned char USART_Receive( void ) {/* Wait for data to be received */ while ( !(UCSR0A & (1<<RXC0)) ) ; /* Get and return received data from buffer */ return UDR0; } ISR(USART_RXC_vect) {sendChar = USART_Receive(); } void setup() {pinMode(led, OUTPUT); pinMode(button, INPUT); USART_Init(MYUBRR); } void loop() { USART_Transmit(sendChar); delay(1000); }[/code] Das senden in der loop-Funktion klappt ohne Probleme, bis ich im Arduino-"Serial Monitor" einen Buchstaben an den Arduino sende. Dann scheint die loop-Funktion nicht mehr aufgerufen zu werden. Leider konnte mir das Tutorial dabei auch nicht weiter helfen. Was mache ich falsch? Danke schonmal im vorraus. Gruß NCC-1701-M =/\=

    Login or register to post comments

  1. spirou sagt:

    Moin,
    der Fehler steck in der (unnötigen) Funktion unsigned char USART_Receive( void ).
    Du wartest da auf ein Ereignis, welches schon eingetreten ist - das empfangen einen Zeichens. Währe das Zeichen nicht schon vollständig empfangen, hättest du keinen Interrupt bekommen.

    Kleine Frage am Rande, warum machst du dir die Mühe? In HardwareSerial.cpp ist doch der ganze Kram implementiert inklusive rx-ringbuffer und so.

    - Spirou

    Login or register to post comments

  1. NCC-1701-M sagt:

    n' Abend

    Danke für deine Hilfe.. Ich hab das while weg gelassen aber leider hat es nicht funktioniert. Ich hab mir dann die HardwareSerial nochmal genau angeschaut und gesehen wo der Fehler liegt. In meinem Code habe ich die ISR mit USART_RXC_vect in der HardwareSerial verwenden sie jedoch USART_RX_vect. Damit funktioniert es nun auch bei mir. :-)

    Ich habe ein anderes Programm, indem ein Timer-Interrupt drin ist, dort lese ich die daten über die HardwareSerial im loop ein. Wird jedoch während des einlesens der Timer-Interrupt erzeugt, kommt es zu fehlern und ich möchte testen, ob ich das Problem durch den USART-Interrupt umgehen kann.

    Jedenfalls, vielen Dank für deine Hilfe

    Viele Grüße
    NCC-1701-M

    =/\=

    Login or register to post comments

  1. LTD sagt:

    Hallo,
    irgendwie sind mir die Timer beim Arduino immernoch ein Rätsel.
    Bei den Microchip PICs kam es mir irgendwie einfacher vor^^

    Ich habe einen ATmega328 auf meinem Arduino und wollte einen Timer0-Interrupt implementieren. un habe ich das Datenblatt studiert und mich auf sämtlichen Seiten informiert.

    wegen dieser Fehlermeldung: "error: expected constructor, destructor, or type conversion before '(' token" wird mein folgender Code nicht kompiliert.
    ---------------------------------------------------------------------------------------------

    #include <avr/interrupt.h>
    #include <avr/io.h>
     
    int counter;
    int counter2;
     
    BLINKER(TIMER0_OVF_vect)
    {
      if(counter==238)
      {
        counter=0;
        counter2++;
        if(counter2==1050)
        {
          counter2=0;
          if(digitalRead(13)==HIGH) digitalWrite(13,LOW);
          if(digitalRead(13)==LOW) digitalWrite(13,HIGH);
        }
      }
    }
     
    void setup()
    {
      pinMode(13,OUTPUT);
      digitalWrite(13,HIGH);
      TCCR0B=3; //Prescaler= 64/1
      TCNT0=0;  //Timer0 resetten
      TIMSK0=1; //Overflow-Interrupt-Enable
      TIFR0=0;  //Overflow-Flag-Bit
      SREG=128; //Global-Interrupt-Enable
      counter=0;
      counter2=0;
    }
     
    void loop()
    {
      //unwichtiges
    }

    ---------------------------------------------------------------------------------------------

    könnt ihr mir helfen?
    Ich glaube, ich benötige in dieser Sprache sowieso noch einiges an Nachhilfe^^ ;)

    LG LTD

    Login or register to post comments

  1. axel1973 sagt:

    Hallo,

    ich bin selbst auch noch kein spezialist in C und habe dein programm auch nicht geladen bzw weiter geprüft. allerdings glaube ich könnte das problem an folgender Zeile liegen:

    BLINKER(TIMER0_OVF_vect)
    {

    ich meine, da deine Subroutine "BLINKER()" keine Rückgabewerte sendet sollte die Zeile wie folgt lauten:

    void BLINKER(TIMER0_OVF_vect)
    {

    Das Schlüsselwort "void" vor der Methode/Funktion zeigt an dass diese Methode/Funktion KEINE Rückgabewerte erzeugt. Wenn dies nicht durch "void" angezeigt wird, geht der compiler wohl davon aus dass irgend etwas zurückgegeben werden soll, was in deinem Programm allerdings nie gemacht wird (z.b. ein return xyz).

    Wie gesagt, habs selbst nicht getestet. Ist eine reine Vermutung. Viel ERfolg mit deinem Projekt!

    MfG
    Axel Werner
    [ http://awerner.homeip.net ]

    Login or register to post comments

  1. chrimbo sagt:

    Ich hoffe für ihn, dass er sein Projekt entweder abgeschlossen oder aufgegeben hat.
    Jedenfalls ist es sehr unwahrscheinlich, dass er nach über einem Jahr keine Lösung gefunden hat und genau auf deine Antwort (die übrigens nicht funktioniert) gewartet hat.

    Sorry

    Login or register to post comments