Forum: Mikrocontroller und Digitale Elektronik Problem mit Interrupt


von Hlao L. (lli_howa)


Lesenswert?

Hallo Zusammen,

ich bin ganz neu in der Welt der Programmierung mit Mikrocontroller. Ich 
habe ein Programm geschrieben, was ein Interrupt durch Drücken einen 
Taster auslöst. Dabei soll das mainProgramm unterbrochen werden und die 
LED leuchten. Leider bleibt das Hauptprogramm immer am Laufen und wird 
das Interrupt nicht ausgelöst.

Kann mir vielleicht da jemanden helfen, wie ich das Programm verbessern 
kann.

hier ist das geschriebene Code von mir:
1
#define F_CPU 2000000
2
#define BAUD 9600UL
3
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
4
5
#include <avr/io.h>
6
#include <avr/delay.h>
7
#include <avr/interrupt.h>
8
9
// Praeprozessor Makros fuer Ausgaenge
10
#define set_bit(port,mask) ((port) |= (1<<mask))
11
#define clr_bit(port,mask) ((port) &= ~(1<<mask))
12
#define tog_bit(port,mask) ((port) ^= (1<<mask))
13
14
// Praeprozessor Makros fuer Eingaenge
15
#define input_bit(port,mask) ((port) & (1<<mask))
16
void USART_Init(void)
17
{
18
  // Baudrate einstellen
19
  UBRR2H = (unsigned char)(UBRR_VAL>>8);
20
  UBRR2L = (unsigned char)UBRR_VAL;
21
  // receiver and transmitter einschalten
22
  UCSR2B = (1<<RXEN2)|(1<<TXEN2);
23
  
24
  //  frame format auf 8data, 1stop bit setzen
25
  UCSR2C = (1<<UCSZ21|1<<UCSZ20);
26
  CLKPR = (1<<CLKPCE); 
27
  CLKPR = (1<<CLKPS1); 
28
} // USART_Init
29
30
void USART_putChar( unsigned char data )
31
{
32
  // warte bis Sendepuffer leer ist
33
  while (!( UCSR2A & (1<<UDRE2)));
34
  
35
  UDR2 = data;
36
  
37
  return 0;
38
}
39
void USART_putStr(unsigned char *s)
40
{
41
  while (*s)
42
  {   
43
    USART_putChar(*s);
44
    s++;
45
  }
46
}
47
48
49
ISR(INT1_vect)
50
{
51
   set_bit(PORTB,PB6);
52
   USART_putStr("LED EIN \r\n");
53
}
54
55
int main(void)
56
{
57
  //PB3 Ausgang
58
  DDRB |= (1<<PB6);
59
  
60
  // PD1 als Eingang
61
  DDRD &=~(1<<PD1);
62
  
63
  // Pullup einschalten
64
  PORTD |=(1<<PD1);
65
  
66
  // fallende Flanke    
67
  EICRA |=(1<<ISC11);
68
  
69
  // INT1 einschalten 
70
  EIMSK |=(1<<INT1);
71
    
72
  // UART Init
73
  USART_Init();
74
  
75
  // Globale Interrupts einschalten
76
  sei();     
77
  
78
  while(1)
79
  
80
  {  
81
    USART_putStr("LED AUS \r\n");       
82
  }
83
  _delay_ms(500);
84
}

Für eure Hilfe bin euch sehr dankbar.

von Peter D. (peda)


Lesenswert?

Es gibt auf der Welt nicht nur einen MC und von einer Familie nicht nur 
einen Typ.
Zu jeder Frage gehört daher die Angabe des Targets (komplette 
Bezeichnung).

Hlao Lajh schrieb:
> Leider bleibt das Hauptprogramm immer am Laufen und wird
> das Interrupt nicht ausgelöst.

Woran erkennst Du das?

Hlao Lajh schrieb:
> ISR(INT1_vect)
> {
>    set_bit(PORTB,PB6);
>    USART_putStr("LED EIN \r\n");

USART_putStr ist nicht reentrant. Du mußt Dich daher entscheiden, ob nur 
im Interrupt oder nur im Main. Beides zusammen ergibt Zeichensalat.

von Hlao L. (lli_howa)


Lesenswert?

Peter Dannegger schrieb:
> Es gibt auf der Welt nicht nur einen MC und von einer Familie nicht nur
> einen Typ.
> Zu jeder Frage gehört daher die Angabe des Targets (komplette
> Bezeichnung).

Ich arbeite mit dem Atmega1280



> Woran erkennst Du das?

Auf dem Terminal wird immer LED AUS angezeigt.

Für Verbesserungsvorschläge wäre ich euch sehr dankbar.

von Daniel V. (danvet)


Lesenswert?

Hallo,
zu deinem Programm gäbe es viel zu sagen.
Da du neu in der ControllerWelt bist schlage ich dir vor zunächst die 
UART-sachen weg zu lassen.

Versuche zuerst die LED ein- und auszuschalten und zwar bei jedem 
Tastendruck.
Dazu kannst du dir das hier durchlesen (und verstehen):
http://www.mikrocontroller.net/articles/Entprellung

Wenn das zuverlässig funktioniert kannst du mit der UART-Ausgabe 
weitermachen.

von Ralf G. (ralg)


Lesenswert?

Hlao Lajh schrieb:
> set_bit(PORTB,PB6);

Geht die LED an? Ist die korrekt angeschlossen?

1. Kleiner Test zum Einfügen vor sei();
1
  set_bit(PORTB,PB6);
2
  _delay_ms(500);
3
  clr_bit(PORTB,PB6);
4
  _delay_ms(500);
5
  set_bit(PORTB,PB6);
6
  _delay_ms(500);
7
  clr_bit(PORTB,PB6);
8
  _delay_ms(500);

2. Lege einen Puffer an, der an die Funktion 'USART_putStr' übergeben 
wird.
In der ISR wird nur der Text dort reingeschrieben.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.