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!
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.
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!
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.
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!
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.
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!
> 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 ...
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.
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!
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.