ISR Problem beim Tiny 2313

Gast #1285589
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.
1
#include <avr/io.h>
2
#include <avr/wdt.h>
3
#include <inttypes.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6
#include <avr/sleep.h>
7

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

13
void init_mcu (void);
14

15
int main (void)
16
{
17
  init_mcu();
18
  while(1)
19
  {
20
    
21
    PORTB |= (1<<PB4);//LED AUS
22
    
23
  }
24

25
return 0;
26
}
27

28
void init_mcu (void)
29
{
30

31
  DDRB =0b11111111;
32
  PORTB=0b11100000;
33
  DDRD =0b01100000;
34
  PORTD=0b00000000;
35
  UCSRB = 1<<TXEN | 1<<RXEN;              // UART TX einschalten   UART RX einschalten
36
  UCSRC = 1<<UCSZ1 | 1<<UCSZ0;           // Asynchron 8N1
37
  UBRRH = UBRR_VAL >> 8;
38
  UBRRL = UBRR_VAL & 0xFF;
39
  MCUCR |=(1<<ISC10)|(1<<ISC11);
40
  GIMSK |=(1<<INT1);
41
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
42
  //_delay_ms(30000);
43
  sei();
44
}
45

46
ISR(INT1_vect)
47
{
48
  
49

50
  PORTB &= ~(1<<PB4);
51
  in=uart_getc();
52
  uart_putc(in);
53
}

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
Persönliche Seite #1285614
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.
Gast #1285631
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.
#1285652
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.
Persönliche Seite #1285664
Lesenswert?
• ▲
▼
1
#include <avr/io.h>
2
#include <avr/wdt.h>
3
#include <inttypes.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6
#include <avr/sleep.h>
7

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

13
#define DEBUG 1
14

15
volatile unsigned char num_ints;
16

17
ISR(INT1_vect)
18
{
19
  num_ints += 1;
20
}
21

22
void init_mcu (void)
23
{
24
  // I/O Init
25
  DDRB =0b11111111;
26
  PORTB=0b11100000;
27
  DDRD =0b01100000;
28
  PORTD=0b00000000;
29

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

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

40
  // für später?
41
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
42
  //_delay_ms(30000);
43
 
44
  sei();
45
}
46

47
int main (void)
48
{
49
  init_mcu();
50

51
  while(1)
52
  {
53
    if (num_ints)
54
    {
55
      unsigned char i = num_ints;
56
      char in;
57

58
      // Arbeitsroutine
59
      in = uart_getc();
60
      uart_putc(in); 
61
      num_ints = 0;
62

63
#if DEBUG
64
      // DEBUG: Wieviele INT1s waren es?
65
      do
66
      {
67
        PORTB &= ~(1<<PB4); //LED AN
68
        _delay_ms(200);
69
        PORTB |= (1<<PB4);  //LED AUS
70
      } while(--i);
71
#endif /* DEBUG */
72
    }
73
  }
74

75
  return 0;
76
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren