Forum: PC-Programmierung µC von PC steuern


von cyberhazard (Gast)


Lesenswert?

Hallo,

zuerst mein Vorhaben:

Ich möchte einen AVR Mikrocontroller zum steuern bzw. regeln benutzen:
An einigen Ports sitzen sensoren (z.B. Lichtschranken) und an anderen 
Aktoren (z.B. Schalter oder einfach nur Dioden).
Den Controller versehe ich mit einem Programm, das auf bestimmte 
Sensoren mit den jeweiligen Aktoren reagiert (Regelung durch logik).


Nun mein Problem:

Ich möchte eine seriele Verbindung (RS232 o. USB) vom µC zum PC 
realisieren, um die jeweiligen Port-Zustände abzufragen und zu 
verändern: z.B.:

sbit P23 = P2^3;
sbit P24 = P2^4;
sbit P25 = P2^5;
void main()
{if ((P23==1) && (P24==1))
{P25=1;
printf("Port 2.3 und Port 2.4 sind gesetzt!");}}

Wenn an den Ports P2.3 und P2.4 ein "High-Signal" anliegt, leuchtet an 
Port P2.5 eine LED. Außerdem wird folgende Meldung ausgegeben: "Port 2.3 
und Port 2.4 sind gesetzt!" Zusätzlich zu den Sensoren am µC soll auch 
der PC die Ports zusätzlich steuern können.  Die µC-Steuerung sollte 
aber nach wie vor auch funktionieren, wenn der PC mal ausgeschaltet ist.


Zu meinem Wissensstand:

Ich bin Stundent der Informationstechnik und habe geringe Erfahrung mit 
Mikrocontrollern (AT89S52). Habe ein bisschen per RS232 
in-system-programmiert.

Nun will ich die PC-Verbindung nicht nur zum Laden des Programms in den 
µC nutzen sondern auch den µC mit dem PC steuern.

Ich bin seit ca. einem Jahr begeistert von der Mikrocontroller-Technik 
und war erstaunt, dass es dazu solche tollen Foren gibt!

Ich freue mich über eure Ratschläge!

von Stefan (Gast)


Lesenswert?

Das Projekt ist machbar.

Für einen Proof-of-Concept oder Demonstrator würde ich auf der PC Seite 
noch nicht mit der Programmierung anfangen. Stattdessen würde ich auf 
der PC-Seite ein übliches Terminalprogramm verwenden, um mit dem µC zu 
kommunizieren.

Auf der µC-Seite ist die Kommunikation über RS232 noch einfacher. Der 
Schlüssel zum Projekt ist ein gutes Verständnis der 
Interruptprogrammierung.

Später, wenn die Applikation an Dritte übergeben werden soll, würde ich 
dann PC-Seitig eine eigene Applikation schreiben. Sourcecode und 
Libraries zum Ansteuern der RS232 gibt es massig. Es ist halt abhängig 
davon welches deine bevorzugte Programmiersprache ist.


von x . (cyberhazard)


Lesenswert?

Erstmal danke für die Antwort.

habe die letzten Tage intesiv gegoogelt und bin auf folgendes Programm 
gestoßen:
Terminal v1.9b by Br@y
Was sehe ich in diesem Terminalprogramm? Bis jetzt nur ein großes graues 
Feld mit zahlreichen (nicht unbekannten!) Einstellungen rundherum. Kann 
ich mit diesem Programm die Ports einsehen und verändern?

Werde mich mit der Interruptprogrammierung befassen (muss ich sowieso, 
weil ich noch eine Fachprüfung in Assembler ablegen muss!).
Sendet der µC Interruptsignale an den PC oder umgekehrt?
Was für eine Kommunikation habe ich davon?

Es wird in jedem Fall darauf hinaus laufen, dass ich dann ein 
ausführbares (Exe-Datei) Programm mit Grafikoberfläche (z.B. Borland 
c++) habe, wo ich die Portpin-Zustände überwachen und gegebenfalls durch 
einen Klick auf den jeweiligen Button ändern kann.

Das Project soll später meine Studienarbeit werden!
Es soll dann später eine Art "Baukasten" werden aus Mikrocontroller, 
einigen Sensormodulen und einigen Aktormodulen. Womit man verschiedene 
Steurungen und Regelungen "zusammenstecken" kann.

