Projektarbeit: Alarmanlage
-
Ahoi ...
über die Semesterferien muss ich für die Vorlesung Mikroprozessortechnik eine kleines Programm, eine Alarmanlage, entwickeln. Ich weiß, Projektarbeiten / Hausaufgaben sind immer ein heikles Thema. Ich will nicht, dass mir irgendwer die Aufgabe löst, sondern ich habe einfach einige Fragen und Verständnisprobleme und es wär klasse, wenn ihr mir da ein bischen weiterhelfen könntet. Da bis zur Fertigstellung sicher noch ein paar Fragen auftreten, am besten alle Daten:
Hardware:
- Dallas 8051 CPU
8051 based High-Speed Micro with 2 DPTRs, WDT, two Serial Ports
32 I/O lines, 3 Timers/Counters, 15 Interrupts/3 priority levels
5 K ROM, 256 Bytes On-chip RAM + 1024 Bytes addition XRAM
- Touchpanel EAKIT160-6LEDTP (wie ich gehört habe, recht häufig genutzt)
- angeschlossener NumBlock, zusätzlich mit den Tasten [*], [0], [#]Software:
uVision2 - http://www.keil.com/uvision/
EPR_SIM - ELV GmbHLinks:
Beispielcode aus den Übungen - http://files.syn-com.de/bsp.zip
Dokumentation zur Hardware - http://files.syn-com.de/doku01.zip
Ein paar Grundlagen - http://files.syn-com.de/doku02.zip
IDE + EPR Simulator - http://files.syn-com.de/software.zipAufgabe
- Scharfschalten der Alamrmanlage bzw. Abschalten eines ausgelösten Alarms über [*] (beim Abschalten muss danach noch eine 4-stellige PIN eingegeben werden)
- Auslösen des Alarms über den Touchpanel
- Alarmbereich soll farbig auf dem Panel dargestellt werdenZur Zeit bin ich zumindest schonmal soweit, dass ich ein Haus auf dem Panel ausgebe, welches in 4 Bereiche unterteilt ist (durch Definition von 4 Touchtasten). Jetzt brauche ich die Behandlung des Tastendrucks auf dem Numblock, aber hier komme ich einfach nicht weiter. Größtenteils habe ich mit den Codebeispielen gearbeitet, wo es auch eine Datei http://files.syn-com.de/tastaturinterrupt.asm gibt. Ich kann hier allerdings den Code, speziell was den Interrupt angeht, nicht so richtig nachvollziehen. Natürlich funktioniert daher mein aktueller Code http://files.syn-com.de/display.asm auch nicht, den ich mithilfe des Codebeispiels geschrieben habe. Kompiliere ich das z.Z. auskommentierte mit, wir beim Start der Hardware das Haus nicht mehr ausgegeben.
Könnte mir bitte zuerst nochmal kurz jemand den ORG Befehl und das Thema Interrupts erklären, damit ich das Problem im Code nachvollziehen kann. Vieleicht sieht ja auch schon jemand, was ich falsch gemacht haben könnte.
-
Das ist ja mal loeblich.
Zu org: IdR., also wahrscheinlich auch bei deinem Assembler, legt dieser Assembler-Befehl das aktuelle Offset in der binaeren Ausgabedatei fest, die der Assembler erzeugt. (Es handelt sich bei org also nicht um einen OpCode, dh. er bewirkt keine direkte biniaere Ausgabe beim Assemblieren.)
Du hast im Rahmen der Uebung sicher mitbekommen, dass Speicheradressen, bzw. Offsets vor allem beim Programmieren in Assembler sehr wichtig sind. Alle Daten, die in an die CPU angeschlossenem Speicher liegen, haben eine Adresse. Also sowohl herkoemmliche Daten also auch der Code.
Ein Assembler geht beim Assemblieren nun ziemlich geradlinig vor: Der erste OpCode, bzw. Datum, das verarbeitet wird, bekommt intern vom Assembler die Startadresse (oft z.B. 0) zugewiesen, dann wird intern die aktuelle Adresse um die binaere Groesse des verarbeiteten Befehls erhoeht und der naechtse Befehl genau so verarbeitet.
Mit org kann man also auch die Startadresse des binaeren Outputs (was der Assembler in einer Datei ausgibt) festlegen, wenn der Befehl vor allen OpCodes oder Daten steht.
Dieses erwaehnte Offset, das der Assembler fuer sich jedem Datum zuweist, beeinflusst meist uebrigens nur die Adressbildung von Befehlen, wie zB. indirkte Spruenge oder Zugriffe auf den Speicher. Es kann allerdings auch sein, dass dadurch direkt das Offset in der binaeren Ausgabedatei beeinflusst wird, an dem verarbeitete OpCodes oder Daten landen. Sieht mir bei eurem Assembler so aus, als waere letzteres der Fall.So weit verstanden? Dann mal konkret zu deinen Codes:
Bei tastaturinterrupt.asm kannst du schoen sehen, dass die verwendete CPU offenbar nach einem Reset immer bei Offset 0 startet.
Folglich muss das erste, was in deinem Quellcode steht, ein org 0000h sein.
Falls du Interrupts verwenden willst, muss als naechstes direkt nur ein Befehl folgen, der zum eigentlichen Programm springt. Bei euch oft ein "jmp start".
Fuer mehr ist dort erstmal kein Platz, denn die ISR fuer Interrupt 0 wird offenbar bei Offset 0003h erwartet. D.h. nach dem Sprung zum Hauptprogramm muss direkt ein org 0003h und das Unterprogramm der ISR fuer Interrupt 0 folgen.
Nach dem Rueckspung aus der ISR kannst du dann direkt das eigentliche Hauptprogramm hinter dem Label "start:" (z.B.) anhaengen.Wenn du das jetzt auch nur grob verstanden hast, sollte dir in etwa klar sein, dass bei deinem Programm in display.asm so nur grosses Durcheinander rauskommen kann.
Zu Interrupts:
Ist ein weites Feld... Was willst du wissen?
Allgemein sind Interrupts genau was der Name sagt: Unterbrechungen des aktuell laufenden Programms, um kurzfristig andere Programme auszufuehren.
Dabei speichert die CPU die Ruecksprungadresse und meist auch noch ihren aktuellen Zustand (flags) und springt dann an eine fest vorgegebene Adresse.
Siehe auch http://de.wikipedia.org/wiki/InterruptIn deinem Fall geht es um Hardware Interrupts und der Code der ISR fuer Interrupt 0 muss dabei offenbar bei Offset 3 liegen (es wird bei Interrupt 0 immer direkt nach Offset 3 gesprungen, dh. der Interruptvektor ist fix).
Da die Maschine noch mehrere andere Interrupts hat, waere anzunehmen, dass weitere ISRs bei Offset 6, 9, usw. erwartet werden, allerdings werden diese wohl nicht benutzt.
-
Danke für die Hilfe. Das hat mich schonmal ein ganzes Stück weiter gebracht.
Falls wen der aktuelle Code interessiert: http://files.syn-com.de/alarm.asmBesonders die Erklärung zu ORG, dass es sich hierbei nicht um einen OpCode sondern ehr um eine Art Compileranweisung handelt, hat die ganze Sache viel klarer gemacht. Zur Zeit habe ich zumindest schonmal die Scharfschaltung durch die Tastatur und das Auslösen eines Alarms mit Hilfe des Touchpanels hinbekommen
Nun kämpfe ich mit der Soundausgabe, aber ich denke da kann mir nur jemand helfen, der die Hardware kennt. Aber wenn es dann um das Abschalten des Alarms durch eine Pin geht, werd ich mich sicher nochmal zurück melden (müssen)
-
Welche Hardware nutzt ihr für den Sound und wie ist sie angeschlossen? Piezo-Summer am I/O-Pin?
Dann bräuchtest du nur den entsprechenden Ausgangspin alle (Maschinenzyklus / gewünschte Tonfrequenz) invertieren (cpl). Am Besten natürlich über einen Timer.
Da solltest du aber aufpassen, da der Interrupt-Vektor für den Timerinterrupt eventuell bereits durch deine erste Interruptverarbeitung überschrieben ist.
Dazu vielleicht nochmal etwas zu ORG und Interrupts:
Mit ORG weist du den Assembler an, die folgenden Befehle an eine bestimmte Speicheradresse zu schreiben. Wobei natürlich nur der erste Befehl an dieser Stelle liegt, die weiteren Befehle liegen dahinter.Interrupts werden bei bestimmten Bedingungen ausgelöst (z.B. Überlauf eines Timers, Flanke am Eingang etc.). Beim 8051 hat jede Interruptquelle einen Interruptvektor, also eine Adresse, an die beim Auftreten des Interrupts gesprungen wird. Der Platz hinter diesen Adressen langt gerade mal dafür aus, ein Unterprogramm aufzurufen und ein RETI (RETurn from Interrupt) auszuführen. Schreibst du deine ISR also direkt an die Interruptadresse, dann schreibst du weitere Befehle an Stellen, die Als Interruptvektor für andere Quellen gelten.
Bei
org 0003h ; ISR - Adresse push acc ; Akku sichern mov dptr, #0fd00h ; dptr auf Tastaturadresse 0fd00h setzen movx a, @dptr ; Inhalt von Adresse 0fd00h lesen ( Tastencode ) mov r2, a ; Tastencode nach r2 sichern pop acc ; Akku zur�cksetzen reti ; R�ckkehr
können also zusätzliche Interrupts ein unerwünschtes Verhalten an den Tag legen, da sie auf Code deiner ISR springen.
org 0003h call ei0_isr ; ISR für External Interrupt 0 reti ... (Rest deines Programms) ei0_isr: push acc ; Akku sichern mov dptr, #0fd00h ; dptr auf Tastaturadresse 0fd00h setzen movx a, @dptr ; Inhalt von Adresse 0fd00h lesen ( Tastencode ) mov r2, a ; Tastencode nach r2 sichern pop acc ; Akku zur�cksetzen ret