Forum: Mikrocontroller und Digitale Elektronik Endlich neue Probleme! :-(


von Philipp Buchmann (Gast)


Lesenswert?

Hallo,

ich habe mal wieder ein neues, zurzeit nicht nachvollziehbares Problem.
Ich habe folgenden Code:
1
// Dateien inkludieren
2
  .include "m32def.inc"
3
// Variablen definieren
4
  .def temp=r16
5
// Einstellungen
6
  /* Watchdog (de-)aktivieren */
7
  ldi temp,(1<<WDTOE)|(1<<WDE)
8
  out WDTCR,temp
9
  nop
10
  nop
11
  nop
12
  nop
13
  ldi temp,(0<<WDE)
14
  out WDTCR,temp
15
//Datenrichtungsregister setzen
16
  ldi temp,(1<<DDD5)
17
  out DDRD,temp
18
// Hauptcode
19
  ldi temp,(1<<PORTD5)
20
  out PORTD,temp
21
  rjmp ende
22
  ende:
23
  rjmp ende
24
// SRAM konfigurieren

Was soll der Code machen? Ganz einfach! Er schaltet (eigentlich) den 
Watchdog aus und schaltet danach eine LED an.
Nur komisch ist, dass wenn ich den Watchdog entferne,
1
// Dateien inkludieren
2
  .include "m32def.inc"
3
// Variablen definieren
4
  .def temp=r16
5
// Einstellungen
6
  /* Watchdog (de-)aktivieren */
7
//Datenrichtungsregister setzen
8
  ldi temp,(1<<DDD5)
9
  out DDRD,temp
10
// Hauptcode
11
  ldi temp,(1<<PORTD5)
12
  out PORTD,temp
13
  rjmp ende
14
  ende:
15
  rjmp ende
16
// SRAM konfigurieren

alles funktioniert.
Wenn das nicht so ist, dann oszilliert die LED mit einem hohen Takt (ich 
glaube aber nicht mit dem Takt des AVRs...zu langsam).

Erkennt Ihr den Fehler? Für die, die sich fragen, warum ich nicht gleich 
eine Konstante in das Register tem (=r16) lade, kann ich nur sagen, dass 
ich ein bisschen experimentiert bzw. rumprobiert habe...

Danke im Voraus!

von MagIO (Gast)


Lesenswert?

Ähm ... und?

Das ist doch genau das wofür der Watchdog gut ist! Wenn der Watchdog 
nicht periodisch zurückgesetzt wird (von deinem Code), dann löst er 
einen Reset aus.

Deine Endlosschleife setzt nix zurück!

Also hast Du ständig Resets, die natürlich erst mal alle Ports auf 
Eingang zurücksetzen -> LED geht aus.

von Philipp Buchmann (Gast)


Lesenswert?

Aha!

Danke für die Antwort.
Ich habe also den Watchdog gesetzt...

Wie muss ich dann die Register setzen, damit der Watchdog DAUERHAFT 
abgeschaltet wird? Das war nämlich eigentlich mein Ziel.

Toll wäre es, wenn man meinen Code einfach nur verbessert und statt 
Konstanten (z.B. 0b00101101) durch z.B. 1<<******** ersetzen.

Danke im Voraus!

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Hier isses mal für einen Tiny85:
1
   cli      ; first switch off the WD
2
  wdr  
3
  in   temp, MCUSR  ; clr the WDRF bit
4
  andi   temp, (0xff & (0<<WDRF))
5
  out   MCUSR, temp
6
; Write logical one to WDCE and WDE
7
; Keep old prescaler setting to prevent unintentional time-out
8
  in   temp, WDTCR
9
  ori   temp, (1<<WDCE) | (1<<WDE)
10
  out   WDTCR, temp
11
; Turn off WDT
12
  ldi   temp, (0<<WDE)
13
  out   WDTCR, temp
Die entsprechende Prozedur sollte eigentlich im Datenblatt deines Mega32 
stehen.

von Philipp Buchmann (Gast)


Lesenswert?

Aha!

Ich habe mich im Datenblatt verlesen! Ich dachte man muss WDTOE und WDE 
setzen und 4 Takte später den WDE entfernen.
Aber ich muss eigentlich INNERHALB von 4 Takten den WDE entfernen.
Jetzt geht es. Der Watchdog ist nun ausgeschaltet.

Nun habe ich allerdings neue Probleme:

Ich wollte den UART mal testen und wollte einfach mal die Zahlen 25, 36 
und 103 an den PC schicken, die dann mithilfe des Terminalprogramms YAT 
auf dem Bildschirm dargestellt werden.
Natürlich geht auch das nicht, weil sich irgendein klitzekleines Problem 
eingemischt hat.

Findet Ihr den Fehler?
1
// Dateien inkludieren
2
  .include "m32def.inc"
3
// Variablen definieren
4
  .def temp=r16
5
  .def zeichen=r17
6
// Einstellungen
7
  /* Watchdog (de-)aktivieren */
8
  ldi temp,(1<<WDTOE)|(1<<WDE)
9
  out WDTCR,temp
10
  ldi temp,(0<<WDE)
11
  out WDTCR,temp
12
  /* UART (de-)aktivieren */
13
  ldi temp,LOW(RAMEND)
14
  out SPL,temp
15
  ldi temp,HIGH(RAMEND)
16
  out SPH,temp
17
  ldi temp,6
18
  out UBRRH,temp
19
  ldi temp,6
20
  out UBRRL,temp
21
  ldi temp,(1<<RXEN)|(1<<TXEN)
22
  out UCSRB,temp
23
  ldi temp,(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
24
  out UCSRC,temp
25
//Datenrichtungsregister setzen
26
  ldi temp,(1<<DDD5)|(1<<DDD6)
27
  out DDRD,temp
28
// Hauptcode
29
  rjmp abfrage_0
30
  abfrage_0:
31
  ldi zeichen,25
32
  sbis UCSRA,UDRE
33
  rjmp abfrage_0
34
  out UDR,zeichen
35
  abfrage_1:
36
  ldi zeichen,36
37
  sbis UCSRA,UDRE
38
  rjmp abfrage_1
39
  out UDR,zeichen
40
  abfrage_2:
41
  ldi zeichen,103
42
  sbis UCSRA,UDRE
43
  rjmp abfrage_0
44
  out UDR,zeichen
45
  rjmp warte
46
  warte:
47
  ldi  r18,0x10
48
  WGLOOP0:
49
  ldi  r19,0xF8
50
  WGLOOP1:
51
  ldi  r20,0xFB
52
  WGLOOP2:
53
  dec  r20
54
  brne WGLOOP2
55
  dec  r19
56
  brne WGLOOP1
57
  dec  r18
58
  brne WGLOOP0
59
  ldi  r18,0x30
60
  WGLOOP3:
61
  dec  r18
62
  brne WGLOOP3
63
  rjmp abfrage_0
64
// SRAM konfigurieren

Danke im Voraus!

von Jim M. (turboj)


Lesenswert?

> die Zahlen 25, 36 und 103 an den PC schicken [...]

Dein Code schickt aber die Zeichen 25, 36 (ASCII $) und 103 (ASCII g) 
raus. Zahlen müsstest Du erst nach ASCII konvertieren, als Hexadezimal 
ist das etwas leichter.

von Spess53 (Gast)


Lesenswert?

Hi

>  ldi temp,6
>  out UBRRH,temp
>  ldi temp,6
>  out UBRRL,temp

Danach ist UBRR = 0x0606! Verrate mal mit welcher Taktfrequenz dein 
Controller läuft und welche Baudrate du erreichen willst. Ich finde 
dafür keine sinnvolle Kombination. Und dein Controller läuft hoffentlich 
mit einem Quarz. Mit dem internen Oszillator sind Probleme 
vorprogrammiert.

>  ......
>  rjmp abfrage_0
>  abfrage_0:
>  ldi zeichen,25
>  sbis UCSRA,UDRE
>  rjmp abfrage_0
>  ....
>  abfrage_2:
>  ldi zeichen,103
>  sbis UCSRA,UDRE
>  rjmp abfrage_0    <<<<<<<<<<<<<
>  out UDR,zeichen
>  rjmp warte
>  .....

MfG Spess

von Spess53 (Gast)


Lesenswert?

Hi

Nachtrag: Programmierst du eigentlich am Handy? Oder weshalb klebt der 
Code so am linken Rand?

MfG Spess

von Dietrich L. (dietrichl)


Lesenswert?

Philipp Buchmann schrieb:
> Findet Ihr den Fehler?

- Welchen µC hast Du?
- Mit welchem Takt arbeitet er?
- Welche Baudrate willst Du einstellen?
- Hast Du mal am Ausgang TX gemessen, ob da was rauskommt? Mit Oszi, 
ggf. mit LED (dazu Baudrate "runterdrehen")?
- Funktioniert das Terminalprogramm (TX und RX des nicht am µC 
angeschlossenen Kabels brücken), dann müsste man auf dem Bildschirm als 
Echo sehen, was man eintippt.
- Stimmt die Terminalprogramm-Einstellung?
- Hast Du einen Pegelwandler (z.B. MAX232) am µC und arbeitet er?
- Hast Du ein "richtiges" Kabel zwischen µC und PC (TX von PC auf RX vom 
µC und RX von PC auf TX vom µC)?

Gruß Dietrich

von Philipp Buchmann (Gast)


Lesenswert?

Hallo,

> - Welchen µC hast Du?
Ich verwende den ATmega32.
> - Mit welchem Takt arbeitet er?
Er arbeitet mit 1 MHz (interner RC-Oszillator --> ungenau!)
> - Welche Baudrate willst Du einstellen?
Ich möchte 9600 Baud verwenden.
> - Hast Du mal am Ausgang TX gemessen, ob da was rauskommt? Mit Oszi,
> ggf. mit LED (dazu Baudrate "runterdrehen")?
Werde ich noch tun.
> - Funktioniert das Terminalprogramm (TX und RX des nicht am µC
> angeschlossenen Kabels brücken), dann müsste man auf dem Bildschirm als
> Echo sehen, was man eintippt.
Werd ich auch noch tun.
> - Stimmt die Terminalprogramm-Einstellung?
Mit Sicherheit ja. Alle Einstellungen sind korrekt.
> - Hast Du einen Pegelwandler (z.B. MAX232) am µC und arbeitet er?
Ich benutze das Atmel Evaluatuions-Board mit dem eingebauten MAX232.
> - Hast Du ein "richtiges" Kabel zwischen µC und PC (TX von PC auf RX vom µC
> und RX von PC auf TX vom µC)?
Ja, ich verwende dafür ein Nullmodemkabel.

MfG

Ph. Buchmann

von Svenska (Gast)


Lesenswert?

Stell mal runter auf 1200 Baud, eventuell auch noch weniger. Der interne 
Oszillator ist zu ungenau.

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


Lesenswert?

Svenska schrieb:
> Der interne
> Oszillator ist zu ungenau.

Das ist erstens eine Urban Legend, und zweitens würde das
Heruntersetzen der Baudrate daran genau gar nichts ändern.
Die Genauigkeitsforderung für RS-232 ist nämlich relativ, und
ob man nun 9600 Bd mit ±2% einhält oder nur 1200 Bd, ist völlig
schnuppe.

Das Einzige, warum man nicht trotzdem größere Baudraten benutzen
kann ist, dass man für die Taktfrequenz von 1 MHz im Verhältnis zu den
"krummen" üblichen Baudraten dann irgendwann keinen Teilerfaktor
mehr findet, bei dem die statische Abweichung vom Sollwert (also
der systematische Fehler) nicht bereits zu groß wäre für eine
RS-232-Kommunikation.  Bei 1 MHz und 9600 Bd ist das aber nicht
der Fall (sofern man vom U2X-Bit Gebrauch macht), von daher bringt
eine weitere Reduktion der Datenrate dann nichts mehr.

Philipp Buchmann schrieb:
> Wie muss ich dann die Register setzen, damit der Watchdog DAUERHAFT
> abgeschaltet wird?

Du brauchst ihn einfach nur nicht einzuschalten, das macht er nämlich
nicht von selbst.  Man muss ihn entweder durch Software einschalten,
oder aber durch eine Fuse.  In letzterem Falle kannst du ihn aber
gar nicht mehr abschalten, sondern musst ihn in der Software sauber
immer wieder beruhigen.

von Spess53 (Gast)


Lesenswert?

Hi

>Er arbeitet mit 1 MHz (interner RC-Oszillator --> ungenau!)
>> - Welche Baudrate willst Du einstellen?
>Ich möchte 9600 Baud verwenden.

Wenn du dir die Baudraten-Tabellen im Datenblatt angesehen hättest, dann 
wüßtest du, da schon bei korrekten 1MHz 7% Fehler herauskommen.

>Ja, ich verwende dafür ein Nullmodemkabel.

Du brauchst ein 1:1-Kabel.

MfG Spess

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


Lesenswert?

Spess53 schrieb:
> Wenn du dir die Baudraten-Tabellen im Datenblatt angesehen hättest, dann
> wüßtest du, da schon bei korrekten 1MHz 7% Fehler herauskommen.

Nur, wenn man vergisst, bei U2X=1 nachzusehen. ;-)  Gut, im
entsprechenden Steuerregister muss man das Bit natürlich dann
auch noch setzen, das fehlt da oben im Code.  Dafür fummeln sie
alle bienenfleißig und völlig sinnlos am Steuerregister C herum,
dessen Voreinstellung für das gängige "8N1"-Framing (wer hätte es
gedacht?) bereits exakt passend sind.  Aber man kann sich ja nie
sicher sein, ob Atmel das nicht bloß aus lauter langer Weile so
ins Datenblatt schreibt und dann gar nicht implemementiert ...

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.