Forum: Mikrocontroller und Digitale Elektronik [AVR] LED geht bei manchen Programmen nicht ganz aus


von Florian S. (kingeldarion)


Lesenswert?

Guten Tag,

ich bin ein blutiger Anfänger in Microcontrolling und versuche mich 
aktuell durch das AVR-Tutorial zu arbeiten.
Aktuell arbeite ich mit den Timern und habe soweit auch alles gut 
verstanden.
Nun habe ich aber etwas das ich nicht ganz verstehe.

Erstmal zu meiner Hardware:

Ich arbeite mit einem Elegoo/Arduino Uno Rev 3 (Atmega328P).
Jetzt wollte ich eine LED alle x Zeiteinheiten an bzw ausschalten.
Habe also eine LED mit 220 Ohm Widerstand zwischen Ground und einem Pin.

Dazu habe ich den folgenden Code geschrieben:
1
JMP timerStart
2
3
//.include "forLoops.inc"
4
.include "m328pdef.inc"
5
6
.org OVF0addr
7
  JMP timer0_overflow2
8
9
timerStart:
10
  
11
  ldi r21, 1
12
  ldi r17, 0xFF
13
14
  ldi r16, 0xFF
15
  out DDRB, r16
16
17
  ldi r16, 0xFF
18
  out PORTB, r16
19
20
  ldi r16, (1<<CS02)
21
  out TCCR0B, r16
22
23
  ldi r16, (1<<TOIE0)
24
  sts TIMSK0, r16
25
26
  sei
27
28
timerLoop:
29
  JMP timerLoop
30
31
timerChangeLED:
32
  
33
  com r17
34
  out PORTB, r17
35
  RETI
36
37
timer0_overflow:
38
  
39
  adc r20, r21
40
  BRCS timerChangeLED
41
  RETI
42
43
timer0_overflow2:
44
  
45
  add r20, r21
46
  CPI r20, 30
47
  BRSH timerChangeLED
48
  RETI

Je nachdem ob ich beim Interrupt nun timer0_overflow oder 
timer0_overflow2 angebe, habe ich zum einen eine unterschiedliche 
Frequenz in der die LED angeht, was ja auch so sein soll.
Dazu kommt aber, wenn ich timer0_overflow nehme, dann wechselt die LED 
wie sie soll von aus zu an.
Beim timer0_overflow2 jedoch sieht es eher so aus als wenn man von 5V 
auf 3.3V schalten, sie geht nie wirklich aus
Das gilt für den kompletten PortB egal wo ich den Pin für die LED 
anschließe, auch beim PortD hab ich das ganze ausprobiert, selbes 
Ergebnis.

Für mich sieht das irgendwie falsch aus, was da passiert, aber 
vielleicht gibt es da ja irgendeine logische Erklärung für?

Freue mich über Antworten
Mit freundlichen Grüßen
KingEldarion

von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

vor den branch-Befehlen wird immer addiert, so daß es im ersten Fall zu 
weniger häufigem Sprung (branch if carry set) zum Umschalten der LED 
kommt, während im zweiten Fall dies so häufig geschieht, daß Du es mit 
den Augen nur als gedämpfte Helligkeit erkennst.

Ändere mal die Addition, die Konstante 1 und die Konstante 30.
Der Timer löst die IRQs immer genauso oft aus.

MfG

von Stefan E. (sternst)


Lesenswert?

Florian S. schrieb:
> Beim timer0_overflow2 jedoch sieht es eher so aus als wenn man von 5V
> auf 3.3V schalten, sie geht nie wirklich aus

Klar, denn sobald R20 die 30 erreicht, springst du bei jedem Interrupt 
zu timerChnageLED. Also R20<30 -> LED dauerhaft an, R20>=30 -> LED 
wechselt ständig zwischen aus und an.

von Florian S. (kingeldarion)


Lesenswert?

Och Gott bin ich blöd. :D

Ja setze jetzt wieder den Wert auf 0 sobald er 30 erreicht, dann siehts 
auch wieder richtig aus.

Ich war so überzeugt davon das es nicht am Code liegen kann, dass ich 
nicht auf die Idee gekommen bin das mal zu debuggen. Schande über mich.

Danke an euch beide

Grüße
KingEldarion

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.