Forum: Mikrocontroller und Digitale Elektronik Wie geht ihr beim Debuggen vor?


von bushobbyentwickler (Gast)


Lesenswert?

Hallo,

ich habe in einem Programm den Fehler, dass ein Wert aus dem EEPROM 
gelesen wird und über UART an den PC gesendet wird. Dort kommen aber nur 
Werte kleiner 64 an. Wenn im EEPROM 0xFF drinsteht, dann wird 63 an den 
PC gesendet. Steht im EEPROM an der Stelle ein Wert kleiner 63, dann 
wird der richtige Wert über UART gesendet!
Ein anderer Fehler in diesem Programm ist, dass eine LED mit einer 
ungefähren Frequenz von 1Hz mittels eines Delays in der Endlosschleife 
in der Main blinkt. Sende ich Daten über UART an den MC, dann blinkt die 
LED extrem langsamer (60sec für an und aus anstatt 1sec)???

Da ich mit dem STK500 programmiere habe ich dazu eine allgemeine Frage:
Wenn ihr einen Fehler im  Programm habt und nich wisst woran es liegen 
kann, wie geht ihr dann vor, um den Fehler zu finden?

Vielen Dank schonmal

von daniel (Gast)


Lesenswert?

Hi,

prinzipiell sollte man sich nochmal den Code genau ansehen. Und nochmal 
das Funktionsprinzip ueberpruefen ob dieses auch wirklich korrekt 
umgesetzt wurde.
Erfahrung spielt beim Debuggen schon eine grosse Rolle, denn mit jedem 
Fehler den man findet, lernt man dazu.
Es gibt verschiedenen Fehler,die leichtesten sind die syntaktischen ;), 
das sind Fehler wo der Compiler meckert. Dann kommen die systematische, 
von den hast du 1 in deinem Programm(Fehler mit den Bits). Dass sind die 
wo der Compiler nicht mehr meckert, aber dafuer der Kunde :). Und dann 
kommen die ganz fiesen Fehler, dass sind dann die stochastischen, wo die 
systematik stimmt aber troztdem spinnt das Programm wegen den 
Interrupts. Passieren oft nur zufaellig und sind deswegen schwer zu 
finden. Davon hast du auch einen (deine LED) obwohl man den leicht 
findet. Das sind so die bekanntesten Fehlerklassen.
Am wichtigsten ist es immer den Code nochmal anschauen und ueberdenken 
was man da wirklich geschrieben hat. Dann auf die Variablen achten und 
vor allem die Array. (Schreibt man mehr daten in ein array als da hinein 
passen, dann schreibt der uC munter weiter im Speicher und ueberschreibt 
benachbarte Variablen im Speicher )

Fuer dein Problem mit dem UART kannst du schauen ob wirklich alle Bits 
deines Bytes uebergibts, oder ob nicht ein anderer Programmteil ein Teil 
des Bytes ueberschreibt. Denn 63 dez enspricht 00011111b (binaer), das 
bedeutet das deine obersten 3 bit von deinem Wert auf 0 gesetzt werden 
(durch ein AND irgendwo?, die Einstellung im UART?, ... )

Fuer dein Problem mit deiner LED, kann ich folgendes sagen. Da du sie in 
der Main- Schleife laufen laesst und die Zeit ueber eine Endlosschleife 
regelst, ,kann folgendes passieren. Dein Program in der "Main-Schleife" 
wird ausgefuehrt und ploetzlich moechte aber der UART ein Zeichen 
senden, dann hat der UART (ein Interrupt) Vorang (eine hoehere 
Prioritaet) vor deinem Program  und arbeitet sein Programmabschnitt(vom 
UART) ab. Wenn dieser nun sehr lang ist oder du dort auch noch 
Endlosschleifen einsetzt, dann arbeitet der Mikrocontroller die ganze 
Zeit am UART und zaehlt nicht mehr an der Endlosschleife im "main" 
weiter. Irgendwann ist er dann fertig mit dem UART und zaehlt nun noch 
zusaetzlich die Zeit deiner Endlosschleife ab. Aber halt, der 
Programmabschnitt vom UART Interrupt moechte nun nochmal senden ;).
So kann es leicht passieren das deine LED dann 1min braucht, statt 1s. 
Denn die Zeit deiner Endlosschleife in "main" und die mehrmalige Zeit 
vom dem "UART- Interrupt" (so oft er eben waerende der Endlosschleife 
senden moechte) addieren sich.

Hoffe es ist verstaendlich, wenn nicht weiterfragen.
daniel

von Online Debugger (Gast)


Lesenswert?

> Wenn im EEPROM 0xFF drinsteht, dann wird 63 an den
> PC gesendet. Steht im EEPROM an der Stelle ein Wert kleiner 63, dann
> wird der richtige Wert über UART gesendet!
du arbeitest irgendwo mit char, wo 'unsigned char' hin sollte.

von Spess53 (Gast)


Lesenswert?

Hi

Überprüfe mal, ob du nicht den 5Bit-Modus bei der UART eingestellt hast.

@ Online Debugger
'char' sollte eigentlich bis 127 gehen.

MfG Spess

von daniel (Gast)


Lesenswert?

korrektur zu meinem oberen Beitrag:

63 dez entspricht 00111111b (0x3F), es sind nur die obersten 2 Bit nicht 
korrekt.

daniel

von Kai G. (runtimeterror)


Lesenswert?

Ich würde das Programm in Einzelteile zerlegen und diese gezielt prüfen. 
Sicher, dass deine Datenquelle wirklich Zahlen > 63 erzeugt? Ich würde 
versuchen einen hart verdrahteten Wert zu übermitteln und alle nicht 
benötigten Programmteile auszublenden.

Wenn das dann immer noch nicht geht einfach die USART-Routine neu 
schreiben und wenn die funktioniert mit der alten vergleichen.

Wenn das Problem verschwindet liegt's an der Datenbeschaffung, für die 
uns hier noch ein paar Infos fehlen...

Viel Erfolg

Kai

von Kai G. (runtimeterror)


Lesenswert?

>Überprüfe mal, ob du nicht den 5Bit-Modus bei der UART eingestellt hast.

6 Bit meintest du vermutlich :)
Wehe daran liegt's - na gut, kann ja auch versehentlich passieren.

von lkmiller (Gast)


Lesenswert?

@bushobbyentwickler
Debuggen ist das Lösen eines Problems durch das Aufteilen in einzelne 
kleine Probleme (Teile und Herrsche).

Teil dein Problem in einzelne kleine Aufgaben auf:
1) Stell erst mal sicher, dass die serielle Schnitte funktioniert. Sende 
ein Zeichen vom PC zum AVR ändere die Bits (z.B. incrementieren, 
decrementieren, interiteren) und  schick das Zeichen zurück.
2) Wenn das geht, kommt das EEPROM dran....
3) Wenn das geht, ...

Alles gleichzeitig zum Laufen gekommen ist meines Wissens das letzte Mal 
bei Frankenstein (und das Ergebnis war nicht gut!).

von bushobbyentwickler (Gast)


Lesenswert?

Vielen Dank für die Antworten!

Zu dem Problem mit UART:
Ich habe mal probiert sonstwo in dem Programm einfach nur das Byte 0xFF 
rauszuschicken. Am PC kommt da nur '?' (0x3F) an.

Ich hab echt keine Ahnung woran es liegt...

Im ganze Programm schick ich hin und wieder Daten an den PC, allerdings 
nur kleine Werte (also nie über 63) deshalb fällt mir der Fehler jetzt 
erst auf...

von bushobbyentwickler (Gast)


Lesenswert?

Hier meine Funktionen, dies betrifft:
1
void UART_Init(void)
2
{
3
  DDRD = (1 << PD1) | (0 << PD0); 
4
5
  UCSRB |= (1 << RXCIE) | (0 << TXCIE) | (1 << RXEN) | (1 << TXEN);
6
7
  // Baudrate: 19200bps bei 8MHz
8
  UBRRL = 25;
9
  UBRRH = 0;
10
}
11
12
13
void UART_send_char(unsigned char data)
14
{
15
  while (!(UCSRA & (1<<UDRE)))
16
  {
17
    ;  // warten, bis UDR leer ist
18
  }
19
  UDR = data;
20
}

