Problem mit ATmega1284, USART verursacht Resets

Gast #2576944
Lesenswert?

Mir ist beim Verwenden des USART des Controllers ein Problem 
aufgefallen. Es kommt häufig vor, dass der Controller resetet, wenn ein 
Signal an den USART gesendet wird.

Das Programm habe ich in C geschrieben. Es steuert 5 TLC5940 über den 
PortA an. Am Controller sind zwei 100nF Abblokkondensatoren für VCC und 
AVCC sowie ein 100nF an AREF. Es wird ein 20 MHz Quarz verwendet. Als 
RS232 Überträger verwende ich den im STK500 integrierten. Weiterhin ist 
die ISP an das STK500 angeschlossen.

Die TxD und RxD Leitungen des USART 0 habe ich direkt mit dem 
entsprechenden Header des STK500 verbunden. Wenn nun vom PC aus über 
HTerm Signale an den USART sende, treten häufig Resets des Controllers 
auf. Dies ist nicht davon abhängig, ob der USART0 im Programm 
tatsächlich aktiviert ist oder nicht! Wenn allerdings alle Interrupts 
global abgeschaltet sind, tritt der Reset nicht mehr auf. Es sind 
allerdings im Programm keine anderen Interrupts als Timer 1 und Timer 2 
(und der USART) aktiviert. Im Register MCUSR sind nach dem Reset alle 
bits 0.

Was ich schon getestet habe:

-Stromversorgung nicht über STK500 - keine Änderung

-USART deaktiviert - trotzdem Resets

-STK500 an USART1 angeschlossen (USART0 und 1 deaktiviert) - trotzdem 
Resets

-Interrupts deaktiviert - funktioniert

-ISP abgetrennt - keine Änderung

Also meine Frage: Muss man beim ATmega1284 noch irgendwas deaktivieren? 
Die USART Pins werden ja auch noch für Pin Change Interrupt verwendet. 
Dann sollte der Reset aber doch immer auftreten, oder?

Hier noch mein Code, leider noch nicht dokumentiert, aber die Init 
Routinen sollte erkennbar sein.
1
#define F_CPU 20000000
2
#define DEVICE_ADDRESS 0x01
3
#include <avr/io.h>
4
#include <stdint.h> 
5
#include <util/delay.h> 
6
#include <avr/interrupt.h> 
7
#define VPRG PORTA0
8
#define SIN PORTA1
9
#define SCLK PORTA2
10
#define XLAT PORTA3
11
#define BLANK PORTA4
12
#define DCPRG PORTA5
13
#define GSCLK PORTA6
14
#define XERR PORTA7
15

16
volatile uint8_t refresh;
17
volatile uint8_t trigger;
18
uint8_t DCvalues[80];
19
uint16_t PWMvalues[80];
20
uint8_t ValueMap[80][100];
21
uint8_t ControlMap[30][100];
22
uint8_t Patch[80];
23
uint16_t Curve[256];
24

25
void Scycle(void)
26
  {
27
    PORTA |= (1 << SCLK);
28
    PORTA &= ~(1 << SCLK);
29
  }
30
  
31
void Xcycle(void)
32
  {
33
    PORTA |= (1 << XLAT);
34
    PORTA &= ~(1 << XLAT);
35
}  
36

37

38

39

40
void SendPWM(uint16_t x)
41
{  
42
  if(x & 0b0000100000000000){PORTA |= (1 << SIN);}
43
  else{PORTA &= ~(1 << SIN);}
44
  Scycle();
45
  if(x & 0b0000010000000000){PORTA |= (1 << SIN);}
46
  else{PORTA &= ~(1 << SIN);}
47
  Scycle();
48
  if(x & 0b0000001000000000){PORTA |= (1 << SIN);}
49
  else{PORTA &= ~(1 << SIN);}
50
  Scycle();
51
  if(x & 0b0000000100000000){PORTA |= (1 << SIN);}
52
  else{PORTA &= ~(1 << SIN);}
53
  Scycle();
54
  if(x & 0b0000000010000000){PORTA |= (1 << SIN);}
55
  else{PORTA &= ~(1 << SIN);}
56
  Scycle();
57
  if(x & 0b0000000001000000){PORTA |= (1 << SIN);}
58
  else{PORTA &= ~(1 << SIN);}
59
  Scycle();
60
  if(x & 0b0000000000100000){PORTA |= (1 << SIN);}
61
  else{PORTA &= ~(1 << SIN);}
62
  Scycle();
63
  if(x & 0b0000000000010000){PORTA |= (1 << SIN);}
64
  else{PORTA &= ~(1 << SIN);}
65
  Scycle();
66
  if(x & 0b0000000000001000){PORTA |= (1 << SIN);}
67
  else{PORTA &= ~(1 << SIN);}
68
  Scycle();
69
  if(x & 0b0000000000000100){PORTA |= (1 << SIN);}
70
  else{PORTA &= ~(1 << SIN);}
71
  Scycle();
72
  if(x & 0b0000000000000010){PORTA |= (1 << SIN);}
73
  else{PORTA &= ~(1 << SIN);}
74
  Scycle();
75
  if(x & 0b0000000000000001){PORTA |= (1 << SIN);}
76
  else{PORTA &= ~(1 << SIN);}
77
  Scycle();
78
}  
79

