Forum: Mikrocontroller und Digitale Elektronik Problem mit UART


von Thomas (Gast)


Lesenswert?

Hallo,

ich bin ein Anfänger und habe dieses Programm für meinen atmega32 
geschrieben:

Config Portc.7 = Output
Dim I As Byte
Do
I = Inkey()
If I = 0 Then
     Portc.7 = 1
       Exit Do
  else
       Portc.7 = 0
       Print "1"
  End If
Loop



Dieses Programm soll den UART auslesen und eine LED einschalten, bzw. 
auschalten, wenn der UART eine "1" liefert.

Mein Problem ist, dass das Programm nicht funktioniert: Egal in welchen 
Teil der Verzweigung ich das Print "1" als Rückgabewert schreibe, er 
wird immer zurückgeliefert, auch wenn ich gar nichts sende.


Woran kann das liegen?

Thomas

von Karl H. (kbuchegg)


Lesenswert?

Thomas wrote:

> wird immer zurückgeliefert, auch wenn ich gar nichts sende.

Wenn du gar nichts sendet, wartet Inkey nicht auf das Einlangen
eines Zeichens, sondern liefert 0 zurück.

Vorher IsCharWaiting aufrufen, um festzustellen, ob über die
UART überhaupt etwas empfangen wurde.


PS: Diese Antwort konnte mit google und dem Suchstring
"BASCOM Inkey" in 20 Sekunden ermittelt werden.

von Thomas (Gast)


Lesenswert?

Mh, danke, aber leider funktioniert es immer noch nicht.
Mein Code sieht jetzt so aus:



Config Portc.7 = Output
Dim I As Byte
Do
If Ischarwaiting() <> 0 Then
I = Inkey()
If I = 1 Then
     Portc.7 = 1
     Print "0"
  else
       Portc.7 = 0
       Print "1"
  End If
  End If
Loop


Wer hat eine Idee, woran es liegen könnte?

Thomas

von Karl H. (kbuchegg)


Lesenswert?

Thomas wrote:

> I = Inkey()
> If I = 1 Then

Wenn du auf deinem Terminal auf die Taste '1' drückst, dann
wird der ASCII Code für '1' gesendet. Der ist aber nicht 1
sondern 49

Siehe: jede beliebige ASCII Tabelle die du im Netz finden kannst.

(Preisfrage, wie müsste denn dann deine Abfrage aussehen,
wenn du den Vergleich nicht auf '1' sondern auf 'z' aufbauen
möchtest)

Alternativ könnte man in BASCOM aber wahrscheinlich auch

   if I = '1' then