Es soll Technik-Abgeneigten veranschaulichen, dass man unbegrenzte 
möglichkeiten hat seine Fantasie zu verwirklichen!

von Stefan (Gast)


Lesenswert?

Oha, da hapert es aber am Verständnis, was µCs so machen bzw. wie so ein 
Projekt aufgebaut ist.

Die Ports auf dem µC kannst du mit diesem Programm nicht direkt 
verändern. Mit dem Bray-Terminalprogramm kannst du die serielle 
Schnittstelle auf dem PC einstellen (Baudrate, Bitzahl, Handshake,...) 
und du kannst sehen was vom µC gesendet wird und du kannst Zeichen an 
den µC senden. Mehr im Prinzip nicht.

Deine Portsteuerung müsste selbstständig auf dem µC laufen. Dort braucht 
es dafür aber ein entsprechendes, selbstgeschriebenes Programm. Mit dem 
PC und dem Terminalprogramm oben gibst du diesem µC-Programm 
"Text"-Anweisungen und zwar über eine serielle Kommunikation. D.h. das 
µC_Programm wickelt die Kommunikation mit dem PC ab (Senden, Empfangen), 
macht eine Auswertung des Empfangenen und setzt es in Portbefehle etc. 
um.

Da Zustandänderungen an Ports und an der seriellen Schnittstelle 
voneinander unabhängig auftreten, empfielt es sich mit Interrupts zu 
arbeiten. Eine Aufgabe in einem Bereich kann durch Zustandänderungen in 
einem anderen Bereich unterbrochen werden.

Für den Einstieg würde ich auf dem µC ein Progrämmelchen schreiben, 
welches Zeichen empfängt, diese verändert (z.B. Kleinschrift in 
Grossschrift und vice versa) und dann an den PC zurücksendet. Hierbei 
ist die Interruptprogrammierung noch nicht zwingend notwendig. Man kann 
auch "von Hand zu Fuss" die serielle Kommunikation abwickeln. Stichwort 
hier Polling-Verfahren. Den Einstieg zum schreiben dieses 
Progrämmelchens gibt es im AVR-Tutorial für Assembler und im 
AVR-GCC-Tutorial für C.

Im nächsten Schritt könnte das Progrämmelchen anfangen das Empfangene 
als Befehle zu interpretieren z.B. "1" heisst mit Port xyz dies machen, 
"2" heisst mit Port xyz das machen. Und so weiter, bis die 
Wunschapplikation auf dem µC läuft. Paralle dazu könnte man von 
Polling-Verfahren auf das Interrupt-Verfahren umstellen.

von x . (cyberhazard)


Lesenswert?

Stefan wrote:
> Oha, da hapert es aber am Verständnis, was µCs so machen bzw. wie so ein
> Projekt aufgebaut ist.

