Forum: Mikrocontroller und Digitale Elektronik AVR/ASM Tip zu abgeänd. PWM-Helligkeit Tut. (Helligkeit über Taster)


von Manuel T. (tedd)


Lesenswert?

Hi!

Ich versuche mich gerade an dem PWM Tutorial:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_PWM

Das untere CodeBeispiel zeigt ja wie die LED's unterschiedlich hell 
leuchten.

Ich nutze ein STK500 mit ATmega8515(L) und soweit klappt das auch,  das 
wichtigste habe ich wohl noch nicht verstanden und zwar das mit dem 
Interrupt aber das soll erstmal egal sein...

Ich habe jetzt versucht, dass ich die Helligkeitsstufen (erstmal von der 
ersten LED) über die Taster hochlaufen lassen kann um somit die 
Helligkeit der jeweiligen LED ändern zu können nur klappt das ganze 
nicht - es tut sich nämlich nichts wenn ich den Taster drücke und ich 
vermute, dass es daran liegt, dass ich das ganze irgendwie auch mit 
einem Interrupt machen muss!?

folgenden Code habe ich eingefügt
1
loop:           
2
    in     temp, PIND        ; Lese Status der Taster in temp ein
3
    CPI   temp, 0b00000001    ; Prüfe ob Taster 1 gedrückt ist...
4
    BREQ   inc_ocr_1        ; ... wenn ja, dann Springe zu inc_ocr_1
5
    
6
    rjmp    loop
7
8
inc_ocr_1:
9
    inc ocr_1            ; inkrementiere ocr_1
10
    CPI ocr_1, 127           ; Prüfe ob Helligkeitswert überschritten
11
    BRLO loop            ; wenn nicht springe zurück zu loop
12
    ldi ocr_1, 0          ; wenn doch, setze ocr_1 = 0
13
    rjmp loop            ; zurück zu loop

Danke schonmal für eure Hilfe und besten Gruß,
Manuel

von Manuel T. (tedd)


Lesenswert?

Sorry, dass ich das Thema wieder hochhole, aber ich glaube nicht, dass 
mir hier niemand eine kurze Antwort liefern kann :)
Also woran liegt's?

Danke und Gruß,
Manuel

von Heiko (Gast)


Lesenswert?

Bist du sicher, dass der Taster nach VCC schaltet und alle anderen Pins 
auf Masse liegen? Sonst bekommst du garantiert nicht 0b00000001 in 
PIND...

Üblicherweise macht man das in Assembler mit "skip if bit in 
i/o-register set" bzw. "...cleared" - wie der Befehl in Kurzform heißt, 
weiß ich nicht, ich habe lange nicht mehr in Assembler programmiert.

Nächstes Problem: Wie oft (wie viele Millionen Mal pro Sekunde) wird das 
angesprungen? Wie schnell würde er also hochzählen?

MfG, Heiko

von ArRaY (Gast)


Lesenswert?

Ich denke auch, dass es an dem 0x00000001 liegt.
Probier mal ein andi temp, 0b00000001 davor zu schreiben zum test...

von Manuel T. (tedd)


Lesenswert?

Danke für die Hilfe ihr beiden! Es lag wirklich daran. ouh mman - sorry, 
dass ich sowas scheinbar einfaches übersehen habe.

Heiko wrote:
> Nächstes Problem: Wie oft (wie viele Millionen Mal pro Sekunde) wird das
> angesprungen? Wie schnell würde er also hochzählen?
>
> MfG, Heiko

Tatsächlich... Wenn ich den Taster drücke, zählt der so schnell hoch, 
dass es eher Zufall ist, was für eine Helligkeit die LED dann hat.

Wie verlangsame ich das ganze jetzt am praktischsten?
Muss ich jetzt eine Vorschleife in
1
inc_ocr_1:
einbauen, die bis zu einem bestimmten Wert läuft bis dann inkrementiert 
wird?
Wenn ja, welcher Wert wäre denn sinnvoll?
Ahja der Systemtakt, dürfte glaube ich 1MHz sein? Aufjedenfall steht im 
Datenblatt, dass der ATmega8515 mit diesem als Standardeinstellung 
ausgeliefert wird und ich habe da denke ich noch nichts dran geändert.
Läuft der Zähler dann mit 1/1000000 s hoch?

Danke und Gruß,
Manuel

von Manuel T. (tedd)


Angehängte Dateien:

Lesenswert?

Also, dass Problem was ich hatte, habe ich jetzt so gelöst, dass ich bei 
jedem Interruppt der durch einen Overflow aufgerufen!? wird eine 
Variable hochzählen lasse. Die Variable wirkt dann wie ein Prescaler?! 
Wenn die Variable hochgezählt ist, kommt noch ein kleiner Zähler (weil 
ich mit dem ersten Zähler nicht höher als 255 zählen kann) der auch 
hochgezählt haben muss und dann wird erst die Helligkeitsstufe der LED 
um 1 inkrementiert...

Funktioniert soweit eigtl so wie ich das wollte, nur kommt mir das etwas 
unschön vor, weil ich jetzt nur für das hochzählen 2 weitere Register 
bzw Variablen belege und auch 2 schleifen habe.
Der Grund warum ich nicht einfach den Prescaler vom Counter0 geändert 
hab ist ja, dass der glaube ich schon passend für die PWM eingestellt 
ist, also kann ich den nicht ändern, oder?

Hatte auch noch überlegt den 16Bit Counter irgendwie einzustellen aber 
das war mir grad zu hoch und extra einen 16Bit Counter für diese 
"einfache" Aktion schien mir dann auch ein bisschen zu viel Aufwand.

Kann man das vielleicht alles in eine Schleife in der man auch nur 1 
Register nutzt packen oder sonst irgendwie eleganter machen?

Der ASM-Code so wie er jetzt funktioniert ist angehängt.

Danke und Gruß,
tedd

von Manuel T. (tedd)


Lesenswert?

Hi!
Ich wollte nochmal nachfragen, ob das wirklich eine sinnvolle Lösung mit 
den 2 Registern zum "Vorzählen" ist, aber was anderes fällt mir auch 
nicht ein.
Wenn ich das richtig verstanden habe ist im ATmega8515 auch ein 16 Bit 
Register was ich dafür benutzen könnte anstatt 2 8-bit Register. Nur ist 
fraglich ob das dann nicht "überdimensioniert" ist.
Aber bei so einem kleinen Programm muss man sich da ja eh nicht wirklich 
Gedanken machen.
Falls es sonst noch irgendwelche Anregungen zum ProgrammCode gibt - 
immer her damit - kann ich als Anfänger gut gebrauchen ;)

Danke und Gruß,
manuel

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.