Forum: Mikrocontroller und Digitale Elektronik 89C2051 Bascom Reset durch RS232 !


von Mos K. (moscito)


Lesenswert?

Hallo erstmal,

komme leider bei meinem Projekt nicht weiter und würde mich über jeden
Tip freuen...

Zielsetzung: über's Internet den PC einschalten und dann einen
Kamerawagen fernsteuern :-)

Basis ist ein XPORT (RS232/Ethernet/Webserver) von Lantronix, welcher
ein von mir gebasteltes Java Applet zum Betrachterbrowser hochlädt.
Der User erzeugt durch anklicken der Schaltflächen verschiedene ASCII
Zeichen am Ausgang des XPORT's. Diese werden von einem 89C2051
ausgewertet und in Outputs umgesetzt.

Das Ganze funktioniert auch wunderbar, aber es kommt häufig vor, daß
der 89C2051 sich resettet wenn Zeichen reinkommen. Insbesondere, wenn
die Zeichenfolgen schnell hintereinander kommen.
Das Java Applet kann ich ausschließen, denn der gleiche Effekt
entsteht, wenn ich die Zeichen mit dem Terminal schicke.

Hier mal eben das Proggi für den Micro:

$regfile = "89c2051.dat"
$crystal = 11059200
$baud = 9600

Dim A As Byte
Dim C As Byte
Print "Xport RS232 I/O Extension V1.0"
Print "(c) JK 04/2005"
Print " "
Print "Aux2=p1.6, Aux1=P1.5, CPU=P1.4, P1.3= RI, P1.2=BW, P1.1=LE,
P1.0=FW"
Print ""
P1 = 0
Do
 A = Waitkey()
   If A <> C Then
      P1 = P1 And &B11110000
   End If
   If A <> 0 Then
   A = Chr(a)
       Select Case A
           Case "a" : Set P1.0
                     Set P1.1
                     Print "Forward - Left"
           Case "s" : Set P1.0
                     Print "Forward"
           Case "d" : Set P1.0
                      Set P1.3
                     Print "Forward - Right"
           Case "y" : Set P1.2
                      Set P1.1
                     Print "Backward - Left"
           Case "z" : Set P1.2
                      Set P1.1
                     Print "Backward - Left"
           Case "x" : Set P1.2
                     Print "Backward"
           Case "c" : Set P1.2
                     Set P1.3
                     Print "Backward - Right"
           Case "C" : Set P1.4
                     Print "CPU on"
           Case "V" : Reset P1.4
                     Print "CPU off"
           Case "D" : Set P1.5
                     Print "Aux1 on"
           Case "F" : Reset P1.5
                     Print "Aux1 off"
           Case "E" : Set P1.6
                     Print "Aux2 on"
           Case "R" : Reset P1.6
                     Print "Aux2 off"
           Case Else
                P1 = P1 And &B11110000
                     Print "Stop"
       End Select
       Print ""
    End If
    C = A

Loop


Hab absolut keinen Schimmer mehr, was ich noch machen soll.

