Forum: Mikrocontroller und Digitale Elektronik Software-PWM


von Andy11 (Gast)


Lesenswert?

ich habe jetzt eine Software-PWM geschrieben und weiß nicht warum sie 
nicht funktioniert:
1
;**********************************Header**************************************
2
;* Projektname:                                  *
3
;* Name des Erstellers:                              *
4
;* Zuletzt aktualisiert:                            *
5
;*                                        *
6
;*                                        *
7
;******************************************************************************
8
9
10
;*****************************Initialisierungen********************************
11
.include "m16def.inc" ;Definitionsdatei des Mega16
12
13
;Stackpointer-init***********
14
  ldi r16, High(Ramend)
15
  out SPH, r16
16
17
  ldi r16, Low(Ramend)
18
  out SPL, r16
19
20
;ADC-init***********
21
22
;*****************Deklarierete Funktionen und Subroutinen**********************
23
24
;*************************Variablendeklarationen*******************************
25
26
;*****************************Ein-Ausgänge*************************************
27
  ser r16      ;Setze Registerinhalt auf 255 (ldi r16, 255)
28
  out DDRB, r16   ;Portb als Ausgabeport
29
30
;******************************************************************************
31
32
clr r16 
33
;*****************************Hauptprogramm************************************
34
Hauptprogramm:
35
Rauf:  inc r16        ;Zähler raufzählen
36
    
37
    cpi r16, 127
38
    brsh setzeBit    ;wenn r16 >= 127 ist dann setze Bits in PORTB 
39
    
40
    cpi r16, 255    ;Vergleiche ob Zahl schon maximum
41
    brne Rauf       ;wenn nein dann zähle weiter hoch
42
  
43
Runter:  dec r16        ;wenn ja dann zähle runter
44
45
    cpi r16, 127
46
    brlo loescheBit    ;wenn r16 <= 127 ist dann lösche Bits in PORTB 
47
48
    cpi r16, 0      ;Vergleiche ob 0
49
    brne Runter      ;wenn nicht null dann zählew weiter runter
50
51
jmp Hauptprogramm      ;wenn null dann fang wieder neu an
52
53
54
;***********************Unterprogramme/Funktionen******************************
55
56
setzeBit:
57
  push r16
58
    ldi r16, 255
59
    out PORTB, r16
60
  pop r16
61
ret
62
63
loescheBit:
64
  push r16
65
    ldi r16, 0
66
    out PORTB, r16
67
  pop r16
68
ret

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Unterprogramme werden nicht mit branch bzw. jump angesprungen, 
sondern mit call aufgerufen... :-o
Nur dann funktioniert auch der ret

Warum zählst du rauf und runter?
PWM wird üblicherweise so gemacht: ein Zähler zählt von 0 bis zum 
Endwert. Solange der Zähler kleiner ist als ein Grenzwert, wird eine 1 
ausgegeben, sonst eine 0.

von Andy11 (Gast)


Lesenswert?

>Unterprogramme werden nicht mit branch bzw. jump angesprungen,
>sondern mit call aufgerufen... :-o
>Nur dann funktioniert auch der ret
1
;**********************************Header**************************************
2
;* Projektname:                                  *
3
;* Name des Erstellers:                              *
4
;* Zuletzt aktualisiert:                            *
5
;*                                        *
6
;*                                        *
7
;******************************************************************************
8
9
10
;*****************************Initialisierungen********************************
11
.include "m16def.inc" ;Definitionsdatei des Mega16
12
13
;Stackpointer-init***********
14
  ldi r16, High(Ramend)
15
  out SPH, r16
16
17
  ldi r16, Low(Ramend)
18
  out SPL, r16
19
20
;ADC-init***********
21
22
;*****************Deklarierete Funktionen und Subroutinen**********************
23
24
;*************************Variablendeklarationen*******************************
25
26
;*****************************Ein-Ausgänge*************************************
27
  ser r16      ;Setze Registerinhalt auf 255 (ldi r16, 255)
28
  out DDRB, r16   ;Portb als Ausgabeport
29
30
;******************************************************************************
31
32
clr r16 
33
;*****************************Hauptprogramm************************************
34
Hauptprogramm:
35
36
Rauf:  inc r16        ;Zähler raufzählen
37
    