schreiben. Aber da ich BASCOM überhaupt nicht kann und auch
in nächster Zeit nicht vorhabe zu lernen, schau ich einfach in
die BASCOM Hilfe und lese dort nach und gebe das dort gelesene
hier einfach zum Besten. Und den Rest rate ich einfach mal
ein bischen (so wie den Vergleich auf '1' anstelle von
   if I = 49 then     # 49 ist der ASCII Code von '1'

Möglicherweise müsste es

   if I = "1" then

heissen, da ich nicht weiss ob BASCOM in seiner Syntax zwischen
einzelnen Zeichen und Strings unterscheidet.

Edit:
Es muss tatsächlich

  if I = "1" then

lauten.

von Thomas (Gast)


Lesenswert?

Mh, es geht immer noch nicht. Ich habe als Alternative mal dieses 
Programm übertragen:

Do
If Ischarwaiting() = 1 Then
Print "1"
End If
Loop


Dieses Programm sollte ja eine "1" zurücksenden, sobald man über den 
UART etwas sendet, oder?

Leider funktionieert auch das nicht.

Thomas

von Karl H. (kbuchegg)


Lesenswert?

Thomas wrote:
>
> Leider funktionieert auch das nicht.

Dann sollten wir mal die grundsätzliche Funktion des UART in
Frage stellen:

* Welche Taktrate fährt dein µC
* Bist du sicher, dass diese Taktrate auch wirklich am µC
  eingestellt ist.
  Hinweis: Es genügt nicht, nur in BASCOM hinzuschreiben, dass
  deine Taktrate zb 3456789 Mhz beträgt. Da muss schon ein
  Quarz mit dieser Frequenz an den Prozessor angeschlossen sein
  und der Quarz muss auch aktiviert sein.
* Falls du einen Quarz dran hast und der auch tatsächlich aktiviert
  ist, hast du BASCOM auch mitgeteilt, mit welcher Taktrate dein
  Quarz arbeitet?
* Ich seh in deinem Code auch nirgends eine Vereinbarung der Baudrate


http://www.rowalt.de/mc/avr/avrboard/03/avrb03.htm

von Thomas (Gast)


Lesenswert?

"Dann sollten wir mal die grundsätzliche Funktion des UART in
Frage stellen:
* Welche Taktrate fährt dein µC
* Bist du sicher, dass diese Taktrate auch wirklich am µC
  eingestellt ist.
  Hinweis: Es genügt nicht, nur in BASCOM hinzuschreiben, dass
  deine Taktrate zb 3456789 Mhz beträgt. Da muss schon ein
  Quarz mit dieser Frequenz an den Prozessor angeschlossen sein
  und der Quarz muss auch aktiviert sein.
* Falls du einen Quarz dran hast und der auch tatsächlich aktiviert
  ist, hast du BASCOM auch mitgeteilt, mit welcher Taktrate dein
  Quarz arbeitet?"


Ich habe einen 16 Mhz Quarz angeschlossen, ich habe oben im Bascom Code 
"$crystal = 16000000" stehen, ich habe die FUsebits gesetzt.

Das Senden von Daten vom Controller zum PC funktioniert auch, nur 
andersrum gibt es Probleme.


Mir ist noch folgendes aufgefallen:

Schreibe ich diesen Code, kommt es zu einer Endlosschleife und es werden 
sehr viele "1" in sehr kurzer Zeit übertragen:

"Print "1"
Do
If Ischarwaiting() = 1 Then
Print "1"
End If
Loop"

von Karl H. (kbuchegg)


Lesenswert?


von Thomas (Gast)


Lesenswert?

Ich habe folgendes über den eigentlichen COde stehen:

$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 16000000
$baud = 9600



Thomas

von Karl H. (kbuchegg)


Lesenswert?

In der Hilfe zu IsCharWaitung ist ein Beispielprogramm.
Hast du das schon mal ausprobiert?

http://avrhelp.mcselec.com/index.html

von Thomas (Gast)


Lesenswert?

Leider helfen mir die beiden Seiten auch nicht weiter . :-(

vll. noch eine Sache: Ich benutze das Programm "htern" als 
Terminalprogramm und Windows vista als Betriebssystem.


Thomas

von Thomas (Gast)


Lesenswert?

Ja, habe ich ausprobiert, auch erfolgslos...

von Karl H. (kbuchegg)


Lesenswert?

Thomas wrote:
> Leider helfen mir die beiden Seiten auch nicht weiter . :-(

Dann wirds schwierig.
Wenn die Demo-Programm aus der BACOM Hilfe nicht funktionieren
und deine Hardware einwandfrei funktioniert (Quarz drann und auch
aktiv; da ein Senden bei dir funktioniert glaube ich dir das
auch), dann liegt ein Problem vor, welches von hier aus so gut
wie nicht diagnostizierbar ist.

> vll. noch eine Sache: Ich benutze das Programm "htern" als
> Terminalprogramm und Windows vista als Betriebssystem.

Ist egal. Hauptsache irgendein Terminalprogramm welches
Zeichen senden und empfangen kann.


Noch was: Was liefert denn INKEY zurück?
Vielleicht lässt sich aus dem Wert der kommt etwas ableiten.

von Thomas (Gast)


Lesenswert?

Wie kann ich denn herrausfinden, welchen Wert Inkey() zurückliefert, 
wenn das nicht richtig funktioniert?

Mir ist aber noch was aufgeallen:

Wenn ich diesen Code benutze, passiert gar nichts:

"Do
If Ischarwaiting() = 1 Then
Print "1"
End If
Loop"



Wenn ich diesen Code benutze, kommen sehr viele "1" in kurzer Zeit an. 
Woran liegt das denn?

"Print "1"
Do
If Ischarwaiting() = 1 Then
Print "1"
End If
Loop"


Thomas

von Karl H. (kbuchegg)


Lesenswert?

Thomas wrote:
> Wie kann ich denn herrausfinden, welchen Wert Inkey() zurückliefert,
> wenn das nicht richtig funktioniert?

Ich denke du hast die Demos aus der BASCOM Hilfe ausprobiert?
Die machen genau das: Die UART abfragen, und zurückgeben
was empfangen wurde. Und da deine Ischarwaiting ständig 1
zurückliefert,ist sie offenbar der Meinung, dass etwas
empfangen wurde.

von Karl H. (kbuchegg)


Lesenswert?

Aus der BSACOM Hilfe zusammengestopselt

$regfile = "m32def.dat"
$crystal = 16000000
$framesize = 32
$swstack = 32
$hwstack = 32
$baud = 9600

Dim A As Byte

Do
  A = Inkey()               'get ascii value from serial port
  Print "ASCII code " ; A ; " from serial"
Loop

End


Das sollte eigentlich nach meinen Verständnis ständig
ASCII code 0 from serial
ausgeben.
Und wenn eine Taste gedrückt wird (zb. '1' ) dann sollte
einmalig
ASCII code 49 from serial
auftauchen

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.