Mikrocontroller und Digitale Elektronik
›
Thread
Problem mit RGB-LED-Fader Atmega8
Hallo,
ich habe erste vor ein paar Woche mit Assembler und AVR s angefangen.
Gerade versuche ich mit PWM einen RGB-Fader zu programmieren, geht auch
schon recht gut.
Allerdings springt er nicht erst aus den Routinen wenn ocr_X = 00 ist
sonder schon bei recht zufälligen Werten bei rot zbsp: schon bei 242.
Wahrscheinlich habe ich einen ganz einfachen Denkfehler aber ich hoffe
ihr könnt mir trotzdem helfen. 1 .include "m8def.inc"
2
3 .def temp = r16
4 .def PWMCount = r17
5 .def ocr_1 = r18 ; Helligkeitswert Led1: 0 .. 127
6 .def ocr_2 = r19 ; Helligkeitswert Led2: 0 .. 127
7 .def ocr_3 = r20 ; Helligkeitswert Led3: 0 .. 127
8 .def counter = r23
9
10 .org 0x0000
11 rjmp main ; Reset Handler
12 .org OVF0addr
13 rjmp timer0_overflow ; Timer Overflow Handler
14
15 main:
16 ldi counter, $01
17 ldi temp, LOW(RAMEND) ; Stackpointer initialisieren
18 out SPL, temp
19 ldi temp, HIGH(RAMEND)
20 out SPH, temp
21
22 ldi temp, 0xFF ; Port C auf Ausgang
23 out DDRC, temp
24
25 ldi ocr_1, $ff ; Blau
26 ldi ocr_2, $ff ; Grün
27 ldi ocr_3, $ff ; Rot
28
29 ldi temp, 1<<CS00 ; CS00 setzen: Teiler 1
30 out TCCR0, temp
31
32 ldi temp, 1<<TOIE0 ; TOIE0: Interrupt bei Timer Overflow
33 out TIMSK, temp
34
35 sei
36
37 loop:
38 rol counter
39
40 sbrs counter, 0
41 rcall rot_an
42 sbrs counter, 1
43 rcall gruen_an
44 sbrs counter, 2
45 rcall blau_an
46
47 sbrs counter, 3
48 rcall rot_aus
49 sbrs counter, 4
50 rcall gruen_aus
51 sbrs counter, 5
52 rcall blau_aus
53
54 rjmp loop
55
56 ;*****************
57 blau_an:
58 cpi ocr_1, $00
59 breq loop
60 dec ocr_1
61 rcall pause
62 cpi ocr_1, $00
63 brne blau_an
64 ret
65
66 ;****************
67 blau_aus:
68 cpi ocr_1, $fe
69 breq loop
70 cpi ocr_2, $00
71 breq blau_aus_2
72 cpi ocr_3, $00
73 breq blau_aus_2
74 rjmp loop
75
76 blau_aus_2:
77 inc ocr_1
78 rcall pause
79 cpi ocr_1, $fe
80 brne blau_aus_2
81 ldi counter, $01
82 ret
83
84 ;******************
85 Gruen_an:
86 cpi ocr_2, $00
87 breq loop
88 dec ocr_2
89 rcall pause
90 cpi ocr_2, $00
91 brne Gruen_an
92 ret
93 ;***************
94 gruen_aus:
95 cpi ocr_2, $fe
96 breq loop
97 cpi ocr_1, $00
98 breq gruen_aus_2
99 cpi ocr_3, $00
100 breq gruen_aus_2
101 rjmp loop
102
103 Gruen_aus_2:
104 inc ocr_2
105 rcall pause
106 cpi ocr_2, $ff
107 brne Gruen_aus_2
108 ret
109 ;*************
110 Rot_an:
111 cpi ocr_3, $00
112 breq loop
113 dec ocr_3
114 rcall pause
115 cpi ocr_3, $00 <--Hier springt er schon bei 242 nicht mehr zu rot_an
116 brne Rot_an
117 ret
118 ;**********
119 rot_aus:
120 cpi ocr_3, $fe
121 breq loop
122 cpi ocr_1, $00
123 breq rot_aus_2
124 cpi ocr_2, $00
125 breq rot_aus_2
126 rjmp loop
127
128 Rot_aus_2:
129 inc ocr_3
130 rcall pause
131 cpi ocr_3, $fe
132 brne Rot_aus_2
133 ret
134
135 timer0_overflow: ; Timer 0 Overflow Handler
136 inc PWMCount ; den PWM Zähler von 0 bis
137 cpi PWMCount, 127 ; 127 zählen lassen
138 brne WorkPWM
139 clr PWMCount
140
141 WorkPWM:
142 ldi temp, 0b11000000 ; 0 .. Led an, 1 .. Led aus
143
144 cp PWMCount, ocr_1 ; Ist der Grenzwert für Led 1 erreicht
145 brlo OneOn
146 ori temp, $01
147
148 OneOn: cp PWMCount, ocr_2 ; Ist der Grenzwert für Led 2 erreicht
149 brlo TwoOn
150 ori temp, $02
151
152 TwoOn: cp PWMCount, ocr_3 ; Ist der Grenzwert für Led 3 erreicht
153 brlo ThreeOn
154 ori temp, $04
155
156 ThreeOn:
157 ori temp, $08
158
159 SetBits: ; Die neue Bitbelegung am Port ausgeben
160 andi temp, 0b00000111
161 out PORTC, temp
162
163 reti
164
165 pause:
166 ; =============================
167 ; Warteschleifen-Generator
168 ; 20000 Zyklen:
169 ; -----------------------------
170 ; warte 19998 Zyklen:
171 ldi R21, $21
172 WGLOOP0: ldi R22, $C9
173 WGLOOP1: dec R22
174 ;brne WGLOOP1
175 dec R21
176 ;brne WGLOOP0
177 ; -----------------------------
178 ; warte 2 Zyklen:
179 nop
180 nop
181 ; =============================
182 ret
Du solltest in der Interruptroutine timer0_overflow unbedingt das sreg
sichern.
Thomas
Danke!
Jetzt läuft es.
Gruß Michael
V
Vivil
Gast
24.03.2011 06:53
#2116659
Ich würde mal diese Zeilen bedenken. Ansonsten hast du einen Zeitbombe.
1 blau_an:
2 cpi ocr_1, $00
3 breq loop
4
5
6 blau_aus:
7 cpi ocr_1, $fe
8 breq loop
9
10
11 Gruen_an:
12 cpi ocr_2, $00
13 breq loop
14
15
16 gruen_aus:
17 cpi ocr_2, $fe
18 breq loop
19
20 Rot_an:
21 cpi ocr_3, $00
22 breq loop
23
24
25 rot_aus:
26 cpi ocr_3, $fe
27 breq loop
Ich habe es mittlerweile von fe auf ff geändert, kann dir aber nicht
ganz folgen. Kannst du mir etwas genauer erklären, was du mit Zeitbombe
meinst?
Gruß Michael
↑ Nach oben
← Zurück zu Mikrocontroller und Digitale Elektronik
Antwort schreiben