80
void ProgPWM(void)
81
{
82
  int i;
83
  for(i=0;i<80;i++){SendPWM(PWMvalues[i]);}
84
  Xcycle();
85
}
86

87

88
void SendDC(uint8_t x)
89
{
90
  if(x & 0b00100000){PORTA |= (1 << SIN);}
91
  else{PORTA &= ~(1 << SIN);}
92
  Scycle();
93
  if(x & 0b00010000){PORTA |= (1 << SIN);}
94
  else{PORTA &= ~(1 << SIN);}
95
  Scycle();
96
  if(x & 0b00001000){PORTA |= (1 << SIN);}
97
  else{PORTA &= ~(1 << SIN);}
98
  Scycle();
99
  if(x & 0b00000100){PORTA |= (1 << SIN);}
100
  else{PORTA &= ~(1 << SIN);}
101
  Scycle();
102
  if(x & 0b00000010){PORTA |= (1 << SIN);}
103
  else{PORTA &= ~(1 << SIN);}
104
  Scycle();
105
  if(x & 0b00000001){PORTA |= (1 << SIN);}
106
  else{PORTA &= ~(1 << SIN);}
107
  Scycle();
108
}  
109

110

111
  
112
void ProgDC(void)
113
{
114
  int i;
115
PORTA |= (1 << VPRG);for(i=0;i<80;i++){SendDC(DCvalues[i]);}
116
  Xcycle();
117
  PORTA &= ~(1 << VPRG);
118
}
119

