Usart verursacht Reset bei Rücksprung

OP #2591009
Lesenswert?

Schönen Abend,

Der einfach Code unten macht mich Wahnsinnig, die USART0_Senden() 
Funktion geht einwandfrei. Warum er mit USART_Str("Hallo") die Hallo 
zwar ausgibt, aber dann einen Reset verursacht begreife ich nicht. Als 
könnte das Programm nicht aus der USART_Str() zurückspringen?

Nutze einen Atmega128A mit einem USB-Serial Kontroller.

Irgendwo muss der Hund sein.

1
#include <avr/io.h>
2
#include <util/delay.h>
3

4
#ifndef F_CPU
5
#define F_CPU 8000000UL  // Systemtakt in Hz - Definition als unsigned long beachten 
6
#endif
7
 
8
#define BAUD 9600UL      // Baudrate, muss in Hterm gleich eingestellt sein.
9
 
10
// Berechnungen
11
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
12
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
13
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)      // Fehler in Promille, 1000 = kein Fehler.
14
 
15
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
16
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
17
#endif
18

19
void USART0_Init( void );
20
void USART0_Senden( unsigned char z);
21
void USART_Str(const char *s);
22
unsigned char USART0_Receive( void );
23

24
int main(void){
25
     unsigned char tmp=0;
26

27
   DDRB = 0xff;
28
   PORTB = 0x00;
29
   _delay_ms(100);
30
         USART0_Init(); 
31
     
32
    USART0_Senden('B');
33
   USART0_Senden('J');
34
   USART0_Senden('N');
35
   USART0_Senden('\n');  
36
   _delay_ms(1000);     
37
   USART_Str("Hallo");
38
   while(1){
39
     PORTB = 0xff;
40
       if(UCSR0A & (1<<RXC0)) 
41
       {
42
         tmp=USART0_Receive();
43
         USART0_Senden(tmp);
44
       } 
45
         }
46
   return 0;
47
}
48

49
void USART0_Init(){                              
50
     UCSR0B = (1<<RXEN0)|(1<<TXEN0);
51
     UCSR0C = (1<<UCSZ00)|(1<<UCSZ01);
52
     UBRR0H = UBRR_VAL >> 8; 
53
     UBRR0L = UBRR_VAL & 0x0FF;
54
}
55

56

57
unsigned char USART0_Receive(){    
58
     while ( !(UCSR0A & (1<<RXC0)) );
59
    
60
     return UDR0;
61
} 
62

63

64
void USART_Str (const char *s){ 
65
   while ( !(UCSR0A & (1<<UDRE0)));   //Warten bis UDR leer ist für Senden
66

67
   while (*s){ 
68
      USART0_Senden(*s);         //Zeichen senden 
69
      s++;                    //Adresse erhöhen 
70
   }    
71
} 
72

73
void USART0_Senden( unsigned char z ){
74
    
75
     while ( !( UCSR0A & (1<<UDRE0)) );
76
    
77
     UDR0 = z;
78
}
Gast #2591243
Lesenswert?

Thomas Bergmüller schrieb:
> _delay_ms(1000);
> Dir ist klar dass das nicht hinhaut? Die Delayfunktionen funktionieren
> nur bis zu bestimmten Werten, siehe
> http://www.nongnu.org/avr-libc/user-manual/group__...
hast du dir überhaupt mal durchgelese was dort steht, wenn du schon die 
quelle angibst?

> When the user request delay which exceed the maximum possible one,
> _delay_ms() provides a decreased resolution functionality. In this
> mode _delay_ms() will work with a resolution of 1/10 ms, providing
> delays up to 6.5535 seconds (independent from CPU frequency). The
> user will not be informed about decreased resolution.


@Bruno In.
das delay ist ok.
#2591303
Lesenswert?

Martin Wende schrieb:
> Sagt das meinem AVRGCC, als ich mit AVR Anfing habe ich das \0 auch
> immer weggelassen und da stand dann aufm LCD der gesamte
> Speicherinhalt...

Du meinst nicht zufällig diese Art der Deklaration?
1
char str[]={'H','A','L','L','O','\0'};

oder sogar sowas?
1
str[0] = 'H';
2
str[1] = 'A';
3
str[2] = 'L';
4
str[3] = 'L';
5
str[4] = 'O';
6
str[5] = '\0';

Gruß Oliver
Persönliche Seite #2591361
Lesenswert?

Peter II schrieb:
> Martin Wende schrieb:
>> Sagt das meinem AVRGCC, als ich mit AVR Anfing habe ich das \0 auch
>> immer weggelassen und da stand dann aufm LCD der gesamte
>> Speicherinhalt...
> dann war der Fehler woanders, der (AVR)GCC hat no nie diesen Fehler
> gemacht.

Jedenfalls wurde solch ein Fehler nie berichtet, und ich hab die avr-gcc 
Fehler ziemlich genau im Blick.

Also Martin, her mit dem Testfall, der Compilerversion und den Optionen 
:-)
#2591654
Lesenswert?

ist das wirklich so, dass bei

while (*s){

und Inhalt = 0 die Schleife verlassen wird?

Davon abgesehen, das Programm hängt dann ewig in der schnarchlangsamen 
UART-Routine fest bei der Programmausführung.
Es wär evtl. sinnvoll mal über den TXC Flag zum Einen und den 
TXC-Interrupt im Besonderen nachzudenken.
#2592455
Lesenswert?

Peter II schrieb:
>> http://www.nongnu.org/avr-libc/user-manual/group__...
> hast du dir überhaupt mal durchgelese was dort steht, wenn du schon die
> quelle angibst?

Ich glaub ich muss mich entschuldigen, sehr peinlich... (wobei ich 
solche langen Delays üblicherweise mit einem Timer lösen würde, dann 
kann der Prozessor inzwischen was anderes tun (auch wenns hier im 
Beispiel wenig Sinn machen wird))
OP #2592554
Lesenswert?

Sorry, war den ganzen Tag auf dem Bau. Habe ja eine Flut von Antworten 
erhalten. Super, Werde es sofort durchchecken.


Karl Heinz Buchegger schrieb:
> Hast du die M103 Fuse abgeschaltet?

Nein. Werde ich sofort mal machen.

>_delay_ms(1000);

Die waren zum Testen, sonst resetet der so schnell.

>USART_Str("Hallo\0");

Auch schon versucht, gleiches Resultat.

>while (*s)

Hier habe ich schon getestet mit einem Aufruf ohne Pointer, genau 
dasselbe.


Danke für die vielen Hinweise.

bjn
OP #2592584
Lesenswert?

Das gibt's ja nicht, Du bist Super Karl Heinz.

> Karl Heinz Buchegger schrieb:
>> Hast du die M103 Fuse abgeschaltet?

Das war's schon, die M103 Fuse. Habe das mal nachgeschlagen im 
Datenblatt. Der wird ja mit dem Watchdog zusammen beschrieben. Steig 
leider nicht ganz durch, mein Englisch ist schwach ;-{ .

Und was ich gar nicht begreife, was hat das mit einem Funktionsaufruf 
zuntun.

Die Tiefen der Mikrokontroller.
Gast #2592591
Lesenswert?

Bruno In. schrieb:
> Und was ich gar nicht begreife, was hat das mit einem Funktionsaufruf
> zuntun.

überhaupt nichts.

> an ATmega103 compatibility mode can be selected by programming
> the fuse M103C
damit hat er andere Register und Upcodes - der µC hat also eine eine 
Sprache verstanden.
#2592628
Lesenswert?

Bruno In. schrieb:
> Und was ich gar nicht begreife, was hat das mit einem Funktionsaufruf
> zuntun.

Der Compiler ist von einem Mega128 ausgegangen, und hat Code erzeugt, 
der den Stack-Pointer auf das Ende des RAM des Mega128 initialisiert. 
Der Controller ist aber in Wirklichkeit ein Mega103 (wegen der Fuse). 
Bei dem endet das RAM eher (weil er weniger Register hat und daher das 
RAM auch eher anfängt). Somit zeigt der Stack-Pointer auf eine Adresse, 
an der gar kein RAM ist, und damit geht das erste ret mit ziemlicher 
Sicherheit in die Hose.

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