Sieht doch eigentlich gut aus oder?

von bushobbyentwickler (Gast)


Lesenswert?

Ich hab jetzt mal im HyperTerminal angeschaut was der MC scickt: y mit 
Doppelpunkt also 0xFF!!!!

Dann liegt der Fehler wohl an der Windows-Anwendung. Da verwende ich 
Visual Basic (2008) mit der integrierten COMport-Komponente. Dann wird 
da wohl irgendwo der Fehler liegen, obwohl eigentlich alles richtig 
eingestellt ist...

von Frank (Gast)


Lesenswert?

Vielleicht zeigt VB die nicht darstellbaren Zeichen (also 0xFF) nur 
einfach als '?' an.

von John G. (johngo)


Lesenswert?

Ich empfehle unbedingt einen richtigen Debugger zur Unterstützung der 
Fehlersuche. Ich weiß nicht, mit welchem Mikrocontroller du arbeitest, 
ich verwende z.B. den AVR Dragon für den Atmega168. Da kannst du dann 
den C-Sourcecode Zeile für Zeile durchsteppen, Variablen anschaun und 
ändern, und du kannst richtig "sehen" wohin das Programm läuft - 
wunderschön! Ohne Debugger ist es oft echt sehr sehr mühsam, es ist wie 
ein Tappen im Dunkeln und Raten, was das Programm wo vielleicht tut. 
Warum sich das Leben unnötig schwer machen, der Dragon kostet nicht die 
Welt!

von dirk (Gast)


Lesenswert?

Passt deine Baudrate wiklich ???

von Daniel F. (df311)


Lesenswert?

bushobbyentwickler wrote:
>
1
> void UART_Init(void)
2
> {
3
>   DDRD = (1 << PD1) | (0 << PD0);
4
> 
5
>   UCSRB |= (1 << RXCIE) | (0 << TXCIE) | (1 << RXEN) | (1 << TXEN);
6
> }
7
> 
8
>
>
> Sieht doch eigentlich gut aus oder?

eine 0 irgendwohin zu schieben ist absolut sinnlos, da es immer eine 0 
bleiben wird, und "irgendwas oder 0" immer "irgendwas" bleibt.

(logische) linksschiebeoperationen kann man sich auch wie eine 
multiplikation mit einer 2er-potenz vorstellen, also

umgekehrt "entspricht" eine rechtsschiebeoperation einer 
ganzzahldivision durch eine zweierpotenz.

zum thema uart:
besorg dir das programm "portmon" (afair von sysinternals), damit kannst 
du die komplette kommunikation über die serielle und parallele 
schnittstelle(n) aufzeichnen.
da du mit hyperterminal bereits "richtigere" daten empfangen hast als 
mit vb, check mal die baudraten- und formateinstellung der vb-komponente 
und rechne nochmal nach, ob der uC wirklich eine brauchbare baudrate 
erzeugt...

von Andreas K. (a-k)


Lesenswert?

Daniel F. wrote:

> eine 0 irgendwohin zu schieben ist absolut sinnlos, da es immer eine 0
> bleiben wird, und "irgendwas oder 0" immer "irgendwas" bleibt.

Nicht "sinnlos" sondern "wirkungslos". Es ist hier durchaus sinnvoll, da 
es dokumentiert, dass beispielsweise der RX Interrupt ausgeschaltet 
bleibt.

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


Lesenswert?

Andreas Kaiser wrote:

> Nicht "sinnlos" sondern "wirkungslos". Es ist hier durchaus sinnvoll, da
> es dokumentiert, dass beispielsweise der RX Interrupt ausgeschaltet
> bleibt.

Dann müsste man aber immer alle 8 Bits hinschreiben.

