www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ISR Problem beim Tiny 2313


Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,
ich hab eine kleines Problem mit einer ISR beim Tiny2313.
Und zwar soll mein Tiny wenn er eine Low-Flanke an INT1 detektiert in 
der ISR ein Zeichen per Uart Empfangen und dieses in eine globale 
Variable schreiben danach soll er wieder zum Hauptprogramm wechseln. Das 
anspringen der ISR klappt aber komischerweise liest er immer erst 4 
Zeichen ein bevor er wieder raussüringt.

Kann eventuell jemand was zu meinem Code sagen ,weil ich finde den 
Fehler einfach nicht.
#include <avr/io.h>
#include <avr/wdt.h>
#include <inttypes.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille
#define BAUD 115200L

void init_mcu (void);

int main (void)
{
  init_mcu();
  while(1)
  {
    
    PORTB |= (1<<PB4);//LED AUS
    
  }

return 0;
}

void init_mcu (void)
{

  DDRB =0b11111111;
  PORTB=0b11100000;
  DDRD =0b01100000;
  PORTD=0b00000000;
  UCSRB = 1<<TXEN | 1<<RXEN;              // UART TX einschalten   UART RX einschalten
  UCSRC = 1<<UCSZ1 | 1<<UCSZ0;           // Asynchron 8N1
  UBRRH = UBRR_VAL >> 8;
  UBRRL = UBRR_VAL & 0xFF;
  MCUCR |=(1<<ISC10)|(1<<ISC11);
  GIMSK |=(1<<INT1);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  //_delay_ms(30000);
  sei();
}

ISR(INT1_vect)
{
  

  PORTB &= ~(1<<PB4);
  in=uart_getc();
  uart_putc(in);
}

Falls sich jemand nach dem Sinn fragt : Dies ist erstmal nur ein Test ob 
das rein und rausspringen klappt.Es geht hinterher darum ein 
Steuerzeichen zu empfangen was von einem Linux Router kommt,wobei dessen 
RS232 Schnittstelle aber nicht explizit frei ist für diese eine Aufgabe.

MfG

Max

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh hab ich vergessen in ist natürlich mit volatile char in='Y' 
definiert.
Sorry.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist IMHO wahrscheinlich nicht "komischerweise liest er immer erst 4
Zeichen ein bevor er wieder raussüringt" sondern die ISR(INT1_vect) wird 
viermal hintereinander aufgerufen.

Wenn das Eingangssignal ein "Steuerzeichen" von einer RS232-Leitung ist, 
können sich darin mehrere steigende Flanken verstecken 
(http://www.mikrocontroller.net/articles/RS-232 => Startbit + Nextframe 
+ Anzahl 1-0 Wechsel im Steuerzeichen?)

1/ Hast du eine Möglichkeit das Signal am externen Interrupteingang zu 
oszilloskopieren?

2/ UART-Aktionen innerhalb der ISR(INT1_vect) wären für mich ein No-Go. 
Lieber in der ISR ein globales, volatile Flag setzen und das im 
Userprogramm (main) abfragen und behandeln.

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry diese Möglichkeit habe ich leider nicht.Aber ich glaube ich habe 
mich falsch ausgedrückt. Die UART ist mit den RX/TX Leitungen des 
Routers verbunden.Und ein GPIO Pin des Routers Schaltet kurz die Tiny 
INT1 Leitung auf high und anschliessend sofort wieder auf low.Nun sendet 
der Router erst das Uart Zeichen da der Tiny nach dem Pin Wechsel in der 
ISR bei uart_getc() stehen sollte.So sollte der Ablauf zumindest sein.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Max schrieb:
> Nun sendet
> der Router erst das Uart Zeichen da der Tiny nach dem Pin Wechsel in der
> ISR bei uart_getc() stehen sollte.So sollte der Ablauf zumindest sein.

Und wo kommt dieses uart_getc her? Vielleicht aus der Fleury-Lib? Das 
uart_getc dort wartet nämlich nicht auf ein Zeichen.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert

#include <avr/io.h>
#include <avr/wdt.h>
#include <inttypes.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille
#define BAUD 115200L

#define DEBUG 1

volatile unsigned char num_ints;

ISR(INT1_vect)
{
  num_ints += 1;
}

void init_mcu (void)
{
  // I/O Init
  DDRB =0b11111111;
  PORTB=0b11100000;
  DDRD =0b01100000;
  PORTD=0b00000000;

  // UART Init
  UCSRB = 1<<TXEN | 1<<RXEN;   // UART TX und RX einschalten
  UCSRC = 1<<UCSZ1 | 1<<UCSZ0; // Asynchron 8N1
  UBRRH = UBRR_VAL >> 8;
  UBRRL = UBRR_VAL & 0xFF;

  // INT1 Init
  MCUCR |= (1<<ISC10)|(1<<ISC11); // steigende Flanke
  GIMSK |= (1<<INT1);

  // für später?
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  //_delay_ms(30000);
 
  sei();
}

int main (void)
{
  init_mcu();

  while(1)
  {
    if (num_ints)
    {
      unsigned char i = num_ints;
      char in;

      // Arbeitsroutine
      in = uart_getc();
      uart_putc(in); 
      num_ints = 0;

#if DEBUG
      // DEBUG: Wieviele INT1s waren es?
      do
      {
        PORTB &= ~(1<<PB4); //LED AN
        _delay_ms(200);
        PORTB |= (1<<PB4);  //LED AUS
      } while(--i);
#endif /* DEBUG */
    }
  }

  return 0;
}


Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh die hab ich vergessen.Das ist das getc hier aus dem AVR-GCC Tutorial.
uint8_t uart_getc(void)
{
    while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
        ;
    return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.