Forum: Compiler & IDEs [Atmega8 + STK500] UART-Probleme


von Chris (Gast)


Lesenswert?

Hallo.
Ich habe einen Atmega8 und ein STK500 und versuche damit gerade 
ADC-Werte über UART an den PC zu senden...

Den Quellcode zum Senden habe ich vom Tutorial:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART

Das komische ist, dass es eine kurze Zeit funktioniert.
Jedesmal wenn ich auf den RESET-Button am STK-500 drücke kommen ein paar 
Zahlenwerte vom ADC (die auch richtig sind).
Aber nach ca. 1s hört er auf.

Mir ist auch aufgefallen, dass wenn der ADC-Wert 3-stellig ist, ich 16 
Zahlen bekomme und wenn der Wert nur 2-stellig ist, ich sogar 20 Werte 
erhalte. Manchmal steht nach der letzten Zahl auch ein Sonderzeichen. 
Manchmal siehts aus wie ein t, manchmal ein ü oder '...


Hier der Quellcode:

main.c:
1
#include <avr/io.h>
2
#include <stdlib.h> // itoa
3
#include "myUART.h"
4
#include "myADC.h"
5
#include <util/delay.h>
6
7
// MAIN
8
int main(void){
9
10
  // LEDs initialisieren
11
  DDRB  = 0xFF;
12
  PORTB = 0x00;
13
14
  // UART initialisieren
15
  uart_init();
16
17
  // ADC initialisieren
18
  ADC_Init();
19
20
  // Variablen definieren
21
  uint16_t adcval;
22
  char s[7];
23
24
while(1){
25
26
  // ADC auslesen
27
  adcval = ADC_Read(0);
28
29
  //uart_puts("\n\r");
30
  //uart_puts("Hello world\n\r");
31
32
  // UART senden
33
  itoa(adcval, s, 10);  // 10 steht fuer radix (Dezimalsystem)
34
  uart_puts(s);
35
36
  // Da itoa einen Zeiger auf den Beginn von s zurueckgibt verkuerzt auch:
37
  //uart_puts(itoa(adcval,s,10));
38
39
  // UART senden
40
  uart_puts("\n\r");        // Zeilenumbruch
41
42
  //_delay_ms(1000);
43
}
44
return 0;
45
} //*/// END of main

myUART.h:
1
#include <avr/io.h>
2
3
void uart_init(void);
4
int uart_putc(unsigned char c);
5
void uart_puts (char *s);

myUART.c:
1
#include "myUART.h"
2
3
/* 
4
  UART-Init: 
5
Berechnung des Wertes für das Baudratenregister 
6
aus Taktrate und gewünschter Baudrate
7
*/
8
9
#ifndef F_CPU
10
11
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 2000000"
12
#define F_CPU 2000000UL  // Systemtakt in Hz - Definition als unsigned long beachten 
13
                         // Ohne ergeben sich unten Fehler in der Berechnung
14
#endif
15
 
16
#define BAUD 9600UL      // Baudrate
17
 
18
// Berechnungen
19
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
20
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
21
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
22
 
23
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
24
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
25
#endif
26
27
28
29
/* UART-Init Bsp. ATmega16 */
30
 
31
void uart_init(void)
32
{
33
  UBRRH = UBRR_VAL >> 8;
34
  UBRRL = UBRR_VAL & 0xFF;
35
 
36
  UCSRB |= (1<<TXEN);  // UART TX einschalten
37
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
38
}
39
40
41
int uart_putc(unsigned char c)
42
{
43
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
44
    {
45
    }                             
46
 
47
    UDR = c;                      /* sende Zeichen */
48
    return 0;
49
}
50
 
51
 
52
/* puts ist unabhaengig vom Controllertyp */
53
void uart_puts (char *s)
54
{
55
    while (*s)
56
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
57
        uart_putc(*s);
58
        s++;
59
    }
60
}

von Klaus W. (mfgkw)


Lesenswert?

Wie genau stimmt die Baudrate?

von Chris (Gast)


Lesenswert?

Keine Ahnung.
Ich weiß leider nicht wie man die Baudrate misst oder wo sie angezeigt 
wird...

von Chris (Gast)


Lesenswert?

Ich glaub auch nicht wirklich, dass da was falsch ist, denn die werte 
werden immer richtig ausgegeben. Wenn ich die Baudrate am terminal 
umstelle kommt natürlich Mist raus, aber in allen Fällen bricht er das 
senden nach kurzer Zeit ab. Auch am Oszi hab ich kurz rumprobiert. Wenn 
ich reset drücke, sehe ich kurz ein paar Flanken, aber danach ist wieder 
alles ruhig.

Ich glaub halt es liegt am Code, dass der µC nach kurzer Zeit zum Senden 
aufhört.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Nimm dir einen ATmega88 und debug' es via debugWIRE.

von Karl H. (kbuchegg)


Lesenswert?

Wenn du kein DebugWire hast, hast du vielleicht noch ein paar LED am µC?

Die würde ich mal benutzen:
2 LED

Vor dem ADC auslesen die 1. LED ein
ADC auslesen
die 1. LED wieder ausschalten

vor der Ausgabe die 2.te LED ein
ausgeben
danach die 2.te LED wieder aus


Fragestellungen:
Wenn der UART Datenstrom aufhört, hört dann auch das Geblinke der LED 
auf?
Wenn ja: Welche LED ist als letztes eingeschaltet?

von Attila C. (attila)


Lesenswert?

Ich empfinde den Reset-Knopf am STK500 als völlig unbrauchbar. Ich 
benutze immer den Power Schalter um einen Reset auszulösen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Attila Ciftci schrieb:
> Ich empfinde den Reset-Knopf am STK500 als völlig unbrauchbar.

Warum denn das?

von Attila C. (attila)


Lesenswert?

Weil (zumindest bei meinem STK) beim Drücken des reset Knopfes der µC 
sich "zu verschlucken" scheint. Mehrmaliges Drücken hilft manchmal aber 
"am saubersten" ist der Power Schalter.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Attila Ciftci schrieb:
> Weil (zumindest bei meinem STK) beim Drücken des reset Knopfes der µC
> sich "zu verschlucken" scheint.

Sehr seltsam.  Der Knopf wird über die Firmware des STK-Controllers
gepollt und dann als /RESET über einen Levelshifter (diskret
aufgebaut wie alle beim STK500) weitergereicht.

Hast du mal einen Oszi da dran gehalten?  Bei mir prellt da nichts.

von Attila C. (attila)


Lesenswert?

Ich wollte nur dem Chris einen Hinweis geben das es vielleicht Teil 
seines Problems ist. Ich habe ein LCD am Atmega8 dran und beim drücken 
des reset am STK kommen da auch gerne irgendwelche Sonderzeichen. Ein 
"richtiges" power off lässt den Atmega wieder machen was er soll.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Attila Ciftci schrieb:
> Ich wollte nur dem Chris einen Hinweis geben das es vielleicht Teil
> seines Problems ist.

Ich würde es für einen Fehler in deinem STK halten.

von Attila C. (attila)


Lesenswert?

Schon möglich, daher sagte ich ja auch "vielleicht".

von Chris (Gast)


Lesenswert?

Mir ist nicht aufgefallen, dass sich das STK500 anders verhält, wenn ich 
es aus- und wieder einschalte (anstelle des Reset-Buttons).

Karl Heinz Buchegger schrieb:
> Wenn du kein DebugWire hast, hast du vielleicht noch ein paar LED am µC?
>
> Die würde ich mal benutzen:
> 2 LED
>
> Vor dem ADC auslesen die 1. LED ein
> ADC auslesen
> die 1. LED wieder ausschalten
>
> vor der Ausgabe die 2.te LED ein
> ausgeben
> danach die 2.te LED wieder aus
>
>
> Fragestellungen:
> Wenn der UART Datenstrom aufhört, hört dann auch das Geblinke der LED
> auf?
> Wenn ja: Welche LED ist als letztes eingeschaltet?

Ich kann dir versichern, dass es daran nicht liegt. Egal ob ich jetzt 
ein "hello world" oder nur einen einzelnen char wiederholt ausgebe, es 
hört nach kurzer Zeit auf.

Allerdings hab ichs jetzt mal eine LED am PD1(TXD) angeschlossen und 
siehe da: Sie leuchtet und leuchtet und leuchtet. Muss wohl doch an der 
Baudrate liegen. Allerdings bin ich davon ausgegangen, dass wenn die 
Baudrate nicht stimmt, trotzdem irgendetwas empfangen wird.

Vielleicht liegts an den Einstellungen am STK500 und im AVR Studio !?
Der XTAL1-Jumper ist gesetzt.
>Datenblatt:
>> When the XTAL1 jumper is connected, the STK500 internal clock system
>> is used as main clock to the target AVR.

OSCSEL-Jumper Pin 1 und 2 sind verbunden.
>Datenblatt:
>> On-board software clock signal connected (default)

In den Project configuration options im AVR studio sind 2MHz 
eingestellt.
Wenn das STK500 verbunden ist, sind folgende Einstellungen zu sehen:
Fuses:
SUT_CKSEL (Clock Source) ist auf "Int. RC Osc. 2MHz; Start-up time: 6 CK 
+ 64ms" eingestellt.
Advanced:
Oscillator Calibration Byte: "Select Frequency"
(es würden noch 1,2,4 und 8MHz zur Auswahl stehen)
HW Settings:
Clock Generator: 3.686 MHz