120
uint8_t CalcOutput(uint8_t frameval,uint8_t preframeval,uint8_t fadeval)
121
{
122
  uint16_t v1 = (uint16_t)frameval*fadeval/255;
123
  uint16_t v2 = (uint16_t)preframeval*(255-fadeval)/255;
124
  uint16_t v5 = v1+v2;
125
  if(v5 > 255){return 255;}
126
  else{return v5;}
127
    //return frameval;
128
}
129
void OutputData(uint8_t frameA, uint8_t frameB,uint8_t frameC,uint8_t frameD,uint8_t preframeA, uint8_t preframeB,uint8_t preframeC,uint8_t preframeD,uint8_t fadecounterA, uint8_t fadecounterB,uint8_t fadecounterC,uint8_t fadecounterD)
130
{
131
  int i;
132
  for(i=0;i<32;i++){PWMvalues[Patch[i]] = Curve[CalcOutput(ValueMap[i][frameA],ValueMap[i][preframeA],fadecounterA)];}
133
  for(i=32;i<64;i++){PWMvalues[Patch[i]] = Curve[CalcOutput(ValueMap[i][frameB],ValueMap[i][preframeB],fadecounterB)];}  
134
  for(i=64;i<68;i++){PWMvalues[Patch[i]] = Curve[CalcOutput(ValueMap[i][frameC],ValueMap[i][preframeC],fadecounterC)];}  
135
  for(i=68;i<80;i++){PWMvalues[Patch[i]] = Curve[CalcOutput(ValueMap[i][frameD],ValueMap[i][preframeD],fadecounterD)];}  
136
  ProgPWM();
137
}      
138
int main(void)
139
{
140
  DDRA = 0xff;
141
  DDRB  =0xff;
142
  DDRC = 0xFF;
143
  PORTC = (1 << 4);
144
  DDRA &= ~(1 << XERR);
145
  PORTA = (0 << VPRG) | (0 << SIN)| (0 << SCLK)| (0 << XLAT)| (1 << BLANK)| (1 << DCPRG)| (0 << GSCLK);
146
  int i;
147
  for(i=0;i<256;i++){Curve[i] = i;}
148
  for(i=0;i<80;i++){Patch[i] = i;}
149
  for(i=0;i<80;i++){DCvalues[i] = 10;}
150
  int j;  
151
  for(i=0;i<80;i++){for(j=0;j<100;j++){ValueMap[i][j] = (j%2)*255;}}
152
  for(i=0;i<4;i++){for(j=0;j<100;j++){ControlMap[i][j] = 64;}}//TriggerTime
153
  for(i=4;i<8;i++){for(j=0;j<100;j++){ControlMap[i][j] = 1;}}  //FadeAmmount
154
  for(i=8;i<12;i++){for(j=0;j<100;j++){ControlMap[i][j] = 1;}}//TriggerControl
155
  for(i=12;i<16;i++){for(j=0;j<100;j++){ControlMap[i][j] = 0;}}//LoopControl
156
  for(i=16;i<20;i++){for(j=0;j<100;j++){ControlMap[i][j] = 0;}}//LoopDestination
157
  for(i=20;i<24;i++){for(j=0;j<100;j++){ControlMap[i][j] = 0;}}//LoopCounter
158
  for(i=24;i<28;i++){ControlMap[i][0] = 255;}      
159
  ProgDC();    
160
  
161
  TCCR0A = (1 << WGM01)|(1<<COM0A0);
162
  TCCR0B = (1 << CS00);
163
  OCR0A = 0x01;
164
  TCCR1B = (1 << CS02) | (1 << WGM12);
165
  TIMSK1 = (1 << OCIE1A);
166
  OCR1A = 0x02FF;
167
  TCCR2A = (1 << WGM21);
168
  TCCR2B = (1 << CS20)|(1 << CS21)|(1 << CS22);
169
  TIMSK2 = (1 << OCIE2A);
170
  OCR2A = 0x04;
171
  UBRR0L = 64;
172
  UCSR0C = (1 << UCSZ00)|(1 << UCSZ01);
173
  UCSR0B = (1 << RXCIE0)|(1 << RXEN0);
174
  PORTA &= ~(1 << BLANK);
175
  sei();
176
  PORTC &= ~(1 << 4);
177
  PORTC = MCUSR;
178
  MCUSR = 0;
179
    while(1)
180
    {  
181
    if(trigger != 0){refresh = 1;}
182
    if(trigger == 10){ProgDC();}
183
    if(refresh == 1){
184
//static int c;
185
      static int framediv;              
186
      static int fc1,fc2,fc3,fc4;
187
      static int ft1,ft2,ft3,ft4;
188
      static int pfc1,pfc2,pfc3,pfc4;
189
      static int fac1,fac2,fac3,fac4;
190
      framediv++;
191
      if(framediv == 16)
192
      {
193
        ft1++;
194
        if((ft1 == ControlMap[0][fc1] && ControlMap[8][fc1] == 1)||(ControlMap[8][fc1]==trigger))
195
        {
196
          pfc1=fc1;
197
          if(ControlMap[12][fc1]==0){fc1++;}
198
          else{
199
            if(ControlMap[20][fc1] < ControlMap[12][fc1]){
200
              fc1 = ControlMap[16][fc1];
201
              ControlMap[20][fc1]++;
202
            }
203
            else{
204
              ControlMap[20][fc1]=0;
205
              fc1++;
206
            }
207
          }
208
          if((fc1 == 100)|(fc1==ControlMap[24][0])){fc1 = 0;}
209
          ft1 = 0;
210
          fac1 = 0;
211
        }
212
        ft2++;
213
        if((ft2 == ControlMap[1][fc2] && ControlMap[9][fc2] == 1)||(ControlMap[9][fc2]==trigger))
214
        {
215
          pfc2=fc2;
216
          if(ControlMap[13][fc2]==0){fc2++;}
217
          else{
218
            if(ControlMap[21][fc2] < ControlMap[13][fc2]){
219
              fc2 = ControlMap[17][fc2];
220
              ControlMap[21][fc2]++;
221
            }
222
            else{
223
              ControlMap[21][fc2]=0;
224
              fc2++;
225
            }
226
          }
227
          if((fc2 == 100)|(fc2==ControlMap[25][0])){fc2 = 0;}
228
          ft2 = 0;
229
          fac2 = 0;
230
        }
231
        ft3++;
232
        if((ft3 == ControlMap[2][fc3] && ControlMap[10][fc3] == 1)||(ControlMap[10][fc3]==trigger))
233
        {
234
          pfc3=fc3;
235
          if(ControlMap[14][fc3]==0){fc3++;}
236
          else{
237
            if(ControlMap[22][fc3] < ControlMap[14][fc3]){
238
              fc3 = ControlMap[18][fc3];
239
              ControlMap[22][fc3]++;
240
            }
241
            else{
242
              ControlMap[22][fc3]=0;
243
              fc3++;
244
            }
245
          }
246
          if((fc3 == 100)|(fc3==ControlMap[26][0])){fc3 = 0;}
247
          ft3 = 0;
248
          fac3 = 0;
249
        }
250
        ft4++;
251
        if((ft4 == ControlMap[3][fc4] && ControlMap[11][fc4] == 1)||(ControlMap[11][fc4]==trigger))
252
        {
253
          pfc4=fc4;
254
          if(ControlMap[15][fc4]==0){fc4++;}
255
          else{
256
            if(ControlMap[23][fc4] < ControlMap[15][fc4]){
257
              fc4 = ControlMap[19][fc4];
258
              ControlMap[23][fc4]++;
259
            }
260
            else{
261
              ControlMap[23][fc4]=0;
262
              fc4++;
263
            }
264
          }
265
          if((fc4 == 100)|(fc4==ControlMap[27][0])){fc4 = 0;}
266
          ft4 = 0;
267
          fac4 = 0;
268
        }
269
        framediv = 0;
270
        //c++;
271
      }
272
      if(fac1 + ControlMap[4][fc1] < 255){fac1 += ControlMap[4][fc1];}
273
      else{fac1 = 255;}
274
      if(fac2 + ControlMap[5][fc2] < 255){fac2 += ControlMap[5][fc2];}
275
      else{fac2 = 255;}
276
      if(fac3 + ControlMap[6][fc3] < 255){fac3 += ControlMap[6][fc3];}
277
      else{fac3 = 255;}
278
      if(fac4 + ControlMap[7][fc4] < 255){fac4 += ControlMap[7][fc4];}
279
      else{fac4 = 255;}  
280
      OutputData(fc1,fc2,fc3,fc4,pfc1,pfc2,pfc3,pfc4,fac1,fac2,fac3,fac4);      
281
      refresh = 0;
282
      if(trigger != 0){trigger = 0;}      
283
    }
284
  }
285
}
286

