Forum: Mikrocontroller und Digitale Elektronik [AVR] PWM "auf Knopfdruck" - Programm geht nicht


von Memmels (Gast)


Lesenswert?

Guten Morgen

ich bin AVR-Anfänger und möchte ein Programm schreiben, mit dem man PWM 
"auf Knopfdruck" ändern kann. Als Anhaltspunkt habe ich die Programme 
vom AVR-Tutorial auf dieser Seite hier verwendet: Das erste (zu finden 
im Kapitel Interrupts) schaltet eine LED an und aus, das zweite (zu 
finden bei PWM) war eine Reihe von LEDs mit unterschiedlicher Dimmung.
So, jetzt zu meinem Programm: Der Tasterdruck sorgt für die fallende 
Flanke bei PD2 bzw. PD3 und löst INT0 bzw. INT1 aus. Diese externen 
Interrupts machen nichts anderes als die Bedingung, die LED 
auszuschalten, zu verändern. (Den PWM-Wert sozusagen)
Das übliche Programm funktioniert so wie "PWM in Software", nämlich, 
dass bei einem Timer-Overflow der PWMCounter mit dem PWM-Wert verglichen 
wird und ggf. die LED an bleibt bzw. aus geschalten wird. So - soviel 
dazu.
Im Debugging-Modus von AVR-Studio funktioniert alles wunderbar!? 
Komischerweise funktionierts auf dem Board (STK500, was sonst) nicht.

Vielen Dank für alle hilfreichen Antworten, hier noch der Code.

P.S.: Mir ist bewusst, dass bei dem Programm die Entprellung der Taster 
nicht berücksichtigt wird, daran liegts aber auch nicht.
1
.include "m8def.inc"
2
 
3
.def temp  = r16
4
 
5
.def PWMCount = r17          ;PWM-Zähler
6
 
7
.def pwm1 = r18            ;Helligkeits- bzw. PWM-Wert Led: 0 - 127
8
9
.org 0x000
10
       rjmp main
11
.org INT0addr                     ;External Interrupt0 Vector Address
12
       rjmp  int0_handler                   
13
.org INT1addr                     ;External Interrupt1 Vector Address
14
       rjmp int1_handler                  
15
.org OVF0addr                     ;Overflow0 Interrupt Vector Address
16
       rjmp timer0_overflow                                    
17
18
main:
19
        ldi     temp, LOW(RAMEND)  ;Stackpointer initialisieren
20
        out     SPL, temp
21
        ldi     temp, HIGH(RAMEND)
22
        out     SPH, temp
23
  
24
        ldi     temp, 0xFF      ;Port B auf Ausgang
25
        out     DDRB, temp
26
 
27
    ldi    temp, 0x00
28
    out    DDRD, temp      ;Port D auf Eingang
29
30
    ;Timer Setup
31
    ldi    temp, 1<<CS00    
32
    out    TCCR0, temp      ;Teiler 1
33
    ldi    temp, 1<<TOIE0    
34
    out    TIMSK, temp      ;Interrupt bei Timer-Overflow
35
    ;Taster-Interrupt Setup
36
    ldi    temp, 1<<ISC01 | 1<<ISC11
37
    out    MCUCR, temp      ;fallende Flanke
38
    ldi    temp, 1<<INT0 | 1<<INT1
39
    out    GICR, temp      ;INT0 und INT1 aktivieren
40
41
    sei
42
43
    ldi    pwm1, 50      ;Standart-PWM Wert 50
44
    ldi    temp, 0x00
45
    out    PORTB, temp      ;LEDs an
46
47
loop:  rjmp loop          ;leere Endlosschleife
48
49
int0_handler:
50
    
51
    ldi    pwm1, 30
52
    reti            ;Bei Switch-X PWM-Wert 30
53
54
int1_handler:
55
56
    ldi    pwm1, 70
57
    reti            ;Bei Switch-Y PWM-Wert 70
58
59
timer0_overflow:
60
61
    inc    PWMCount      
62
    cpi    PWMCount, 128    
63
    brne  WorkPWM        ;PWM-Zähler von 0 bis 127
64
    clr    PWMCount      ;zählen lassen
65
66
WorkPWM:
67
68
    cp    PWMCount, pwm1    ;wenn Zähler kleiner PWM-Wert
69
    brlo  SetBits        ;nach SetBits springen, LEDs bleiben an
70
    ori    temp, 0xFF      ;wenn nicht, LEDs aus
71
72
SetBits:
73
    out    PORTB, temp      ;Neue Bitbelegung am Port ausgeben
74
75
    reti

von Karl H. (kbuchegg)


Lesenswert?

Memmels schrieb:


>     ldi    temp, 0x00
>     out    DDRD, temp      ;Port D auf Eingang

Brauchen deine Taster keinen Pullup?



> loop:  rjmp loop          ;leere Endlosschleife

Dein µC tut die ganze Zeit nichts anderes als Däumchen drehen. Das muss 
mir mal wer erklären, warum man da Tasten über Interrupts abfragen muss. 
Wahrscheinlich deshalb, damit man mehr Fehlerquellen hat. Wär ja auch 
sonst zu einfach.

von Memmels (Gast)


Lesenswert?

zu den Pull-Ups: Hab ich bei den bisherigen Testprogrammen nicht 
gebraucht und dachte deswegen, dass auf dem Board evtl "externe" 
Wiederstände drauf sind.
Zur Endlosschleife: Jo, richtig. Er wartet bis der Timer-Overflow 
Interrupt kommt oder bis nen Taster gedrückt wird. Wo ist denn jetzt das 
Problem dabei? Verstehe ich nicht ganz :) Was wäre denn eine 
funktionsfähige Alternative? Sorry, dass ich da anscheinend noch etwas 
planlos bin, eine Erklärung wäre super!
Danke

von spess53 (Gast)


Lesenswert?

Hi

>Brauchen deine Taster keinen Pullup?

Sind auf dem STK500.

>Im Debugging-Modus von AVR-Studio funktioniert alles wunderbar!?
>Komischerweise funktionierts auf dem Board (STK500, was sonst) nicht.

Was funktioniert?

>   ori    temp, 0xFF      ;wenn nicht, LEDs aus

Ab der Stelle bleibt temp für alle Ewigkeit auf $FF und

>SetBits:
>    out    PORTB, temp      ;Neue Bitbelegung am Port ausgeben

damit bleiben die LEDs genau so lange aus.

MfG Spess

von Memmels (Gast)


Lesenswert?

Ach, na klar vielen Dank! Für alle, die es noch interessiert: Einfach in 
WorkPWM die LEDs vorher anmachen. Das sieht dann so aus.
1
WorkPWM:
2
    ldi    temp, 0x00        ;LEDs an
3
    cp    PWMCount, pwm1     ;wenn Zähler kleiner PWM-Wert
4
    brlo  SetBits            ;nach SetBits springen, LEDs bleiben an
5
    ori    temp, 0xFF        ;wenn nicht, LEDs aus

Bisher ist man allerdigns auf 2 Taster begrenzt, weil es ja über die 
Interrupts vll nicht ganz so elegant ist (Int0 und Int1). Falls sich 
jemand noch die Mühe machen möchte, wie wäre das ganze jetzt mit 
"beliebig vielen" Tastern umsetzbar? Das ist mir noch ein Rätsel!

von spess53 (Gast)


Lesenswert?

Hi

>Falls sich
>jemand noch die Mühe machen möchte, wie wäre das ganze jetzt mit
>"beliebig vielen" Tastern umsetzbar? Das ist mir noch ein Rätsel!

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten

MfG Spess

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.