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
von
Vivil (Gast)
24.03.2011 06:53
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.