287
ISR(TIMER2_COMPA_vect)
288
{
289
  PORTA |= (1 << BLANK);
290
  PORTA &= ~(1 << BLANK);
291
}
292

293
ISR(TIMER1_COMPA_vect)
294
{
295
  refresh = 1;
296
}
297

298
void SaveStore(uint8_t mw, uint8_t it, uint8_t t)
299
{
300
  if(mw == 200){if(it < 80){DCvalues[it]=t;}}
301
  else if(mw == 201){Curve[it]=t;}  
302
  else if(mw == 202){if(it < 80){Patch[it]=t;}}
303
  else if((mw >= 116) && (mw < 120)){if(it < 80){if(t < 100){Patch[it]=t;}}}  
304
  else if((mw >= 100) && (mw < 128)){if(it < 100){ControlMap[mw-100][it]=t;}}
305
  else{if(it < 100){ValueMap[mw][it]=t;}}
306
}
307

308
ISR(USART0__RX_vect)
309
{
310
  static uint8_t uart_status;
311
  uint8_t temp;
312
  static uint8_t mem_write_address;
313
  static uint8_t lenght;
314
  static uint8_t mem_iter;
315
  switch(uart_status){
316
  case 0:
317
    if(UCSR0A & (1 << FE0)){uart_status = 1;}
318
    temp = UDR0;
319
    break;
320
  case 1:
321
    temp = UDR0;
322
    if(temp == 0){uart_status = 2;}
323
    else{uart_status = 0;}
324
    break;  
325
  case 2:
326
    temp = UDR0;
327
    if(temp == 0){uart_status = 3;}
328
    else{trigger = temp;uart_status = 0;}
329
    break;
330
  case 3:
331
    temp = UDR0;
332
    if(temp == DEVICE_ADDRESS){uart_status = 4;}
333
    else{uart_status = 0;}
334
    break;
335
  case 4:
336
    temp = UDR0;
337
    mem_write_address = temp;
338
    uart_status = 5;
339
    break;
340
  case 5:
341
    temp = UDR0;
342
    lenght = temp;
343
    mem_iter=0;
344
    uart_status = 6;
345
    break;
346
  case 6:
347
    temp = UDR0;
348
    SaveStore(mem_write_address,mem_iter,temp);
349
    if(mem_iter == lenght){uart_status = 0;}  
350
    mem_iter++;
351
    break;
352
  }
353
//  PORTC = uart_status;
354
}
#2577157
Lesenswert?

Thomas Eckmann schrieb:
> Gerold schrieb:
>> also gehe ich schon davon aus, dass es stimmt.
> Das ist eindeutig ein Fehler: ISR(USART0__RX_vect)
> Und nur das ist richtig: ISR(USART0_RX_vect)
> Ob das nun lila wird oder nicht.

