********************************************************************* * * * Programm fader.asc * * * * Datum: 26.Mai 1991 * * * * Fuer den Betrieb des Faderpanels (2.0) ueber die synchrone * * Schnittstelle, in Verbindung mit einem 68HC11-Mainprocessor. * * * ********************************************************************* * * * Beschreibung: * * * * Das Programm wird aufgeteilt in 4 Teile: * * * * * * 1. Kommunikationsmodul (Interrupt) * * * * Treiber fuer die Ein-/Ausgabe ueber die serielle Schnittstelle. * * Empfaengt LED-Daten und Fade-Zeit-Daten, * * Sendet Taster- und Potidaten. * * * * * * 2.Ein-Ausgabemodul (Interrupt) * * * * Gibt Ledwerte pulsbreitenmoduliert und gemultiplext an die * * Leds aus. * * * * * * 3.Synchronisationsmodul (Hauptprogramm) * * * * Hauptprogramm-Endlosschleife: * * Liest Taster und Potiwerte ein und stellt sie dem * * Kommunikationsmodul zur Verfuegung. * * Bearbeitet die Zeitumschalter. * * Berechnet mithilfe der Fadezeit und der Zeitschalter die * * Position der Autofade-Szenen (Zeitsynchronisation ueber * * Wait-Flag mit Ein-/Ausgabemdul) * * Berechnet aus den Ledwerten des Komm.-moduls die Werte fuer das * * I/O-Modul. * * Erledigt die Tabellenzuordnung der ein-/auszugebenden Werte * * (bedingt durch Unterschiede Tabellenordnung <--> Layoutordnung) * * * * * * 4.Initialisierungsmodul * * * * Wird nur nach Reset einmal durchlaufen, * * Initialisiert die Interrupts, die Processorkommunikation und * * Variablen. * * * ********************************************************************* incl c:\hc11\register.asc abstand equ 240 120us Pause zwischen PWM-Umschaltung period equ %0000011111110000 2048 * 0.5us = 1ms gesperiod equ abstand+period anzahl equ 40 *------ Interne Variablen: ----------* zaehler rmb 2 ledpwm rmb 2*40 tread rmb 10 lastt rmb 2 impuls rmb 1 schalter rmb 2 puffer rmb 1 spuffer rmb 2 zeit rmb 2 szpoti rmb 8 8 Byte Szenenpotis (intern) ! szlow rmb 8 Lowbyte Szenen ccount rmb 2 Zaehler SPI-Interrupt cflag rmb 1 Flag SPI-Interrupt taster rmb 5 Szenenflash, Kanalflash (Mitte), * Kanalflash (oben), * Zeit 1 (unten), Zeit 2 (oben) *------ Kommunikations-Variablen: ---* sendtab rmb 0 * dummy2 rmb 0 Platzfueller, damit Empf.- und Rectab. gleich outtast rmb 3 Flashtaster Szenen, Kanal unten, Kanal oben szhigh rmb 8 8 Byte Szenen (High) klpoti rmb 8 16 Byte Kanaele khpoti rmb 8 dummy1 rmb 0 dieses Byte wird als erstes gelesen, weil * bei der ersten Uebertragung im Datenregister * SPDR noch alter Wert steht !!! * empftab rmb 0 * blink rmb 1 Future Use zeit1 rmb 2 Zeitwert 1 (unten) zeit2 rmb 2 Zeitwert 2 (oben) led rmb 40 Szenen, * Kanaele (unten), Kanaele (oben), * Zeit 1 (unten), Zeit 2 (oben) -> intern ********************************************************************* initall ORG $B600 lds #$FF Stackpointer laden ldaa #$0ff staa DDRC ldaa #%00000000 Port C auf Open-Kollektor initialisieren staa PIOC ldaa #%10000000 Port A Pin 7 auf Ausgang staa PACTL ldaa #%10000011 Ladungspumpe einschalten staa OPTION ldaa #%00110000 AD-Wandler initialisieren staa ADCTL ldaa #$7E Output-Compare-Interrupt einrichten staa OC1RAM staa SPIRAM ldd #OC1IRQ std OC1RAM+1 ldd #SPIIRQ SPI-Interrupt einrichten std SPIRAM+1 ldaa #%00011100 SPI-System initialisieren: staa DDRD Datenrichtung einstellen ldaa #%11000100 staa SPCR ldaa #%10000000 staa TMSK1 Freigabe von Timer1 staa TFLG1 ldaa #%10101010 staa TCTL1 ldaa #%01111000 4 pulsmodulierte Ausg„nge staa OC1M staa OC1D ldx #$ffff stx zaehler inx stx ccount ;SPI-Counter nullsetzen ldaa #%11000011 * ldaa HPRIO * oraa #3 ;SPI-System hoechste Prioritaet! staa HPRIO cli Interrupts freigeben ********************************************************************* main ******* Tastertabelle umsetzen von 2*4 Bit in 1*8 Bit: ldx #10 ldy #5 nextt ldab tread-1,x rechte Taster dex ldaa tread-1,x linke Taster lsrd lsrd lsrd lsrd rora innerster Taster links ins Carry rolb rora rolb rora rolb rora rolb stab taster-1,y dey dex bne nextt ldd taster Flashtasten umkopieren ins Ausgabe-Array coma Negieren : comb Taster gedrueckt: -> 1 (aktiv high) std outtast ldaa taster+2 coma staa outtast+2 ******* Schalterberechnung: ldaa lastt Schalterberechnung anda taster+3 eora lastt staa impuls eora schalter staa schalter ldaa taster+3 staa lastt ldaa schalter coma anda impuls oraa schalter+1 staa schalter+1 ldaa lastt+1 anda taster+4 eora lastt+1 staa impuls eora schalter+1 staa schalter+1 LDAA taster+4 staa lastt+1 ldaa schalter+1 coma oraa schalter staa schalter Schalterberechnung Ende ******* Szenen berechnen: ldaa #$80 Timeroverflow? (30Hz) bita TFLG2 beq notimerflag Nein, Szenen ueberspringen staa TFLG2 Ja, Timerflag loeschen und Szenen rechnen ldx #8 8 Potis bearbeiten ldd schalter Schalter in Schalterpuffer schreiben std spuffer nxtszene ldd #$ffff passende Zeit laden rol spuffer bcs tn2 ldd zeit2 tn2 rol spuffer+1 bcs tend ldd zeit1 tend std zeit ldaa szpoti-1,x Analogwert holen staa puffer ldaa szhigh-1,x ldab szlow-1,x cmpa puffer beq szende bcs greater lower subd zeit POTI KLEINER ALS ALTER WERT bcs unten cmpa puffer bcc lnogrt unten ldaa puffer lnogrt bra save greater addd zeit Poti gr”áer als alter Wert bcs oben cmpa puffer bcs gnolow oben ldaa puffer gnolow save staa szhigh-1,x neuen Wert abspeichern stab szlow-1,x szende dex bne nxtszene 8-mal Schleifenwiederholung notimerflag ******* Zeitschalter in Ledwerte umsetzen: ldx #16 ldaa schalter+1 ldab schalter nextzs clr led-1+24,x lsld bcs nichtan dec led-1+24,x nichtan dex bne nextzs ******* Ledwerte in PWM-Werte umsetzen: ldx #0 nextl ldab led,x Ledwert holen und PWM-Wert berechnen tba mul lsrd lsrd lsrd lsrd lsrd pshx xgdx bitb #%00000100 beq notinv eorb #%00000011 notinv lsld xgdx std ledpwm,x PWM-Wert an Tabellenadresse speichern pulx inx cpx #40 bne nextl jmp main Hauptprogramm-Endlosschleife ********************************************************************* SPIIRQ ldaa SPSR SPIF-Flag loeschen clr ccount ldx ccount Zaehler nach X holen ldaa SPDR Empfangsregister nach Empfangstabelle ldab sendtab-1,x Senderegister mit Sendetabelle laden * Am Anfang Dummy schicken: sendtab-1 !!! stab SPDR Moeglichst flott naechste Uebertragung staa empftab,x vorbereiten !!! inc ccount+1 Zaehler (Low-Byte) erhoehen clr cflag Monoflop-Flag triggern rti Ende Interrupt (30us) * Laenge gesamt mit Ein- und Aussprung: * 32 us ********************************************************************* * * OC1-Interrupt: * * -liest Potiwerte ein * -liest Taster ein * -gibt Ledwerte gemultiplext und pulsbreitenmoduliert aus. * * * Selektieren der einzelnen Led- und Tastergruppen in dieser Reihenfolge: * * --5-- --6-- [ Kanal-Flashtaster oben] * * --3-- --4-- [ Kanal-Flashtaster unten] * * --9-- -10-- [ Zeit 2 (oben)] * * --7-- --8-- [ Zeit 1 (unten)] * * --1-- --2-- [ Flashtaster Szenen] * * * Dadurch ergibt sich eine einfache Reihenfolge in den einzelnen Arrays. * select fdb %0001000000000001 Szenen 1-4 (links) fdb %1000000000000010 Szenen 5-8 (rechts) fdb %0000000100000011 Kanaele oben 1-4 (links) fdb %0100000000000100 Kanaele oben 5-8 (rechts) fdb %0000001000000101 Kanaele unten 1-4 (links) fdb %0010000000000110 Kanaele unten 5-8 (rechts) fdb %0000100000000111 Zeit 1 (unten) 1-4 (links) fdb %0000000010000000 Zeit 1 (unten) 5-8 (rechts) fdb %0000010000000000 Zeit 2 (oben) 1-4 (links) fdb %0000000001000000 Zeit 2 (oben) 5-8 (rechts) OC1IRQ ldaa #%10000000 Interruptanforderung loeschen staa TFLG1 Unbedingt vor Freigabe anderer IR's! * Sonst kommt sofort neuer Timer-IR ldaa cflag SPI-Timeoutflag erhoehen inca staa cflag Wenn Cflag >= 3, dann Timeout cmpa #3 (letzter SPI-Int. mind. 2ms her) bcs notimeout und ldd #0 SPI-Counter auf Null setzen std ccount notimeout cli Jetzt koennen alle IR's freigegeben * werden. ********************************************************* * * * Bis hier werden alle IR's verzoegert! * * D.h. 21us maximale Verzoegerung !!! * * * ********************************************************* ldx zaehler Zaehler holen, inx incrementieren, stx zaehler abspeichern fuer naechsten IR. cpx #8 Nur X-Werte 0-7 bearbeiten bcc adready (8 Potis) ldaa ADR1 staa klpoti,x ldaa ADR2 staa szpoti,x ldaa ADR3 staa khpoti,x adready xgdx Select-Wort aus Tabelle holen ldx #select lslb abx ldd 0,x stab PORTB und auf Port B/C ausgeben staa PORTC ldx zaehler Tasten einlesen ldaa PORTE staa tread,x xgdx X mal 8 asld asld asld xgdx ldd TCNT 2.5 addd #gesperiod 2 std TOC1 2.5 subd ledpwm,x 3 std TOC2 2.5 ldd TOC1 2.5 subd ledpwm+2,x 3 std TOC3 2.5 ldd TOC1 2.5 subd ledpwm+4,x 3 std TOC4 2.5 ldd TOC1 2.5 subd ledpwm+6,x 3 std TOC5 2.5 gesamt 36.5 us cpx #71 Vergleich, ob schon 10 Durchlaeufe bcs notfull Nein, springe zum Ende ldx #$ffff Ja, lade Zaehler neu (ffff+1 -> 0) stx zaehler notfull rti Ruecksprung zum Hauptprogramm ********************************************************************* end