ledtest2.asm


1
;********   ledtest2.asm   ********
2
; Testprogramm für AVR-Demoboard mit AT90S1200
3
; Durchzählen der LEDs per Timer0
4
; 
5
; Autor: J. Zimmermann    Status: getestet
6
; Datum: 08.06.1998    Version: 1.0
7
;
8
; Ing.-Büro Josef Zimmermann
9
; Copyleft nach GNU GPL
10
; 
11
; Konfiguration der Harware: Atmel Evaluationboard
12
; Verbindung per Flachbandkabel von LEDs mit PortB
13
;
14
; Für AVR-ASM V1.21 oder höher
15
; Bitte den sleep-Befehl nicht im Simulator verwenden!
16
;
17
; Die Art und Weise in der die Hardware-Register initialisiert werden ist nicht ganz 
18
; sauber. Besser wäre es zunächst das Register zu lesen, den Wert über Bit-Befehle zu
19
; ändern und dann zurück zu schreiben. Spätestens bei der Portierung auf einen anderen
20
; Controller der AVR-Familie kann es sonst zu Problemen kommen. Darüber hinaus muß bei
21
; der Portierung der Stackpointer initialisiert werden, was sich beim 90S1200 
22
; erübrigt, wegen des Hardwarestacks.
23
;
24
;********************************************
25
; Etwas Theorie zum Timer
26
; Es soll ein Timer_tic von 50ms erzeugt werden. Dieser steuert per Interrupt das 
27
; hochzählen des Ausgangsports. Das Demo-Board ist mit einem 4MHz-Quarz bestückt.
28
; Ein Interrupt wird beim Timer0 überlauf ausgelöst. Damit ergibt sich:
29
; 
30
; TCNT0 = 256 - (T_tic / ( T_clk * Kprescale)) 
31
; TCNT0 = 61 für T_tic = 50ms  T_clk = 1/4 us und Kprescale = 1024
32
;
33
; als Randbedingung für den Prescaler ist folgendes zu beachten:
34
; 
35
; Kprescale > (T_tic / (T_clk * 256))
36
;
37
; Wir T_tic größer als T_clk * 1024 * 256 kann man den Takt über einen Softwarezähler 
38
; weiter herunterteilen. Die Altenative wäre ein exter Takt (passender Frequenz) zum
39
; takten des Timer/Counters.
40
41
42
.include "1200def.inc"
43
.device AT90S1200
44
45
.def  Temp  =r16    ;temporary register
46
.def  L_Temp  =r17
47
48
49
;***** Reset- und Interrupt-Vektoren
50
51
RESET:  rjmp  ihMain    ;000 Reset Einsprung
52
  rjmp  ihIrq0    ;001 IRQ0
53
  rjmp  ihTimer0_ovf  ;002 Timer/Counter0 overflow
54
  rjmp  ihAna_cmp  ;003 Analog Comparator
55
56
57
;*** Initialisierung PortB, Timer0, Interrupte und IDLE-Mode  
58
ihMain:
59
  ser  Temp    ;Temp = 0xff
60
  out  DDRB,Temp  ;PORTB = alle Pins outputs
61
  out  PORTB, Temp  ;PORTB = 0xff -> alle LEDs aus, Low aktiv!
62
63
  ldi  L_Temp, 0x3d  ;TCNT0 := 61dez. = 0x3d  Timerregister mit Wert laden
64
  out  TCNT0, L_Temp
65
66
  ldi  L_Temp, 0x05  ;TCCR0 := 00000101b = 0x05  Prescalefaktor 1024 
67
  out  TCCR0, L_Temp
68
69
  ldi  L_Temp, 0x02  ;TIMSK := 00000010b = 0x02  Enable Timer0 overflow INT
70
  out  TIMSK, L_Temp
71
72
  sei      ;SREG Global Interrup enable
73
74
  ldi  L_Temp, 0x20  ;MCUCR := 00100000b = 0x20 IDLE MODE per "sleep"
75
  out  MCUCR, L_Temp
76
77
;*** Das eigentliches Hauptprogramm tut nichts, außer schlafen!   
78
; Achtung!!! "sleep" nicht auf dem Simulator verwenden! 
79
forever:      ; 
80
   sleep      ;CPU sagt gute Nacht bis der Timer klingelt. IDLE MODE!
81
  rjmp  forever    ;Und das ganze noch mal von vorne
82
83
84
85
;**** Timer overflow Interrupt 
86
; Die TOV0-Flag (im Register TIFR) wird automatisch mit Aufruf des Interruptvectors 
87
; zurückgesetzt. Die I-Flag (im Status-Register) wird mit RETI zurückgesetzt.
88
89
ihTimer0_ovf:
90
  ldi  L_Temp, 0x3d  ;TCNT0 := 0x31  Timerregister laden
91
  out  TCNT0, L_Temp
92
  out  PORTB,Temp  ;PORTB := Temp  
93
  dec  Temp    ;Temp := Temp - 1
94
  reti
95
96
97
;****** Ist etwas schiefgegangen? ****
98
; Diese Routinen dürfen eigentlich nicht angesprungen werden, da diese Interrupts 
99
; nicht frei gegeben sind. (Hilfreich beim debuggen) Die Routine endet in einer 
100
; Endlosschleife, weil kein RETI ausgeführt wird und damit der Global Interrupt 
101
; (I-Bit im Status Register) disabled bleibt!
102
; Es wird ein Fehler-Code auf die LEDs ausgegeben und das Programm hängt fest.
103
104
ihIRQ0:
105
  ldi  Temp, 0xfe  ;Wert für LED0 ein
106
  rjmp  INT_ERR    ;
107
108
ihAna_cmp:
109
  ldi  Temp, 0xfd  ;Wert für LED1 ein
110
  rjmp  INT_ERR
111
112
INT_ERR:
113
  out  PORTB, Temp  ;Error Wert an LEDs anzeigen
114
  rjmp  INT_ERR
115
116
117
VERSION:  .DB  "LEDTEST2.ASM FUER AVR 90S1200 Version 1.0 "