Es ist aber nicht zwangsläufig die Ursache des Problems. Denn obwohl 
"eigentlich falsch" könnte es dennoch richtig sein. Die Atmel-Leute 
haben bei ihrer eigenen Toolchain so manches verbockt. Dazu gehören auch 
diverse Vektoren mit doppelten Unterstrich. Siehe z.B. hier:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=117536
Gast #2577444
Lesenswert?

Wenn die IRQs nicht aktiviert sind, wird refresh auch nicht durch die 
Timer-ISR oder über trigger 1, d. h. der riesige Anweisungsblock in 
main() wird nicht ausgeführt.

Eine Reset-Quelle in diesem Block könnte ein Stackoverflow sein. Du hast 
ca 11 kB globale Daten. Plus die statischen Daten im riesigen 
Anweisungsblock plus sonstige lokale Daten.

Weitere Fehlerquellen können Bufferoverflows bei den vielen Schleifen 
sein. Hier und bei den Dimensionierungen der Felder lohnt es sich statt 
mit absoluten Werten mit Makronamen als Grenzen zu arbeiten. Wenn man 
das macht, ist es auch einfacher die Grenzen zu verkleinern, um einen 
potentiellen Stackoverflow zu entlarven.
Gast #2578002
Lesenswert?

Stackoverflow wäre natürlich eine Möglichkeit, aber wie gesagt der 
Fehler tritt auch auf wenn der Uart gar nicht an ist, und einfach nur 
das Signal an die Pins angelegt wird.

Ich habe trotzdem mittels Auskommentierung getestet ob man den Fehler 
eingrenzen kann und es schaut so aus als ob der Fehler immer dann 
auftritt, wenn ein Signal an den Uart kommt und gleichzeitig der AVR 
Daten an die TLCs sendet. Kommentiert man das nämlich aus funktionierts.
Gast #2586824
Lesenswert?

Hab noch keine Lösung gefunden. Problem scheint schlimmer zu werden, 
jetzt funktioniert auch ein kleines Testprogramm wie dieses nicht mehr:

1
/*
2
 * AVRGCC1.c
3
 *
4
 * Created: 24.02.2012 23:00:34
5
 *  Author: Gerold von Lachemair
6
 */ 
7
#define F_CPU 20000000
8
#define DEVICE_ADDRESS 0x01
9
#include <avr/io.h>
10
#include <stdint.h> 
11
#include <util/delay.h> 
12
#include <avr/interrupt.h> 
13
#define VPRG PORTA0
14
#define SIN PORTA1
15
#define SCLK PORTA2
16
#define XLAT PORTA3
17
#define BLANK PORTA4
18
#define DCPRG PORTA5
19
#define GSCLK PORTA6
20
#define XERR PORTA7
21

22
      
23
int main(void)
24
{
25
  DDRC = 0xFF;
26
  PORTC = (1 << 4);
27
  sei();
28
  PORTC &= ~(1 << 4);
29
  PORTC = MCUSR;
30
  MCUSR = 0;
31
    while(1)
32
    {  
33

34
  }
35
}

Auch hier treten die Resets auf, wenn an den UART gesendet wird.

Hab an Hardware jetzt auch nichts mehr außer Spannungsversorgung (mit 
Kondensatoren), Quarz, ISP und UART dran.
Gast #2587144
Lesenswert?

Ich würde bei der

Hardware

1) einen anderes µC Exemplar testen, um auszuschießen, dass der jetzige 
µC einen Hau weg hat.

2) alle Spannungen an allen Pins des µC messen und im Schaltplan / 
Aufbaubild dokumentieren. Messbezugspunkt ist GND am µC.

3) mit einem DSO oder einem LA den Spannungsverlauf beim Anlegen von 
Signalen an UART-Pins aufzeichnen.

und bei der Software

4) die Fuses (Watchdog?, Brownout?) und den Flashinhalt auslesen 
und das HEX-File disassemblieren, um auszuschließen, dass die Toolchain 
ink. Flashen schief geht.
Gast #2601206
Lesenswert?

Problem anscheinend gelöst!


Nachdem ich eure Vorschläge alle soweit möglich durchgearbeitet habe und 
den µc auch unter Assembler getestet habe, bin ich schließlich durch 
Probieren auf die Lösung gekommen: der Atmel mag unter der Einstellung 
EXTOSC nur Quarze bis 16 MHz, für 20 MHz muss man FSOSC verwenden, dann 
gehts!

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