Außerdem ging es hier um eine »|=«-Operation, dann bleibt der
Rx-Interrupt trotzdem eingeschaltet, sofern er es vorher schon war.
In diesem Kontext also wirklich sinnlos.

von lkmiller (Gast)


Lesenswert?

@ Daniel F.

1 x 2 = 4, das hat was ;-)

Das Schieben einer 0 ist zur Dokumentation sinnvoll
und kostet keine Rechenzeit, weil das ja der Compiler schon ausrechnet.


Großbuchstaben sind im Deutschen anerkannte Hilfsmittel zur 
Textdarstellung.
Sie verringern die Lesbarkeit eines Textes nicht im Mindesten.
Ähnlich wie z.B. auch Umlaute und Doppelkonsonanten.

von Daniel F. (df311)


Lesenswert?

'tschuldigung, hatte vorher 1 << 1 - da habe ich wohl vergessen, die 2 
in 4 zu ändern

aja, und das mit der Kleinschreibung ist wohl z.t. auch Schuld meiner 
Professoren - die schreiben auch alles klein ;-)

von JensG (Gast)


Lesenswert?

@ bushobbyentwickler (Gast)
> Ich hab jetzt mal im HyperTerminal angeschaut was der MC scickt: y mit
> Doppelpunkt also 0xFF!!!!

Das ist ein allgemeines Problem, wobei ich mir immer noch nicht sicher 
bin, wie die Logik dahinter ist in manchen Windowskomponenten.
wie Du schon selbst schreibst, kommt im Terminal das 0xff als y mit 
Diaeresis  ÿ an, was also der Codierung entsprechend der 
Windows-Codepage 1252 entspricht. Eigentlich müsste das immer so sein, 
und wäre auch logisch. Allerdings scheint dies auch vom benutzten Font 
abzuhängen, ob dies dann richtig angezeigt wird, oder als Fragezeichen 
(ein beliebtes Ersetzungszeichen unter Windows, mit 0x3F codiert), oder 
in manchen Programmen gar als einfaches Kästchen (was nach reinem 
Anzeigeproblem ausschaut).
Beispiel: Datei mit hex werten ff 30 9f 39 3f 30 unter Windows
Problem bei mir (mit WinXP) scheint zumindest das 9f zu sein in einigen 
Programmen.
Wordpad (write) und notepad zeigen alles richtig an (ÿ0Ÿ9?0)
Der Lister im Total Commander zeigt dagegen ein Kästchen anstelle des 
großen Y mit Diaeresis an. Kopiere ich diesen verunstalteten String ins 
Notepad, wird's plötzlich wieder richtig angezeigt (was aber auch nichts 
generell sicherstellt). Scheinbar schießt der eingestellte Font hier 
quer, oder die vom Programm benutzten Runtime-Libs eincompilierter Code 
taugen an der Stelle nicht viel. Die VB Libs scheinen da also auch 
irgendwie ihr eigenes Ding zu drehen.
Wenn Du die Möglichkeit hast, die empfangenen Bytes erstmal als Hex 
anzuzeigen, dann kannst Du ja damit erstmal die empfangenen Daten 
checken.

von bushobbyentwickler (Gast)


Lesenswert?

Das (0 << TXCIE) hab ich drin, weil ich zum Debuggen den TX-Interrupt 
ausgestellt habe, also kein Stress!!! ^^

Den Portmon werde ich mal ausprobieren. Wie gesagt: In Hyperterminal 
kommt das richtige Zeichen an, nur in meiner Visual Basic - Anwendung 
nicht.

Bei der Komponente ist Baudrate, Anzahl Daten- und Stopbits sowie 
Parität auch richtig eingestellt...

Stelle ich im MC und in der Anwendung eine andere Baudrate (z.B. 9600) 
ein, habe ich genau das gleiche Problem, dass die empfangenen Zeichen 
nur Werte von 0 bis 63 haben können!

0011 1111 = 63
-> sieht halt schon sehr danach aus, dass die letzten beiden Bits (LSB 
kommt in UART ja zuerst oder?) verdaddert werden...