Ich habe auch schon mal die Frequenz von 2Mhz auf 3.686MHz umgestellt, 
da sich der Clock Generator nicht genau auf 2Mhz einstellen lässt, aber 
da kamen am Terminal nur irgendwelche Sonderzeichen raus, also nehme ich 
mal an das der Clock Generator nicht aktiv ist...? Stimmt das ?

Es ist halt etwas verwirrend für mich, da man an so vielen Stellen die 
Frequenz einstellen muss.

Beim STK500 ist auch noch ein "Crystal"-Anschluss, der bei mir frei ist.
Ich hätte noch einen 2MHz und einen 4MHz Quarz rumliegen. Ich habe auch 
schon einen drauf gehabt und versucht, über diesen den µC zu takten, 
aber da kam am Terminal nie was brauchbares an. Vielleicht sind auch nur 
die Jumper am STK500 falsch gesetzt oder die Clock Source im AVR Studio 
falsch eingestellt ? Ich hab schon einige Varianten ausprobiert, aber 
ich weiß nicht, welche die Richtige ist...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Chris schrieb:
> Wenn das STK500 verbunden ist, sind folgende Einstellungen zu sehen:
> Fuses:
> SUT_CKSEL (Clock Source) ist auf "Int. RC Osc. 2MHz; Start-up time: 6 CK
> + 64ms" eingestellt.

Vermutlich willst du eher nicht mit dem internen RC-Oszillator
arbeiten, wenn du eine exakte Frequenz haben möchtest.

Der Generator auf dem STK500 ist aus Sicht des AVRs übrigens ein
"external clock", wenngleich die meisten Einstellungen für einen
externen Quarz genauso funktionieren werden.

von J.-u. G. (juwe)


Lesenswert?

Chris schrieb:
> Ich kann dir versichern, dass es daran nicht liegt.

Woran liegt es nicht? Karl Heinz hat doch gar keine mögliche Ursache 
angegeben, sondern Dir nur einen Weg beschrieben, den Fehler 
einzugrenzen.

von Karl H. (kbuchegg)


Lesenswert?

> Ich kann dir versichern, dass es daran nicht liegt.
> Egal ob ich jetzt ein "hello world" oder nur einen einzelnen char
> wiederholt ausgebe, es hört nach kurzer Zeit auf.

Ja und?
Irgendwas friert ein. Und da keiner weiß was, muss man sich erst mal 
einen Überblick verschaffen, was denn eigentlich einfriert.

> Allerdings hab ichs jetzt mal eine LED am PD1(TXD) angeschlossen
> und siehe da: Sie leuchtet und leuchtet und leuchtet.

Siehst du. Die soll nämlich gar nicht leuchten. Die sollte eigentlich 
flackern, weil da ja eine Übertragung rauskommen sollte. Dein Test hat 
jetzt eigentlich nur gezeigt: Dein µC friert ein. Gut, damit ist der PC 
erst mal aus dem Schneider, an dem liegt es nicht. Das ist jetzt aber 
keine wirklich weltbewegende Erkentnis und war zu erwarten.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Die sollte eigentlich
> flackern, weil da ja eine Übertragung rauskommen sollte.

Meinst du, das würde man optisch von Dauerleuchten unterscheiden
können?  Ich würde mal ein Oszillonuckel da dran klemmen.

von J.-u. G. (juwe)


Lesenswert?

Jörg Wunsch schrieb:
> Meinst du, das würde man optisch von Dauerleuchten unterscheiden
> können?

Spätestens, wenn das auskommentierte _delay_ms(1000) wieder eingefügt 
wird.

PS:
Wobei es dann wahrscheinlich ohne weitere Änderungen am Code aussähe, 
als würde die LED gar nicht leuchten.

von Karl H. (kbuchegg)


Lesenswert?

Jörg Wunsch schrieb:
> Karl Heinz Buchegger schrieb:
>> Die sollte eigentlich
>> flackern, weil da ja eine Übertragung rauskommen sollte.
>
> Meinst du, das würde man optisch von Dauerleuchten unterscheiden
> können?

9600 Baud?

Ja, das flackert noch wunderbar. Mit noch geringerer Baudrate sieht man 
es noch viel besser, aber 9600 ist noch gut erkennbar.

ALs ich noch kleiner Programmierknecht auf einer VAX war, hatte der 
Admin immer so einen Zwischenstecker mit ein paar LED dabei.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

J.-u. G. schrieb:
> Jörg Wunsch schrieb:
>> Meinst du, das würde man optisch von Dauerleuchten unterscheiden
>> können?
>
> Spätestens, wenn das auskommentierte _delay_ms(1000) wieder eingefügt
> wird.

Dann erst recht nicht.  TxD = high ist ja der Ruhezustand, und
das würde dann nur von ein paar Impulsen unterbrochen.

Wenn man die LED mal zwischen Ausgang und Masse und mal zwischen
Ausgang und Vcc anklemmt, und sie leuchtet in beiden Positionen,
dann werden Daten übertragen. ;-)

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.