Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- org 100h
- cpu 8086
- jmp start
- ;--------------------------------
- ; Variablen
- status db 00000000b ; Statusbyte
- ; xxxx x
- ; |||| |
- ; |||| +--------> Vereinzeler (1, auf) / (0, zu) bzw.
- ; |||| Verzoegerung aktiv
- ; ++++------------> Anzahl Teile binaer (8-0)
- tcounts db 0 ;Impulszaehler fuer Servo, Vorwaertszaehler
- tcountv dw 100 * twait ; Impulszaehler fuer Verzoegerung * 10ms
- ; Rueckwaertszaehler
- frei db 'frei ', 0 ; Texte
- belegt db 'belegt ', 0
- clrscrn db ' ', 0
- ;--------------------------------
- ; Konstanten
- servo_timer equ 0 ; Zeitkonstante für Servo
- vereinzeler_timer equ 0 ; Zeitkonstante für Vereinzeler
- VE_aktiv equ 1 << 0 ; Vereinzeler bzw. Verzoegerung aktiv
- intab0 equ 20h ; Adresse Interrupttabelle PIT, Kanal 1
- intab1 equ intab0 + 1 * 4 ; Adresse Interrupttabelle PIT, Kanal 2
- intab7 equ intab0 + 7 * 4 ; Adresse Interrupttabelle Lichttaster
- eoi equ 20h ; End Of Interrupt (EOI)
- clrscr equ 0 ; Clear Screen
- getkey equ 1 ; Funktion auf Tastatureingabe warten
- ascii equ 2 ; Funktion ASCII-Zeichenausgabe
- hexbyte equ 4 ; HEX-Byte Ausgabe
- conin equ 5 ; Console IN
- conout equ 6 ; Console OUT
- pitc equ 0a6h ; Steuerkanal PIT
- pit1 equ 0a2h ; Counter 1 PIT
- pit2 equ 0a4h ; Counter 2 PIT
- ppi_ctl equ 0b6h ; Steuerkanal PPI (Parallelinterface)
- ppi_a equ 0b0h ; Kanal A PPI
- ppi_pa0 equ 1 ; LED 0
- ppi_pa1 equ 2 ; LED 1
- ppi_pa2 equ 4 ; LED 2
- ppi_pa3 equ 8 ; Lautsprecher
- ppi_pa6 equ 1 << 6 ; Servomotor
- ppi_b equ 0b2h ; Kanal B PPI
- ppi_c equ 0b4h ; Kanal C PPI
- ocw_2_3 equ 0c0h ; PIC (Interruptcontroller), OCW2,3
- ocw_1 equ 0c2h ; PIC (Interruptcontroller), OCW1
- icw_1 equ 0c0h ; PIC (Interruptcontroller), ICW1
- icw_2_4 equ 0c2h ; PIC (Interruptcontroller), ICW2,4
- leds equ 0 ; LED Port
- schalter equ 0 ; Schalterport
- keybd equ 80h ; SBC-86 Tastatur
- gokey equ 11h ; Taste "GO"
- outkey equ 15h ; Taste "OUT"
- sseg7 equ 9eh ; Segmentanzeige 7
- tcpwm equ 184 ; 1843200 Hz / 184 = ca. 10000 Hz = 0.1 ms
- ;--------------------------------
- ; Taktzyklus
- ; Zeitkonstante fuer PWM-Interrupt
- tpwm equ 200 ; Periodendauer des PWM-Signals * 0.1 ms
- tlinks equ 10 ; Impulsdauer fuer "ZU" * 0.1 ms
- trechts equ 20 ; Impulsdauer fuer "AUF" * 0.1 ms
- tcwait equ 18432 ; 1843200 Hz / 18432 = 100 Hz => 10 ms
- ; Zeitkonstante fuer Wartezeitinterrupt
- twait equ 1 ; Wartezeit fuer offenen Vereinzeler (s)
- shcnt equ 4 ; Shiftcount Anzahl Teile
- pieces equ 8 ; Anzahl Teile initial
- ;-------------------------------------------------------------------------------
- ;-------------------------------------------------------------- Initialisierung
- start:
- call init ; Controller und Interruptsystem scharfmachen
- mov ah, clrscr ; Anzeige aus
- int conout ; Ausschaltung der 7-Segmentanzeige
- mov byte [status], pieces << shcnt ; Init. Statusbyte und alle LEDs
- mov al, 0
- out ppi_a, al ; Ausgabe von 0 auf 7-Segmentanzeige
- mov al, 10000000b ; Setzung des letzten Bits für die 8...
- out leds, al ; Ausgabe von 0 auf den LEDs
- ;-------------------------------------------------------------!!! Hauptprogramm
- ; Ausgaben auf das Display und Zaehlung der Teile
- again:
- mov ah, 2 ; Ausgabe eines Ascii-String (nullterminiert)
- mov bx, clrscrn ; Leeren String in bx kopieren
- mov dl, 7 ; Displaystelle dl: Anzeige ab 7. Stelle
- int 6 ; Ausführung von clear_screen
- mov al, [status] ; Kopieren des Inhalts von Status nach al
- test al, 11110000b ; Vergleich des Inhalts von al mit 0
- jz voll ; Sprung zu Funktion "voll"
- ;-------------------------
- ; Funktionsprung, wenn Statusbyte != 0
- halbvoll:
- mov ah, 4h ; Ausgabe eines Hexbytes
- mov bx, [status] ; Statusbyte Inhalt in bx Register kopieren
- mov dl, 1h ; Ausgabe des Hex-Bytes auf 7-Segmentdisplay 1
- int 6
- mov ah, 2 ; Ausgabe eines Ascii Strings
- mov bx, frei ; Kopieren von frei-Variable in bx
- mov dl, 7 ; Ausgabe von frei auf 7. Segment der Anzeige
- int 6 ; Aufruf von Display-Interrupt
- mov al, [status] ; Kopierung des Inhalts von Status in al
- test al, 11110000b ; Vergleich, ob Statusbyte = 0
- jz voll
- jmp halbvoll
- ;-------------------------
- ; Funktionsprung, wenn Statusbyte = 0
- voll:
- mov ah, 4h ; Ausgabe eines Hexbytes
- mov bx, [status] ; Statusbyte Inhalt in bx Register kopieren
- mov dl, 1h ; Ausgabe des Hex-Bytes auf 7-Segmentdisplay 1
- int 6
- mov ah, 2
- mov bx, clrscrn
- mov dl, 7 ; Stelle, ab wann belegt ausgegeben wird
- int 6
- mov ah, 2
- mov bx, belegt
- mov dl, 7
- int 6
- jmp again
- ;------------------------------------------------------------------- Interrupts
- ; Initialisierung Controller und Interruptsystem
- init:
- cli ; Interrupts aus
- ;-------------------------------------------------------------------------- PIT
- ; PIT-Init. (Zeitgeber-Baustein)
- mov al, 01110110b ; Kanal 1, Mode 3, 16-Bit ZK
- out pitc, al ; Steuerkanal
- mov al, tcpwm & 0ffh ; Low-Teil Zeitkonstante
- out pit1, al
- mov al, tcpwm >> 8 ; High-Teil Zeitkonstante
- out pit1, al
- mov al, 10110110b ; Kanal 2, Mode 3, 16-Bit ZK
- out pitc, al ; Steuerkanal
- mov al, tcwait & 0ffh ; Low-Teil Zeitkonstante
- out pit2, al
- mov al, tcwait >> 8 ; High-Teil Zeitkonstante
- out pit2, al
- ;-------------------------------------------------------------------------- PPI
- ; PPI-Init. (paralleler Interface-Baustein)
- mov al, 10001011b ; PPI A/B/C Mode 0, A Output, sonst Input
- out ppi_ctl, al
- jmp short $+2 ; I/O-Delay
- mov al, 0 ; LED's aus (high aktiv)
- out ppi_a, al
- ;-------------------------------------------------------------------------- PIC
- ; PIC-Init. (Interruptcontroller -> Zuordnung von 8 Interrupts an CPU)
- mov al, 00010011b ; ICW1, ICW4 benoetigt, Bit 2 egal,
- ; Flankentriggerung
- out icw_1, al ; Freischaltung der Eingänge für Interrupts
- jmp short $+2 ; I/O-Delay (Pause)
- mov al, 00001000b ; ICW2, auf INT 8 gemapped
- out icw_2_4, al
- jmp short $+2 ; I/O-Delay
- mov al, 00010001b ; ICW4, MCS-86, EOI, non-buffered,
- ; fully nested
- out icw_2_4, al
- jmp short $+2 ; I/O-Delay
- mov al, 01111100b ; Kanal 0, 1 + 7 am PIC demaskieren (Sofortausführung)
- ; PIT K1, K2 und Lichttaster
- out ocw_1, al
- ;------------------------------------------------------------------------- INIT
- ; Interrupttabelle init.
- mov word [intab7], isr_lt ; Interrupttabelle (Lichttaster)
- ; initialisieren (Offset)
- mov [intab7 + 2], cs ; (Segmentadresse)
- mov word [intab0], isr_servotimer ; Interrupttabelle (Timer K1)
- ; initialisieren (Offset)
- mov [intab0 + 2], cs ; (Segmentadresse)
- mov word [intab1], isr_opentimer ; Interrupttabelle (Timer K2)
- ; initialisieren (Offset)
- mov [intab1 + 2], cs ; (Segmentadresse)
- sti ; ab jetzt Interrupts
- ret
- ;-----------------------------------------------------------!!! Serviceroutinen
- isr_opentimer: ; Timer fuer Vereinzeler (Zeit fuer Oeffnung)
- push ax ; Speicherung von ax auf dem Stack
- mov al, [status]
- test al, 1 ; Vereinzeler-Bit gesetzt?
- jz isr_opentimer_out
- mov al, [tcounts] ; oder tcountv??
- dec al
- mov [tcountv], al
- cmp al, 0 ; Ist Verzögerung = 0? Ja, -> out
- jne isr_opentimer_out
- mov al, [status]
- and al, 11110000b ; Vereinzeler-Bit reset
- mov byte [status], al
- mov al, twait * 100 ;
- mov [tcountv], al
- ;--------------------------------------------------------------- ISR Open Timer
- isr_opentimer_out: ; Ausgang aus dem Service
- mov al, eoi ; EOI an PIC
- out ocw_2_3, al
- pop ax
- iret
- ;---------------------------------------------------------------!!! Lichttaster
- isr_lt: ; Lichttaster
- push ax
- mov al, byte [status] ; Einlesung Statusbyte
- times 4 shr al, 1 ;2^7 bis 2^4 nibble nach rechts schieben zu 2^3 bis 2^0
- dec al
- test al, 11110000b
- jz noch_nicht_null
- ; wenn Statusbyte = 0
- mov al, 00001000b
- times 4 shl al, 1 ;2^3 bis 2^0 nibble nach links schieben zu 2^7 bis 2^4
- out leds, al
- jmp isr_lt_out
- ;---------------------
- noch_nicht_null: ; Merker ist nicht gesetzt
- times 4 shl al, 1 ;2^3 bis 2^0 nibble nach links schieben zu 2^7 bis 2^4
- or al, 1 ; Vereinzeler-Bit setzen
- out leds, al ; Ausgabe des Merkers
- ;-------------------------------------------------------------- ISR Lichttaster
- isr_lt_out: ; Ausgang aus dem Service / Verarbeitung der Request
- mov [status], al
- mov al, eoi ; EOI an PIC
- out ocw_2_3, al
- pop ax
- iret
- ;------------------------------------------------------------!!! ISR Servotimer
- isr_servotimer: ; Timer fuer Servo (Vereinzeler)
- push ax
- mov al, [status], ; Vereinzeler-Bit gesetzt?
- test al, 1
- jz active2 ; 1. Bit nicht gesetzt? Bei nein jump zu active2
- mov ah, [tcounts]
- inc ah
- cmp ah, trechts ; 2ms
- jnz active
- mov al, 0 ; Servo aus
- out ppi_a, al
- ;--------------------
- active:
- cmp ah, [tpwm] ; tcount = 200?
- jnz isr_servotimer_out ; wenn nein, dann jump
- mov al, ppi_pa6 ; Kopierung Servo-Port ins ah-Register
- out ppi_a, al ; Ausgabe von Kanal A
- mov ah, 0 ; Zaehler auf 0 setzen
- jmp isr_servotimer_out
- ;--------------------
- active2:
- mov ah, [tcounts]
- inc ah
- cmp ah, tlinks ; 1ms
- jnz active
- mov al, 0
- out ppi_a, al
- jmp active
- ;------------------------------------------------------------------------------
- isr_servotimer_out: ; Ausgang aus dem Service
- mov byte [tcounts], bl ; hinzugefügt
- mov al, eoi ; EOI an PIC
- out ocw_2_3, al
- pop ax
- iret
- ; Problem: 7-segment ist schneller als servo -> überprüfung im opentimer
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement