1 | stack_seg SEGMENT IDATA ;
|
2 | code_seg SEGMENT CODE ;
|
3 | RSEG stack_seg
|
4 | top_stack: DS 10h ; 16 Byte für Stack freihalten (Wertebereich freihalten)
|
5 | CSEG AT 0 ; Start an Adresse 0
|
6 |
|
7 | JMP START ; Sprung zum Start
|
8 | ORG 0Bh ; Interruptvektor Timer0
|
9 | JMP ISR_TIM_0 ; Einsprungstelle Timer0
|
10 | timer_low EQU 0AFh ; 50msec = 15535 = 3CAF hexadezimal (65535 = FFFF mücro sekunden - 50000 mükrosekunden )
|
11 | timer_high EQU 03Ch
|
12 | RSEG code_seg
|
13 |
|
14 | START:
|
15 | MOV SP,#top_stack ; Initialisierung Stack
|
16 |
|
17 | MOV TL0,#timer_low ; Timer0 LowByte
|
18 | MOV TH0,#timer_high ; Timer0 HighByte
|
19 | MOV TMOD,#00000001b ; Timer Modus 1
|
20 | SETB ET0 ; Interruptfreigabe Timer0 |
|
21 | SETB EA ; Globale Interruptfreigabe |
|
22 | MOV P0,#0 ; Port0 zwecks Eingabe
|
23 | MOV P1,#0FBh ; Port1 zwecks Common Cathode | 0FBh 0= Lowbyte FB = Highbyte
|
24 | MOV P3,#0 ; Port3 zwecks Ausgabe
|
25 |
|
26 | LOOP1:
|
27 | MOV A,P0 ; Eingabewert nach A kopieren / sichern
|
28 | ANL A,#0F0h ; Bit 0 bis 3 Null setzen | 0 = Lowbyte F0= Highbyte
|
29 | SWAP A ; Low- und Highbyte tauschen
|
30 | MOV R5,A ; Den bearbeiteten Eingabewert nach R5 kopieren
|
31 | MOV R0,#10 ; R0 auf 10 setzen, Counter (10 bis 0)
|
32 | SETB TR0 ; Timer 0 starten
|
33 |
|
34 | LOOP2:
|
35 | MOV A,R0 ; aktuellen Counterwert nach A kopieren
|
36 | JNZ LOOP2 ; Sprung zum Label LOOP2 wenn Counter != 0
|
37 | CLR TR0 ; Timer 0 stoppen
|
38 | MOV R1,#00000001b ; R1 auf 1 setzen, Verwendung als Maske
|
39 | MOV R0,#4 ; R0 auf 4 setzen, Counter (4 bis 0) / 4 * 50 msec = 200msec
|
40 | MOV R2,#5 ; R2 auf 4 setzen, Counter (4 bis 0)
|
41 | SETB TR0 ; Timer 0 starten
|
42 |
|
43 | LOOP3:
|
44 | MOV A,R5 ;Den bearbeiteten Eingabewert nach A kopieren
|
45 | ANL A,R1 ; A mit R1 (Maske) UND-verknüpfen
|
46 | MOV P3,A ; Ausgabe von A an Port3
|
47 |
|
48 | MOV A,R1 ;----------------------------------------;
|
49 | RL A ; R1 (Maske) ein mal nach links rotieren / verschieben RL = Rotate LEFT ;
|
50 | MOV R1,A ;----------------------------------------;
|
51 |
|
52 | MOV A,R0 ; aktuellen Counterwert nach A kopieren
|
53 | JNZ LOOP3 ;JumpNotZero | Sprung zum Label LOOP3 wenn Counter != 0
|
54 | CLR TR0 ; Timer 0 stoppen
|
55 | DEC R2 ; Counterwert R2 dekrementieren
|
56 | MOV A,R2 ; R2 nach kopieren
|
57 | JZ LOOP1 ; Sprung zum Label LOOP1 wenn Counter == 0
|
58 | MOV A,R5 ;----------------------------------------;
|
59 | RR A ; R5 ein mal nach rechts rotieren ;
|
60 | MOV R5,A ;----------------------------------------;
|
61 | MOV R1,#00000001b ; R1 auf 1 setzen, Verwendung als Maske
|
62 | MOV R0,#4 ; R0 auf 4 setzen, Counter (4 bis 0)
|
63 | SETB TR0 ; Timer 0 starten
|
64 | JMP LOOP3 ; Sprung zum Label LOOP3
|
65 |
|
66 | ;-------------------
|
67 | ;Interruptroutine
|
68 | ;-------------------
|
69 |
|
70 | ISR_TIM_0: ; Interruptroutine wird im hintergrund immer aufgerufen
|
71 |
|
72 | PUSH PSW ; PSW-Wert auf Stack legen
|
73 | PUSH ACC ; Akkumulator-Wert auf Stack legen
|
74 | DEC R0 ; Counterwert R0 dekrementieren
|
75 | MOV TL0,#timer_low ; Timer0 LowByte / Timer0 Register laden
|
76 | MOV TH0,#timer_high ; Timer0 HighByte / Timer0 Register laden
|
77 | POP ACC ; Akkumulator-Wert vom Stack holen
|
78 | POP PSW ; PSW-Wert vom Stack holen /rekonstruiere PSW
|
79 | RETI ; Rücksprung aus der Interruptroutine
|
80 | END
|