Komischer UART

Gast #3132314
Lesenswert?

Hallo,

ich programmiere gerade meinen ersten mega64. Der UART verhält sich 
komisch.

kann mit
1
int uart_putc(unsigned char c)
2
{
3
    while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
4
    {
5
    }                             
6
 
7
    UDR0 = c;                      /* sende Zeichen */
8
    return 0;
9
}

einzelne Zeichen verschicken

strings hingegen gehen nicht:
1
void uart_puts (char *s)
2
{
3
    while (*s)
4
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
5
        uart_putc(*s);
6
        s++;
7
    }
8
}

wenn ich so was in main stehen habe
1
int main(void)
2
{
3
  UART_init();
4
  sei();
5
  uart_putc('A');
6
    for(;;){
7
      //uart_putc('T');
8
      uart_puts("Huhu\r\n");
9
      _delay_ms(1000);
10
    }
11
    return 0;  
12
}

ist meine screen-Ausgabe
1
AHuhu
2
AHuhu
3
AHuhu
4
AHuhu
5
...

die Sekunde sind auch bei weitem nicht eingehalten. Packe ich nur ein 
char in den loop ist alles gut. da sag ich nur ---hä?---

Any hint?

Georg
Gast #3132330
Lesenswert?

Hi,

Die Theorie mit dem Watchdog hatte ich auch schon, habe aber nicht 
bewußt etwas umgestellt.

Habe gerade mal das delay rausgeschmissen und immernoch das gleiche

interessant ist auch folgende Codeveränderung
1
void uart_puts (char *s)
2
{
3
    while (*s)
4
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
5
        uart_putc(*s);
6
        s++;
7
    }
8
    uart_putc('X');
9
}

bewirkt keinerlei Änderung in der Ausgabe.

das \0 ist nicht als false erkannt

Schorsch
Gast #3132337
Lesenswert?

Ich meine mal das *s ein pointer ist und aus der while gehts nur raus 
wenn der mal zufällig auf die 0 kommt und damit meine ich nicht die 
ascii 0 sondern 0x00.

für so sachen ist meiner meinung nach die strlen(string) geschrieben 
worden.
Gast #3132686
Lesenswert?

Uwe schrieb:
>>     return 0;
> Wohin denn ?

Von der int main wird eine Rückgabe erwartet, auch wenn sie diese 
Codestelle nie erreicht. Das ist vollkommen richtig so.

Auch alles andere schaut für mich richtig aus / ist millionenfach 
bewährter Code. Ich würde den Fehler wirklich in der Konfiguration / der 
Hardware suchen. Da auch das 'A' immer wieder gesendet wird, sieht es 
für mich so aus, als würde der Controller reseten. Probier mal, ob eine 
längere Zeichenkette abgeschnitten wird.
Was ist das für eine Schaltung? Eval. Board oder Eigenbau?
Wie ist der Reset beschaltet? Kann dir da was rein spucken?
Hast du ein Oszi, mit dem du mal auf die Versorgungsspannung schauen 
kannst?
Gast #3132706
Lesenswert?

> als würde der Controller reseten.
bzw. der Stack ist kaputt oder wurde falsch initialisiert (z.B. durch 
falsche CPU definition. Watchdog in den Fuses aktiviert ?
Hast schon recht war nur ein passendes Fehlerbild.
Gast #3132739
Lesenswert?

Schorsch schrieb:
> ich programmiere gerade meinen ersten mega64. Der UART verhält sich
> komisch.

Schorsch schrieb:
> habe den Code für einen mega8 schon 100mal benutzt, da geht er,

Wenn sich der gleiche Code auf einem Mega8 korrekt verhält, auf einem 
Mega64 aber nicht, dann mußt Du die Unterschiede prüfen:
- Quarz?
- Fuses? Wichtig!!!
- Register richtig konfiguriert?
- Hardware drumherum?
Gast #3133404
Lesenswert?

Hallo,
sorry, das ich mich erst jetzt melde, musste den Tag über arbeiten...

ich versuche mal die meisten Fragen zu beantworten:

die Fuses stehen so

1
avrdude: Device signature = 0x1e9602
2
avrdude: safemode: lfuse reads as E0
3
avrdude: safemode: hfuse reads as 99
4
avrdude: safemode: efuse reads as FD

mit dem d in der e-fuse müsste der 103c-mode aus und der watchdog 
eigentlich an sein (p293 im Manual)

meine init-routine sieht so aus:
1
UBRR0H = (unsigned char)(UBRR_VAL>>8); 
2
UBRR0L = (unsigned char)UBRR_VAL; 
3
  
4
UCSR0B = (1<<RXEN0)|(1<<TXEN0);

wobei UBBR_VAL so definiert ist
1
#define F_CPU 14745600UL 
2
#define BAUD 115200UL 
3
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
4
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
5
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
6
 
7
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
8
  #error Systematischer Fehler der Baudrate gršsser 1% und damit zu hoch! 
9
#endif

Die Frage nach den Fuses und den Registern sollte hinreichend 
beantwortet sein.

Zum Board: siehe hier:
Beitrag "Atmega64 PDI/O und RXD/TXD gleichzeitig"

Zusammenfassend, durch einen Flüchtigkeitsfehler werden PDI/O und 
RXD/TXD bei mir doppelt verwendet, das ließ sich beheben, indem ich 4.7k 
in die RXD-Leitung gehängt habe.

Das der UART nun grundsätzlich funktioniert sollte hinreichend gezeigt 
worden sein. Das selbstständige resetten (Wechselwirkung UART in den 
Programmer ???) kann man ausschließen, da das gleiche Problem auch 
auftritt, wenn ich den Programmer abziehe


ah, nochwas
1
void uart_puts (char *s)
2
{
3
  uint8_t n = 0;
4
    while (*s)
5
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
6
        //uart_putc(*s);
7
        uart_putc(s[n]);
8
        s++;
9
    }
10
    uart_putc('X');
11
}

liefert mir immnoch die selbe Ausgabe. Laienhaft ausgedrückt, es scheint 
als zeit ein Pointer ins Nirvana und der Programmcode fängt wieder von 
vorn an. Ist das ein gcc-bug?


Schorsch
Gast #3133449
Lesenswert?

Ja es geht,

ganz, ganz großes Danke schön


ich war natürlich zu doof das Datenblatt zu lesen. efuse auf ff heißt, 
watchdog aus, 103c mode aus
1
avrdude: safemode: lfuse reads as E0
2
avrdude: safemode: hfuse reads as 99
3
avrdude: safemode: efuse reads as FF

Warum ist dieses Programm verherend mit einem Watchdog?

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