Hat von euch einer noch 'ne Idee???
Wäre echt schade um das Projekt :-(((


Moscito

von crazy horse (Gast)


Lesenswert?

mit deinem Programm kann ich dir nicht weiterhelfen, aber es scheint mir
eher ein Stromversorgungsproblem sein. Betreibst du auch den 2051 mit
3,3V oder hast du Pegelwandler eingesetzt?
Poste mal den Schaltplan.

von Mos K. (moscito)


Angehängte Dateien:

Lesenswert?

Hallo Crazy horse,

nen Schaltplan für genau dieses Projekt hab ich noch nicht, aber einen
für eines meiner Parallelprojekte auf gleicher Basis. Hier sind es nur
mehr Steckdosen. Zum Thema Pegel: Der Xport läuft mit 3.3V ist aber
RXD-mäßig 5V tolerant. Dem 2051 scheinen die 3.3V im RXD zu reichen.
Der Reset Anschluß zum Xport ist ein eigener Ausgang des Xports mit
welchem ich den 2051 resetten kann.

von Schau Mal (Gast)


Lesenswert?

Datenempfang ueber 'polling' oder 'interrupt' ?

von Mos K. (moscito)


Lesenswert?

Über Polling

A = Waitkey()

von crazy horse (Gast)


Lesenswert?

da würde ich doch als erstes mal die reset-Verbundung auftrennen...
Ausserdem solltest du sowohl dem 2051 als auch dem XPORT je einen 100nF
spendieren, beim XPORT zusätzlich einen 4µ7. So dicht wie möglich an die
Versorgungspins.

von Schau Mal (Gast)


Lesenswert?

ein Q=22.118 MHz beschleunigt die bearbeitung der 'case'
folglich ... weniger chancen daten zu verlieren

von Mos K. (moscito)


Lesenswert?

Upps- blöde back funktion.

Da hast du sicher Recht, aber erklärt das den Reset?
Bei 9600 Baud läuft doch eh alles auf Halbgas...
Ich werde mal Reset Leitung weg machen. Die 100nF Kondis sind außerdem
schon dran - fehlen nur in der Zeichnung.

Melde mich später nochmal...

von Mos K. (moscito)


Lesenswert?

Also: die Resetleitung ist weg - der 2051 hat nen 100nF Kondi direkt
drüber gelötet - der XPort hat nen 100nF und nen 4,7uF direkt drüber
gelötet - trotzdem noch das gleiche Problem :-((

von crazy horse (Gast)


Lesenswert?

gehen denn die print-Befehle auf die serielle Schnittstelle? Wenn ja,
hast du zumindest ein timing-Problem, wenn du die Schnittstelle im
polling betreibst. Ein Zeichen kommt rein, jetzt beginnt dein Programm
zu rattern und muss je nach Zeichen bis zu 15 Bytes ausgeben, das
dauert natürlich. In dieser Zeit ist nach deiner Methode kein Empfang
möglich. Das erklärt aber nur das Verschlucken von Befehlsbytes, nicht
jedoch einen Reset. Habe lange nichts mehr mit dem 2051 gemacht, wie
verhält sich die UART, wenn sie neue Zeichen bekommt, bevor alte
abgeholt wurden?
Auf jeden Fall solltest du die UART zumindest beim Empfang im Interrupt
betreiben und einen oder 2 Buffer einrichten.

von TriccyMan (Gast)


Lesenswert?

moin moin,

warum wird der CD+ vom ULN per K11 geschaltet? Die K1..K7 liegen doch
immer an 12P. Da muss auch der CD+ ran oder fehlt der Strich?
Dem Q2 würde ich einen Basiswiderstand gönnen.


Mit Gruß vom
TriccyMan

von crazy horse (Gast)


Lesenswert?

jo, bei genauerer Betrachtung...
-Pin9 ULN2003 sollte auf jeden Fall fest auf +12V (oder jedem Relais
eine eigene Diode spendieren)
-an K11 fehlt die Diode auch
-fehlenden Basiswiderstand kann man bei TTL verschmerzen, hat die
Ausgangsstufe intern,

-K8,9 und 10 können auch nicht funktionieren, der 2051 kann keinen
nennenswerten Strom bei H-Pegel liefern, Dioden fehlen auch da.

von Mos K. (moscito)


Lesenswert?

Zuerst mal vielen Dank an alle für die rege Teilnahme !

Crazy Horse:
die print statements gehen in der Tat zurück zum XPort und dann zum
User in das Applet als Kontrolle. Ist ne interessante Überlegung, daß
sich send/receive überschneiden. Sehr wahrscheinlich sogar. Werde
testhalber mal die prints auskommentieren. Guter Gedanke!

TriccyMan:
Der ULN wird per Relais erst zugeschalten, wenn die CPU läuft.
Beim Reset gehen nämlich sämtliche Ausgänge kurzzeitig auf "high".
Mal 8 Steckdosen + 3 Funksteckdosen mal mehrere 400W Computer Netzteile
und anderes Geraffel = Tschüß 16A Sicherung :-)
Das Ganze mußte mit Xor gemacht werden, so muß P3.3/P3.2
unterschiedliche Pegel zum Schalten haben (kontrolliert).
Q2 ist ohne Basis R bei TTL unkritisch.

Zu den Relais:

K8,9,10,11 sind printrelais mit integrierter Diode. Hab nix besseres im
Eagle gefunden...

Hmmm... das mit K8-10 high Pegeln stimmt. Ist auch der bisher einzige
ungestestete Teil der Schaltung. Danke !

von crazy horse (Gast)


Lesenswert?

zum Problem der Anschaltung aller Relais im reset-Zustand: dazu ist
deine Schaltungsidee völlig ungeeignet, kann gut sein, dass alle deine
Probleme daher kommen.
Entweder nimmst du einen Treiber, der mit L-Pegel angesteuert wird
(habe früher viel mit 8051 gearbeitet, daher ist mir die Problematik
noch vertraut, habe immer den ULN2595 genommen) oder alle ULN-Eingänge
über Dioden zusammenfassen und mit einem Transistor nach Masse
schalten. Bei Reset ist dieser Transistor dann ach leitend und zieht
somit alle Ports nach L.

von Sebastian Heyn (Gast)


Lesenswert?

Hi,

bist du sicher das dein programm fehlerfrei compiliert?

dim a as byte

If A <> 0 Then
   A = Chr(a)
   select case a
       .
       .


ich weiss nicht wie bascom8051 damit umgeht, aber dein A=CHR(a) ist
irgendwie nicht ganz plausibel.  richtig wäre

dim a as byte
dim a_Str as string*1

If A <> 0 Then
   A_str = Chr(a)
   select case A_str

von Sebastian Heyn (Gast)


Lesenswert?

dann verstehe ich die If a<>0 nicht. da du ja waitkey() machst muss dein
a an dieser stelle ja ungleich 0 sein, oder?

von Sebastian Heyn (Gast)


Lesenswert?

kleiner tip: um code zu sparen würde ich nicht mit strings arbeiten,
lass die ganze chr-fummelei weg, und arbeite direkt mit ascii-codes
also

select case a
case &h41: anweisung   '"A" empfangen


ausserdem ziehen deine relais zwar an, aber werden nicht wieder
gestoppt. das könnte problematisch sein (sorry falls ich dünn labere -
ich habe nicht in deine schaltpläne geschaut)

von Sebastian Heyn (Gast)


Lesenswert?

Läuft es jetzt????

von Mos K. (moscito)


Lesenswert?

Hallo Sebastian,

danke erst mal für Deine Antworten.

Habe mich heute darauf konzentriert alle print Anweisungen
auszukommentieren um zu verhindern, daß Daten nicht empfangen werden,
weil noch welche gesendet werden. Außerdem habe ich die
Programmierleichen (A<>0 etc.) entfernt.
Das Ergebnis ist noch immer das gleiche.

Werde heute noch die von Dir vorgeschlagene einfachere Abfrage
einhacken, erwarte mir allerdings keine Änderung.

Ich melde mich später nochmal

von Sebastian Heyn (Gast)


Lesenswert?

Ich glaube der hauptfehler dürfte
A = Chr(a)
sein.

von Mos K. (moscito)


Lesenswert?

Hallo Sebastian,

es ist kaum zu glauben: Jetzt funzt es !!!
Es lag offensichtlich an der Chr Anweisung.
Wie kann das denn zu einem Reset führen??? Ist mir echt schleierhaft.
Habe dann die Print Anweisungen wieder eingefügt - geht immer noch :-)
Selbst bei der mir größtmöglichen Klickfrequenz :-)

Achso: das mit den nicht abfallenden Relais ist gewollt. Die sollen so
lange angezogen bleiben, bis das Stop Signal kommt, damit das Fahrzeug
weiter fährt ohne daß man ständig klicken muß.

Vielen Dank!

Und zum guten Schluß noch der aktuelle Code:

$regfile = "89c2051.dat"
$crystal = 11059200
$baud = 9600

Dim A As Byte
Dim C As Byte
Print "Xport RS232 I/O Extension V1.1"
Print "(c) JK 03/2006"
Print " "
Print "Aux2=p1.6, Aux1=P1.5, CPU=P1.4, P1.3= RI, P1.2=BW, P1.1=LE,
P1.0=FW"
Print ""
P1 = 0
Do
 A = Waitkey()
   If A <> C Then
       P1 = P1 And &B11110000
   End If
       Select Case A
           Case &H61 : Set P1.0
                     Set P1.1
                     Print "Forward - Left"
           Case &H73 : Set P1.0
                     Print "Forward"
           Case &H64 : Set P1.0
                      Set P1.3
                     Print "Forward - Right"
           Case &H79 : Set P1.2
                      Set P1.1
                     Print "Backward - Left"
           Case &H7A : Set P1.2
                      Set P1.1
                     Print "Backward - Left"
           Case &H78 : Set P1.2
                     Print "Backward"
           Case &H63 : Set P1.2
                     Set P1.3
                     Print "Backward - Right"
           Case &H43 : Set P1.4
                     Print "CPU on"
           Case &H56 : Reset P1.4
                     Print "CPU off"
           Case &H44 : Set P1.5
                     Print "Aux1 on"
           Case &H46 : Reset P1.5
                     Print "Aux1 off"
           Case &H45 : Set P1.6
                     Print "Aux2 on"
           Case &H52 : Reset P1.6
                     Print "Aux2 off"
           Case Else
                P1 = P1 And &B11110000
                     Print "Stop"
       End Select
       C = A
       Print ""

Loop

von Sebastian Heyn (Gast)


Lesenswert?

Das heißt du stoppst erst bevor du die Richtung änderst?
dann könntest du ja auch

If A <> C Then
       P1 = P1 And &B11110000
       Select Case A
           Case &H61 : Set P1.0
                     Set P1.1
                     Print "Forward - Left"
           Case &H73 : Set P1.0
                     Print "Forward"
           Case &H64 : Set P1.0
                      Set P1.3
                     Print "Forward - Right"
           Case &H79 : Set P1.2
                      Set P1.1
                     Print "Backward - Left"
           Case &H7A : Set P1.2
                      Set P1.1
                     Print "Backward - Left"
           Case &H78 : Set P1.2
                     Print "Backward"
           Case &H63 : Set P1.2
                     Set P1.3
                     Print "Backward - Right"
           Case &H43 : Set P1.4
                     Print "CPU on"
           Case &H56 : Reset P1.4
                     Print "CPU off"
           Case &H44 : Set P1.5
                     Print "Aux1 on"
           Case &H46 : Reset P1.5
                     Print "Aux1 off"
           Case &H45 : Set P1.6
                     Print "Aux2 on"
           Case &H52 : Reset P1.6
                     Print "Aux2 off"
           Case Else
                P1 = P1 And &B11110000
                     Print "Stop"
       End Select
       C = A
END IF
       Print ""

das endif ein stückchen nach hinten versetzen und damit wenn der
gleiche knopf gedrückt wurde cpu zeit sparen, grins
Versuche mich auch grad mit nem 8051.. ist n bisschen anders als avr
...

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.