von bushobbyentwickler (Gast)


Lesenswert?

[quote]Wordpad (write) und notepad zeigen alles richtig an (ÿ0Ÿ9?0)
Der Lister im Total Commander zeigt dagegen ein Kästchen anstelle des
großen Y mit Diaeresis an. Kopiere ich diesen verunstalteten String ins
Notepad, wird's plötzlich wieder richtig angezeigt (was aber auch nichts
generell sicherstellt). Scheinbar schießt der eingestellte Font hier
quer, oder die vom Programm benutzten Runtime-Libs eincompilierter Code
taugen an der Stelle nicht viel. Die VB Libs scheinen da also auch
irgendwie ihr eigenes Ding zu drehen.
Wenn Du die Möglichkeit hast, die empfangenen Bytes erstmal als Hex
anzuzeigen, dann kannst Du ja damit erstmal die empfangenen Daten
checken.[/quote]

Ich habe das betreffende Zeichen schonmal mit Str(Asc(...)) umgewandelt 
und in einer MsgBox anzeigen lassen. Und da steht dann der Dezimalwert 
63.

Aber ein interessanter Gedanke. Vielleicht entspricht in dem 
Zeichensatz, der von der Comport-Komponente verwendet wird das 
Fragezeichen '?' dem Wert 0xFF, und bei der Umwandlung mit Asc(...) wird 
nach dem dem ASCII-Wert des Zeichens (und nicht nach dem Wert im von der 
COM-Komponente verwendeten Zeichensatz) gesucht?!?

von JensG (Gast)


Lesenswert?

ich glaube, 0xff entpricht in keinem Zeichensatz einem Fragezeichen (im 
Gegenteil, in den meisten Codepages ist dort sogar gar kein Zeichen oder 
ein Steuerzeichen). Aber vielfach wird da '?' einfach als 
Ersetzungszeichen verwendet von manchen Win-Komponenten (möglicherweise 
auch in VB), vermutlich einfach in der Annahme, daß das ohnehin kein 
gültiges Zeichen wäre (vielleicht aus historischen Gründen, wo noch 437 
und 850 intensiv genutzt wurden, wo 0xFF ein Sonderzeichen war)
VB enthält wohl immer noch solche Relikte ....

von lkmiller (Gast)


Lesenswert?

Google einfach mal nach OCCONSOLE
oder schau da vorbei
http://www.elektronikladen.de/occonsole.html

Das Teil ist super, läuft ohne Installation vom USB-Stick
und hat den Binär-Modus, wo ein FF als FF angezeigt wird.
Wird leider nicht mehr weiterentwickelt :(

von bushobbyentwickler (Gast)


Lesenswert?

Das Teil ist wirklich super!!!

Also der MC sendet 0xFF, dann liegt es 100%ig an der VB-Komponente.

von bushobbyentwickler (Gast)


Angehängte Dateien:

Lesenswert?

Also hier mal ein Bild von den Einstellungen der SerialPort-Komponente.
Weiß jemand, was hier der Auslöser sein könnte, dass die ReadExisting 
63d zurückgibt obwohl 255d gesendet (und mit einem Terminal-Programm) 
empfangen wurde?

von Kai G. (runtimeterror)


Lesenswert?

Kommt denn eine 62d an, wenn du 254d übermittelst? Nicht, dass die 63d 
gar nichts mit den übertragenen Bytes zu zun hat.

von bushobbyentwickler (Gast)


Lesenswert?

Ich hab gestern die Lösung gefunden.

Wenn ich den InPuffer der VB-Komponente mit der Funktion ReadExisting 
auslese, enthält der zurückgegebene String nur Werte zwischen 0 und 63 
(wieso auch immer).

Lese ich den Puffer dagegen byteweise mit ReadByte aus, dann werden 
Werte von 0 bis 255 ausgegeben!

Es gibt auch noch eine Funktion ReadChar, die allerdings wie 
ReadExisting nur Werte von 0 bis 63 ausgibt.

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.