nicht unbedingt! Ich würde es schon hinkriegen, eine µC-Schaltung zu 
basteln, Sensoren (z.B. Schalter) und Aktoren (z.B. LED's) dranzuklemmen 
und dank "Keil µVision" ein selbstgeschriebens Programm in den µC laden 
und es zum Funktionieren bringen! Das habe ich bereits im FH-Labor 
hinter mir!

Mein Problem liegt viel mehr darin, dass ich die Aktoren nicht nur durch 
die Sensoren  steuern/reglen will, sondern auch durch die 
Tastatur-Tasten!

> Deine Portsteuerung müsste selbstständig auf dem µC laufen. Dort braucht
> es dafür aber ein entsprechendes, selbstgeschriebenes Programm. Mit dem
> PC und dem Terminalprogramm oben gibst du diesem µC-Programm
> "Text"-Anweisungen und zwar über eine serielle Kommunikation. D.h. das
> µC_Programm wickelt die Kommunikation mit dem PC ab (Senden, Empfangen),
> macht eine Auswertung des Empfangenen und setzt es in Portbefehle etc.
> um.
>
> Da Zustandänderungen an Ports und an der seriellen Schnittstelle
> voneinander unabhängig auftreten, empfielt es sich mit Interrupts zu
> arbeiten. Eine Aufgabe in einem Bereich kann durch Zustandänderungen in
> einem anderen Bereich unterbrochen werden.

Mal schauen ob ich dich richtig verstanden habe:
Das Programm muss vollständig auf dem µC geladen sein. Vom PC löse ich 
Interrupts aus auf die der µC mit mit zuvor im Programm festgelegten 
"Interrupt-Service-Routinen" regiert und dann das Programm wieder an der 
Stelle fortsetzt. - Richtig?

Mein konkretes Vorhaben:

Mein Vorhaben besteht unter anderem darin ein Fahrzeug von Tatatur aus 
zu steuern, geregelt wird der µC ausschliesslich über die Sensoren.

Ein Beispiel:
mit den Pfeiltasten gebe ich in den jeweiligen Richtungen "Gas". Sobald 
ich die Taste loslasse, soll das Fahrzeug nur noch "ausrollen" und mit 
dem Betätigen einer anderen Taste soll die Bremse so lange "zupacken", 
wie ich den Finger auf der Taste halte, bis es schließlich zum Stehen 
kommt.
Parallel dazu sollen die Sensoren ständig die Umgebung kontrollieren und 
auf Einflüsse reagieren und die Port-Zustands-Anzeige soll erkennen, 
wenn sich ein Port-Zustand geändert hat.

Dann sehe ich ich einen Nachteil:

Wenn ich das Interrupt-Verfahren richtig verstehe, wird das Programm zu 
der Zeit unterbrochen , zu der ein Interrupt geristriert wird.
Somit wären meine Sensoren zu der Zeit nicht aktiv und die 
Port-Zustands-Anzeige zu der Zeit nicht mehr aktuell, wenn ich durch den 
PC-Interrupt "Gas gebe"?!

Wieso das Ganze?

Ich beschreibe mein Vorhaben/Problem aus dem Grund so genau, da ich wie 
gesagt diese Projekt nächstes Jahr als Studienarbeit abschliessen 
möchte. Darüberhinaus will ich direkt im Anschluss ein Praxissemster auf 
dem Gebiet absolvieren und nach meinem Diplom auf dem Gebiet arbeite. 
Das zu meiner Ebedded-Systems-Robotik-Begeisterung!

Ich bin nur ein Einsteiger auf dem Gebiet, der ein festes Ziel vor Augen 
hat
Ich bin über jede Hilfe/Tipps/Ratschläge sehr dankbar!

von Stefan (Gast)


Lesenswert?

Nee, du hast es immer noch nicht.

Über die serielle Schnittstelle schikct du vom PC zum µC nur Zeichen 
rüber. Was mit den Zeichen gemacht werden soll, entscheidet das von dir 
zu programmierende Programm auf dem µC. Die Übertragung an sich ist von 
der Rechenzeit her Peanuts, wenn es richtig gemacht wird. Dein µC kann 
viiiieeelll Zeit für andere Aufgaben bekommen.

Der µC (bzw. dein Programm, welches auf dem µC läuft) kann die serielle 
Kommunikation auf zwei Arten abwickeln:

1/ Eine Programmroutine fragt regelmäßig, ob Zeichen da sind. Das ist 
ein sog. Polling-Verfahren. Die Nachteile: Du musst programmtechnisch 
dafür sorgen, dass dieses regelmäßige Abfragen auch passiert. Das kann 
bedeuten, dass sonstige Berechnungen so modularisiert werden müssen, 
dass zwischendurch immer wieder mal die Kommunikationsroutine an die 
Reihe kommt... Und die Polling-Routine verbrät
viel viel Zeit, bloss um zu erfahren, dass eben kein Zeichen da ist.

2/ Die serielle Schnittstelle vom µC löst automatisch einen Interrupt 
aus, wenn Zeichen vom PC da sind und unterbricht die aktuell laufende 
Programmroutine auf dem µC. Deine programmierte Interruptroutine 
schnappt sich das Zeichen und beendet den Interrupt. Das ist eine feine 
Sache, weil es nach der Unterbrechung normal an in der zuvor 
unterbrochenen Routine weitergeht. Und Rechenzeit für die Übertragung 
wird nur verbraten, wenn tatsächlich was zu tun ist.

Auch kannst du vorgeben, ob deine Sensoren aktuelle Werte zeigen. Du 
kannst nämlich die Sensoren ebenfalls im Interrupt-Verfahren an dein 
Programm anklinken. Wenn sich z.B. der Zustand an einem Portpin ändert, 
kann das einen (andere) Interrupt auslösen...

Dein Vorhaben ist ohne Interrupts IMHO nicht machbar. Je mehr Aufgaben 
(Sensoren, Aktoren, Kommunikation) dein µC hat, desto weniger Zeit das 
Steuerprogramm unnütz mit Abfragen wo gerade was passiert verbraten. Das 
kann sich ein mieses Programm auf dem PC leisten, weil ein fetter 
Multihyperdupereprozessor drinsteckt...

Auf dem schwächeren µC hingegen müssen möglichst viele 
Controller-Eigenschaften ausgenützt werden, d.h. die Hardware kümmert 
sich um vieles und meldet sich beim Programm, wenn was "wichtiges" 
anliegt. Was wichtig ist, bestimmst du.

Natürlich tritt bei beiden Verfahren (Polling und Interrupt) eine 
Konkurrenzsituation auf. Du hast ja keinen Parallelrechner. Aber auch 
hier gibt es programmtechnische Lösungen.

Auf manchen µC kann man die Interrupts priorisieren, also einer 
Zustandsänderung eines Sensors z.B. mehr Gewicht geben als dem Senden 
von Textmeldungen. Oder in kritsichen Routinen sperrt man die Interrupts 
und hat einen ununterbrechbare Programmabschnitt...

Und es ist auch eine Sache wie du dein Programm schreibst. Modularisiere 
die Aufgaben und schaffe Tasks. Dann kannst du mit einem 
Multitasking-Verfahren (selbstgeschrieben oder fertige Lösung) und mit 
einem Timer-Interrupt einzelne Tasks bedienen.

von x . (cyberhazard)


Lesenswert?

danke für die Infos.

ich habe mir speziel zur Steuerung des Fahrzeugs mit den Pfeiltasten 
folgendes überlegt:
Sobald ich die "Vorwärts-Taste" gedrückt habe wird ein Interrupt an den 
µC gesendet, der den Port des Antriebs "setzt", das Programm läuft 
danach ganz normal weiter und das Fahrzeug fährt. Sobald ich die Taste 
loslasse wird wiederum ein Interrupt gesendet, der den Port des Antriebs 
"rücksetzt"; das Fahrzeug rollt aus.
Das selbe Spiel mit der Bremse.
Somit könnte ich das Fahrzeug von der Tastatur nur duch kurze 
Interrupt-Unterbrechungen steuern und die Sensoren-Regelung wird dadurch 
bis auf die Interrupts nicht beeinträchtigt.

Somit hätte ich die Steurung über die Sensoren als auch über die 
Tastatur ermöglicht!


> 2/ Die serielle Schnittstelle vom µC löst automatisch einen Interrupt
> aus, wenn Zeichen vom PC da sind und unterbricht die aktuell laufende
> Programmroutine auf dem µC. Deine programmierte Interruptroutine
> schnappt sich das Zeichen und beendet den Interrupt.

> Auch kannst du vorgeben, ob deine Sensoren aktuelle Werte zeigen. Du
> kannst nämlich die Sensoren ebenfalls im Interrupt-Verfahren an dein
> Programm anklinken. Wenn sich z.B. der Zustand an einem Portpin ändert,
> kann das einen (andere) Interrupt auslösen...


Wie erzeuge ich einen "bestimmten" Tasten-Interrupt am PC aus, sodass 
das µC-Programm ihn erhält und die zur jeweiligen Taste gehörende 
Interrupt-Service-Routine starten kann?

Erhalten RxD (P3.0)
Senden   TxD (P3.1)

Muss ich nicht zusätzlich in meinem µC-Programm die RS232-Schnittstelle 
im SCON-Register initialisieren (Baudrate, Bitzahl, Handshake), damit 
die µC-Seite die gleichen Einstellungen hat wie die PC-Seite (Terminal)?
z.B: MOV SCON, #52h


Danke im Vorraus!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Wie erzeuge ich einen "bestimmten" Tasten-Interrupt am PC aus, sodass
> das µC-Programm ihn erhält und die zur jeweiligen Taste gehörende
> Interrupt-Service-Routine starten kann?

Es gibt keinen "bestimmten Tasten-Interrupt" auf Deinem µC. Sondern nur 
den, der ausgelöst wird, wenn auf der seriellen Schnittstelle ein 
Zeichen empfangen wird.

Die Auswertung dieses Zeichens und die Entscheidung, welche Routine dann 
aufzurufen ist, musst Du schon selber in Deinem Programm im µC 
vornehmen.

Wenn sichergestellt ist, daß diese aufzurufenden Routinen schneller 
abgearbeitet werden, als auf der seriellen Schnittstelle Zeichen 
ankommen können, dann kannst Du diese Routinen auch in der ISR aufrufen, 
auch wenn das wenig elegant ist.
Bei 9600 Baud hast Du 1 msec Zeit für diese Routinen.

Besser ist ein Zwischenspeichern der empfangenen Zeichen und ein 
Auswerten der empfangenen Zeichen außerhalb der ISR, also in der 
"Hauptschleife" Deines µC-Programmes.

Natürlich musst Du auf Deinem µC die serielle Schnittstelle 
initialisieren, natürlich auch mit den gewünschten Einstellungen wie auf 
dem PC verwendet ...

von Stefan (Gast)


Lesenswert?

Einfache Lösung mit Terminalprogramm und einem Tastendruck am PC pro 
Steuerkommando und unter allen Betriebssystemen:

REPEAT
READ Beitrag "Re: µC von PC steuern"
UNTIL verstanden;

Schwierigere Lösung mit Tastedrücken/-loslassen Steuerung am PC:

Unter Windows kannst du in einem eigenen Programm solche Events wie 
Taste wurde gedrückt oder Taste wurde losgelassen bekommen.

Und du müsstest dann eine entsprechene Kommandosequenz (Zeichen für 
Taste X ist gedrückt oder Taste X ist nicht gedrückt) über die serielle 
Schnittstelle an den µC senden.

In eine Interruptprogrammierung am PC müsstest du nur einsteigen, wenn 
du kein entsprechendes eventbasiertes OS hast, also z.B. wenn du den PC 
unter DOS fahren willst.

Die Behandlung der Kommandos auf dem µC ist dann wieder identisch zur 
ersten Lösung.

von x . (cyberhazard)


Lesenswert?

Rufus T. Firefly wrote:

> Es gibt keinen "bestimmten Tasten-Interrupt" auf Deinem µC. Sondern nur
> den, der ausgelöst wird, wenn auf der seriellen Schnittstelle ein
> Zeichen empfangen wird.

Das habe ich jetzt verstanden. Leuchtet ein!

> Die Auswertung dieses Zeichens und die Entscheidung, welche Routine dann
> aufzurufen ist, musst Du schon selber in Deinem Programm im µC
> vornehmen.

Wie würde so etwas aussehen?

> Besser ist ein Zwischenspeichern der empfangenen Zeichen und ein
> Auswerten der empfangenen Zeichen außerhalb der ISR, also in der
> "Hauptschleife" Deines µC-Programmes.

So in etwa habe ich es mir auch schon vorgestellt.

> Natürlich musst Du auf Deinem µC die serielle Schnittstelle
> initialisieren, natürlich auch mit den gewünschten Einstellungen wie auf
> dem PC verwendet ...

Kannst du mir für den Einstieg anhand eines kleinen funktionierenden 
Beispielprogramms in gcc zeigen, wo folgendes abgehaldelt wird :

- Initialisierung der seriellen Schnittstelle mit 8N1 9660
- Interrupt-Demonstration durch eintreffendes Zeichen an RS232 und 
Zwischenspeichern des empfangenen Zeichens innerhalb der ISR

Die Beispiele im AVR-GCC-Tutorial enthalten nur Codesegmente und keine 
komplette, lauffähige Demontrations-Programme.

Danke für deine Tipps! Sie haben den Kern meines Problems getroffen!

von Stefan (Gast)


Lesenswert?

Alternativer Vorschlag während du auf Lösungen wartest:

Bau die Codesegmente zusammen soweit du kommst. Daran sehen andere, was 
du bereits beherrschst und was noch fehlt. Ergänzungen sind dann rasch 
gemacht.

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.