38
    cpi r16, 250
39
    brsh setzeBit    ;wenn r16 >= 127 ist dann setze Bits in PORTB 
40
41
Weiter1:
42
    
43
    cpi r16, 255    ;Vergleiche ob Zahl schon maximum
44
    brne Rauf       ;wenn nein dann zähle weiter hoch
45
  
46
Runter:  dec r16        ;wenn ja dann zähle runter
47
48
    cpi r16, 250
49
    brlo loescheBit    ;wenn r16 <= 127 ist dann lösche Bits in PORTB 
50
51
Weiter2:
52
53
    cpi r16, 0      ;Vergleiche ob 0
54
    brne Runter      ;wenn nicht null dann zählew weiter runter
55
56
jmp Hauptprogramm      ;wenn null dann fang wieder neu an
57
58
59
;***********************Unterprogramme/Funktionen******************************
60
61
setzeBit:
62
  push r16
63
    ldi r16, 255
64
    out PORTB, r16
65
  pop r16
66
jmp Weiter1
67
68
loescheBit:
69
  push r16
70
    ldi r16, 0
71
    out PORTB, r16
72
  pop r16
73
jmp Weiter2


so funktioniert es aber

>Warum zählst du rauf und runter?
>PWM wird üblicherweise so gemacht: ein Zähler zählt von 0 bis zum
>Endwert. Solange der Zähler kleiner ist als ein Grenzwert, wird eine 1
>ausgegeben, sonst eine 0.

das wäre natürlich auch eine möglichkeit, ich hab das hier bildlich dem 
timer nachgeschrieben, timer zählt mit frequenz rauf und mit frequenz 
runter

jedoc dnke für deinen Einwand, das hat mir zum Lösungsweg verholfen

lg andy

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Warum verwendest du nicht eines der anderen Register?
1
;**********************************************************************
2
clr r16 
3
clr r0        ; alles 0
4
ser r1        ; alles 1
5
;***********************Hauptprogramm**********************************
6
Hauptprogramm:
7
8
Rauf:  inc r16        ;Zähler raufzählen
9
    cpi r16, 250
10
    brlo Weiter1    ;wenn r16 >= 127 ist dann setze Bits in PORTB !!!!!!!! falscher Kommentar !!!!!
11
                    ;!!!!! Zahlenwerte niemals in Kommentare schreiben  !!!!!!!!!!!!!
12
    out PORTB, r1
13
Weiter1:
14
    cpi r16, 255    ;Vergleiche ob Zahl schon maximum
15
    brne Rauf       ;wenn nein dann zähle weiter hoch
16
  
17
Runter:  dec r16        ;wenn ja dann zähle runter
18
    cpi r16, 250
19
    brsh Weiter2    ;wenn r16 <= 127 ist dann lösche Bits in PORTB 
20
    out PORTB, r0
21
Weiter2:
22
    cpi r16, 0      ;Vergleiche ob 0
23
    brne Runter      ;wenn nicht null dann zählew weiter runter
24
25
jmp Hauptprogramm      ;wenn null dann fang wieder neu an

von Andy11 (Gast)


Lesenswert?

>Warum verwendest du nicht eines der anderen Register?

ist es denn nicht besser wenn ich mit einem auskomme?
außerdem find ich es ist übersichtlicher

lg andy

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> ist es denn nicht besser wenn ich mit einem auskomme?
Du hast die anderen Register auch gekauft und mitbezahlt. Warum solltest 
du sie dann nicht verwenden? Oder verwendest du im Auto auch nur den 3. 
Gang?  :-o

> außerdem find ich es ist übersichtlicher
Naja....
BTW: C-Compiler machen es gerne auch so, dass Register mit "üblichen" 
Werten vorbelegt werden. In deinem Programm sind 0x00 und 0xFF "üblich".

von Andy11 (Gast)


Lesenswert?

>Du hast die anderen Register auch gekauft und mitbezahlt. Warum solltest
>du sie dann nicht verwenden? Oder verwendest du im Auto auch nur den 3.
>Gang?  :-o

ich werde auch nicht mein ganzes Leben nur diesen einem Programm witmen, 
da gibt es auch umfangreichere Sachen und daher mein einwand!

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.