Forum: Compiler & IDEs UART Interrupt Probleme


von C-Anfänger (Gast)


Lesenswert?

Hallo,

Ich wollte nun mal mit C-Programmieren anfangen nachdem ich Basic 
genutzt habe.
Ich habe dabei jetz folgendes Problem:
Ich habe eine LED-Anzeige die per UART gesteuert werden soll. Ich habe 
jetzt einen Interrupt eingebaut, der aufgerufen wird wenn Zeichen 
empfangen werden. Das funktioniert ansich auch sehr gut. (Ich gebe 
danach einfach mal eine 0 zurück über den UART und die kommt auch an). 
Aber das Problem ist, dass ich in diesem Interrupt dann eine Variable 
ändern will. Die Variable enthält die Pixel für die Anzeige. Die werden 
dann in einer Endlosschleife auf der Matrix ausgegeben. Jetzt 
funktionieren die Vorher eingestellten Daten ohne Probleme, aber die die 
während die Schleife läuft hinzukommen scheinen nicht übernommen zu 
werden.
Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h> 
3
#include <stdint.h>
4
5
6
#define F_CPU 8000000UL
7
#include <util/delay.h> 
8
9
#define BAUD        38400UL
10
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)
11
12
13
#define red  0
14
#define green  1
15
#define clock  2
16
#define bright  3
17
#define reset  4
18
#define brtwrt  6
19
#define brtclk  5
20
21
#define cres  1
22
#define cclk  0
23
24
volatile uint16_t datar[144];
25
volatile uint16_t datag[144];
26
27
volatile uint8_t i;
28
29
volatile uint8_t col = 0;
30
volatile uint8_t row = 0;
31
32
volatile uint8_t module = 0;
33
34
35
void slm1608()
36
{
37
  PORTC &= ~(1<<reset); //reset
38
  PORTC |= (1<<bright);
39
  PORTC |= (1<<reset);
40
  PORTC &= ~(1<<bright);
41
  PORTC &= ~(1<<reset);
42
43
  PORTC |= (1<<bright); //bright auf high
44
45
  PORTC |= (1<<brtwrt); //brgwrt an
46
47
  for(col = 0; col < 16; col++){
48
    for(row = 0; row < 16; row++){
49
      if( (datar[(module*16)+col]) & (1 << row) ){
50
        PORTC |= (1<<red);
51
      }
52
      if( (datag[(module*16)+col]) & (1 << row) ){
53
        PORTC |= (1<<green);
54
      }
55
56
      PORTC |= (1<<clock);      
57
      PORTC |= (1<<brtclk);
58
      PORTC &= ~(1<<brtclk);
59
      PORTC &= ~(1<<clock);
60
61
      PORTC &= ~(1<<red);
62
      PORTC &= ~(1<<green);
63
    }
64
65
    PORTC &= ~(1<<bright);
66
    _delay_us(200);
67
    PORTC |= (1<<bright);
68
  }
69
70
  if(module == 2)
71
  {
72
    PORTA |= (1<<cres);  //reset high
73
    PORTA &= ~(1<<cres); //reset low
74
75
    for(i = 0; i<6; i++){
76
      PORTA &= ~(1<<cclk); //clock low
77
      PORTA |= (1<<cclk);  //clock high
78
    }
79
80
    datar[3] = 2134;
81
82
    module = 0;
83
  }
84
85
  PORTA &= ~(1<<cclk); //clock low
86
  PORTA |= (1<<cclk);  //clock high
87
88
  module ++;
89
90
91
}
92
93
94
void uart_init(void)
95
{
96
    // Baudrate einstellen (Normaler Modus)
97
    UBRRH = (unsigned char) (UBRR_BAUD>>8);
98
    UBRRL = (unsigned char) (UBRR_BAUD & 0x0ff);
99
100
    // Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts
101
    UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
102
103
    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
104
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
105
}
106
107
108
int main(void)
109
{
110
  uart_init();
111
112
113
    sei();
114
115
  DDRA = 0xFF; //4017
116
  DDRC = 0xFF; //Data SLM1608
117
118
  PORTC = 0;
119
  PORTA = 0;
120
121
  _delay_ms(1);
122
  PORTA |= (1<<cres);  //reset high
123
  _delay_ms(1);
124
  PORTA &= ~(1<<cres); //reset low
125
  _delay_ms(1);
126
127
  for(i = 0; i<144; i++){
128
    datar[i] = 0;
129
  }
130
131
  for(i = 0; i<6; i++){
132
    PORTA |= (1<<cclk);  //clock high
133
    _delay_ms(1);
134
    PORTA &= ~(1<<cclk); //clock low
135
    _delay_ms(1);
136
  }
137
138
  
139
  datar[0] = 51503;
140
  datag[2] = 65535;
141
142
  module = 0;
143
144
  while(1){
145
    slm1608();
146
  }
147
148
}
149
150
151
ISR(USART_RXC_vect)  //Interrupt für UARTSIG_UART_RECV
152
{
153
154
  unsigned char buffer;
155
156
    // Daten aus dem Puffer lesen ...
157
    buffer = UDR;
158
159
    // ... warten bis der Sendepuffer leer ist ...
160
    while ( !( UCSRA & (1<<UDRE)) )
161
        ;
162
163
    datar[5] = 3123 // wenn ein Zeichen gekommen ist, wird ROT[5] auf 3123 gesetzt
164
165
  UDR = 0x30; // 0 senden 
166
}

Weis jemand woran das liegen könnte ?

von C-Anfänger (Gast)


Lesenswert?

keine eine Idee?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Nö, weil ich deine Problembeschreibung nicht verstehe und weil es kein 
gültiges Programm ist (; in der Zeile "datar[5] = 3123 // wenn ein 
Zeichen gekommen ist, wird ROT[5] auf 3123 gesetzt" fehlt)

Ansonsten: Ist die Anzeige wie erwartet, wenn du diesen Programmteil 
benutzt und nichts sendest/empfängst?

  while(1){
    datar[5] = 3123;
    slm1608();
  }

statt

  while(1){
    slm1608();
  }

von C-Anfänger (Gast)


Lesenswert?

Ok Danke schonmal

Ich hab jetzt einfach mal

while(1){
  datar[5]++;
    slm1608();

  }

Eingesetzt

Und es ändert sich nur einmal ...
Es scheint also so als ob nachdem das datar einmal ausgelesen wird es 
sich nicht mehr verändern lässt. Ich hab auch mal nachgemessen. slm1608 
wird auch unendlich lang ausgeführt.

Was Verstehst du nicht ?

von C-Anfänger (Gast)


Lesenswert?

Ok Ich denke ich hab es gelöst ich hab mir einfach mal datar[5] über den 
Uart geschickt und es erhöht sich wirklich. Dann liegt es also an den 
Anzeigen. Da muss ich nochmal schaun ob ich nen denkfehler drin hab.

von C-Anfänger (Gast)


Lesenswert?

Gut hab den Denkfehler gefunden jetzt läuft es

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.