Forum: Mikrocontroller und Digitale Elektronik Problem mit PWM bei Mega8


von danny (Gast)


Angehängte Dateien:

Lesenswert?

Hallo. Ich habe ein kleines Problem. Ich habe im momment ein neues 
projekt. Bei diesem werden 2 motoren über jeweils einen transistor 
geschalten.Nun habe ich das Problem mit dem timer 1 beim mega8. Ich 
poste euch mal mein programm:

.include"m8def.inc"
// r16 und r17 sind die register für die PWM der motoren
//r18 aufwärts können so verwendet werden

// MEGA MIT 8 MHZ

initiallisierung:
timer_und_stack:
ldi r18, HIGH(RAMEND)     ; Stackpointer initialisieren
out SPH, r18
ldi r18, LOW(RAMEND)
out SPL, r18

timer:
ldi r16, 0b00000011
out ddrb, r16

ldi      r16, 0b10100010  //modus festlegen
out      TCCR1A, r16
ldi r16, 0b00011001      //timer prescaler festlegen   0b00000011= 64 
0b00000111=1024
out TCCR1B, r16        // 1024 im realenmodus zum verwenden. 64er 
prescaler nur zum testen im AVR studio
ldi r16, 0xFF
out ICR1H, r16        //soweit zählt der timer
out ICR1L, r16

ldi r16, 0xFF
ldi r17, 0x3F

out OCR1AH, r17        // wenn der timer diesen wert erreicht schaltet 
er
              // den ausgangspin ab
out OCR1AL, r16
out OCR1BH, r17
out OCR1BL, r16
          //             __________________
          //            |           |
          //0x3fff-0xffff |0x0000-0x3fff     |    usw.
          //______________|           |______


ADC_initiallisierung:
ldi r18, 0b11100111
out ADCSRA, r18
ldi r18, 0b00100000
out ADMUX, r18
ldi r18, 0
rjmp main

normalzustand:
sbi ddrb, 2
ldi r17, 0x3F
out OCR1AH, r17

main:
in r18, ADCH
ldi r20, 70   //(normalwert für den ADC. Areff liegt mit kondensator auf 
GND. Messbereich also 5V/256 zustände =0.01953125V*70
        //1,3671875V die anliegen müssen, dass der lenkvorgang 
eingeleitet wird.

cp r18, r20
brge r20match
rjmp main


r20match: // einer bleit stehen in dem sein DDRB eintrag auf eingang 
gelegt wird

cbi ddrb, 2
ldi r16, 0x00
out OCR1AH, r16

rjmp warten_und_lencken






warten_und_lencken:
ldi r30, 255
ldi r31, 255

ldi r29, 255
ldi r28, 255
ldi r27, 255
ldi r26, 255
a1:
nop
nop
nop
nop
nop
nop
nop
nop
dec r30
brne a1
dec r31
brne a1
dec r29
brne a1
dec r28
brne a1
dec r27
brne a1
dec r26
brne a1
rjmp normalzustand




nun will ich das der timer bis OCR1A und OCR1B in denen jeweils die 
gleichen werte stehen zählt. Dann den PORT des timers(ich glaube pini 15 
und 16 war es. müsst ich nochma gucken.) Also den OC1A und den OC1B 
anschaltet wenn der timer bei null beginnt. und jeweils den 
entsprechenden Abschaltet wenn der timer den wert in OCR1A(und B) 
erreicht. dann bis 0xFFFF weiterzählt und wieder bei 0 beginnt, wieder 
die ports anschaltet und so weiter.

Nun mein Problem.
1. der timer zählt nur bis zum wert in OCR1A(B) und zählt dann rückwärts 
bis null. Das soll er aber nicht. Er soll weiterzählen bis 0xffff( steht 
in ICR1) und dann wieder bei null beginnen.
2. ER schaltet bei mir im AVR studio beim erreichen von den OCR!A(B) 
werten den PIN B0 und 1 an statt den portb 0 und 1.

im anhang das prog als ASM.

Ich hoffe ihr könnt mir helfen.

euer danny

PS: Toturial hab ich schon durgeguckt hat mir aber leider nich viel 
geholfen.

von spess53 (Gast)


Lesenswert?

Hi

>ldi      r16, 0b10100010  //modus festlegen

Benutze bitte die Schreibweise ldi r16, 1<<COM1A0|1<<...

Oder sollen wir erst im Datenblatt suchen, welche Bits du meinst?

MfG Spess

von Spezi (Gast)


Lesenswert?

Hallo,

Zum Verständnis:

Du hast eine Controller-Taktfrequenz von 8 MHz, einen Timer-Prescaler 
von 1024 und willst eine 16bit-PWM (0x0000 bis 0xFFFF) erzeugen.
Das ergibt rechnerisch eine PWM-Frequenz von ((8MHz % 1024) % 2^16) ca. 
0,12Hz. Damit kannst du keinen Motor betreiben!

Also, wie sollen die 'realen' Werte nun aussehen?

> der timer zählt nur bis zum wert in OCR1A(B) und zählt dann rückwärts
> bis null. Das soll er aber nicht.

Das sieht nach einer "Phase correct PWM" aus; dort ist das Timer- 
Verhalten so.

von danny (Gast)


Lesenswert?

sry wegen dem prescaler. Ich habs vorher nur abgeschätzt( grob). Ich 
dencke 64 passt da als prescaler dann schon besser....

Sry, was ist eine phase correct PWM? Und wie kann ich das umstellen, 
dass das so leuft wie ich möchte.

@spess

sry wegen der schreibweise.

von danny (Gast)


Lesenswert?

weil wenn ich das richtig aus dem datenblatt verstanden habe brauche ich 
ja fast PWM für meine zwecke.(sry für 2te antwort)

von Spezi (Gast)


Lesenswert?

Hallo,

ein Prescaler von 64 ist genauso unsinnig (PWM-Frequenz: ca. 1,9 Hz) ...
Auch eine PWM-Auflösung von 16bit für eine Motorsteuerung halte ich für 
ziemlich übertrieben. Aber sei es so.

Hier mal ein paar sinnvolle Anhaltspunkte (programmieren musst du sie 
schon selber):

- Timer-Modus: Fast PWM, Modus 14
- Prescaler = 1; bei 16bit PWM-Auflösung ergibt sich so eine PWM-
  Frequenz von ca. 122 Hz. Gut geeignet für Motorsteuerungen.
- Maximalwert (0xFFFF) wird ins Register ICR1 geschrieben.
- Die PWM-Ausgänge auf Standard-PWM einstellen (siehe Mega8-Datenblatt:
  COM1xx-Bits)
- Die jeweiligen PWM-Werte werden in die Register OCR1A und OCR1B
  geschrieben.

Ein PWM-Wert von Null ergibt keine Ansteuerung des Motors; ein 
Umschalten der Pins auf Eingang kann problematisch werden.

Wenn eine kleinere PWM-Auflösung benutzt werden soll, so wird der 
ICR1-Wert angepasst. Dadurch ändert sich aber auch die PWM-Frequenz!

Ich weiss nicht, was die Motoren an Strom ziehen, aber es ist ungünstig, 
sie mit dem Controller an die selbe Spannungsversorgung anzuschliessen. 
Das kann zu Störungen des Controllers führen ...

von Daniel B. (dannyboy1994)


Lesenswert?

es sind kleine 6V motoren die max ich glaub 300mA oder so ziehen. Die 
motoren sind über einen transistor angeschlossen der einen pol des 
motors auf masse zieht wenn er saft kriegt. Die sache ist die. Modus 14 
schön und gut aber ich werd auf dem datenblatt nicht schlau welche bits 
für modus 14 gesetzt sein müssen..... das nervt mich grad richtig an. 
Ich meine wer soll aus:

 (WGM13:0 = 5, 6, 7, 14, or 15)


schlau werden?
heisst das das ich WGM 13 setzen muss und die anderen frei lassen muss? 
ich check einfach nciht wie ich den Fast PWM modus 14 einstelle.

zur sache mit 16 bit. die motoren sollen dann sehr weit gedrosselt 
werden können. des weiteren liegt schon meine schaltung die ich oben 
gepostet habe vor. Da habe ich die motoren an die ports des 16 bit 
timers gehängt.

mein 2tes problem wurde noch nicht behandelt. Er setzt mir beim 
erreichen von OCR1A bzw B   nicht den port B sondern den PinB. Was hat 
es damit auf sich?

von spess53 (Gast)


Lesenswert?

Hi

WGM13:0 = 14 bedeutet WGM13,12,11,10 = 1110.

MfG Spess

von Spezi (Gast)


Lesenswert?

Hallo,

> Ich meine wer soll aus:
> (WGM13:0 = 5, 6, 7, 14, or 15)
> schlau werden?

In meinem Mega8-Datenblatt (von 10/2004; 305 Seiten) gibt es eine schöne 
Tabelle, wo alle Timer-Modi inkl. der zugehörigen WGM-Bits detailliert 
aufgelistet sind (Seite 97). Wo ist also das Problem?

> Er setzt mir beim erreichen von OCR1A bzw B nicht den port B sondern den
> PinB.

???
Es werden doch durch die Fast PWM die Controller-Pins PB1 (OC1A) und PB2 
(OC1B) verwendet. Mit PortB oder PinB hat das nichts zu tun.
Oder willst du den Zustand der Pins im Programm einlesen? Dann ist 
natürlich das PinB-Register angesagt (hier steht immer der "echte" 
Zustand des Pins: 0 oder 1).

von Daniel B. (dannyboy1994)


Lesenswert?

nein. ICh lasse den timer zählen. Habe auch nochmal überprüft hae fast 
PPWm mode 14 eingestellt. Dann leuft er und er ist so eingestellt das er 
mir beim erreichen des OCR1A(B) wertes den jeweiligen port auf ausgang 
schaltet. Doch wenn ich im AVR studio nachgucke schaltet er mir nicht 
portb auf 1 sondern pinb auf 1 und lässt portb auf 0. ICh weis ja nciht 
ob ich deine aussage richtig verstehe:


Dann ist
natürlich das PinB-Register angesagt (hier steht immer der "echte"
Zustand des Pins: 0 oder 1).

heisst das er schaltet mir richtig die 2 pins am controller auf +5V? 
auch wenn er im AVR studio bei PIN b1 ne 1 drin stehen hat?

von Karl H. (kbuchegg)


Lesenswert?

Daniel B. schrieb:
> nein. ICh lasse den timer zählen. Habe auch nochmal überprüft hae fast
> PPWm mode 14 eingestellt. Dann leuft er und er ist so eingestellt das er
> mir beim erreichen des OCR1A(B) wertes den jeweiligen port auf ausgang
> schaltet.

Ähm.
Eine PWM stell einen Port-Pin, der auf Ausgang geschaltet ist, zwischen 
1 und 0 um und nicht den Modus zwischen Eingang und Ausgang um.

> Doch wenn ich im AVR studio nachgucke schaltet er mir nicht
> portb auf 1 sondern pinb auf 1 und lässt portb auf 0.

Sei ein wenig vorsichtig. Der AVR-Simulator hat gerade bei den PWM-Modi 
so seine Problemchen. Dem daerf man nicht alles glauben.

Wenn du in deinem Programm diese vermaledeite Binärschirebweise bei der 
Konfiguration auf vernünftig umgestellt hast und dein Programm, so wie 
es jetzt ist, noch einmal postest, dann wird sich schon jemand finden, 
der da noch einmal drüberschaut.

von Daniel B. (dannyboy1994)


Lesenswert?

1
.include"m8def.inc"
2
// r16 und r17 sind die register für die PWM der motoren
3
//r18 aufwärts können so verwendet werden
4
5
// MEGA MIT 8 MHZ
6
7
initiallisierung:
8
timer_und_stack:
9
ldi r18, HIGH(RAMEND)     ; Stackpointer initialisieren
10
out SPH, r18
11
ldi r18, LOW(RAMEND)
12
out SPL, r18
13
14
timer:
15
ldi r16, 0b00000110
16
out ddrb, r16
17
18
ldi      r16, 1<<COM1A1 |1<<COM1B1 |1<<WGM11  //modus festlegen
19
out      TCCR1A, r16
20
ldi r16, 1<<WGM13|1<<WGM12|1<<CS10    //timer prescaler festlegen   0b00000011= 64  0b00000111=1024
21
out TCCR1B, r16        // 1 im realenmodus zum verwenden. 64er prescaler nur zum testen im AVR studio
22
23
ldi r16, 0xFF
24
out ICR1H, r16        //soweit zählt der timer
25
out ICR1L, r16
26
27
ldi r16, 0xFF
28
ldi r17, 0x3F
29
30
out OCR1AH, r17        // wenn der timer diesen wert erreicht schaltet er 
31
              // den ausgangspin ab
32
out OCR1AL, r16
33
out OCR1BH, r17
34
out OCR1BL, r16
35
          //             ____________________
36
          //            |           |
37
          //0x3fff-0xffff |0x0000-0x3fff     |    usw.
38
          //______________|           |______
39
40
41
ADC_initiallisierung:
42
ldi r18, 1<<ADEN|1<<ADSC|1<<ADFR|1<<ADPS2|1<<ADPS1|1<<ADPS0
43
out ADCSRA, r18
44
ldi r18, 0b00100000
45
out ADMUX, r18
46
ldi r18, 0
47
rjmp main
48
49
normalzustand:
50
sbi ddrb, 2
51
52
53
main:
54
in r18, ADCH
55
ldi r20, 130 //~2,52 V oder weniger   //laut herr grzesina. Spannung nnimmt ab wenn die helligkeit zunimmt. Also:.
56
57
cp r18, r20
58
brlt r20match
59
rjmp main
60
61
62
r20match: // einer bleit stehen in dem sein DDRB eintrag auf eingang gelegt wird
63
64
cbi ddrb, 2
65
66
67
rjmp warten_und_lencken
68
69
70
71
72
73
74
warten_und_lencken:
75
ldi r30, 255
76
ldi r31, 255
77
78
ldi r29, 255
79
ldi r28, 255
80
ldi r27, 255
81
ldi r26, 255
82
a1:
83
nop
84
nop
85
nop
86
nop
87
nop
88
nop
89
nop
90
nop
91
dec r30
92
brne a1
93
dec r31
94
brne a1
95
dec r29
96
brne a1
97
dec r28
98
brne a1
99
dec r27
100
brne a1
101
dec r26
102
brne a1
103
rjmp normalzustand





so das programm in der gewünschten schreibweise. Ja ich weis das er es 
zwischen 1 und 0 umstellt. Aber wie du schon sagst einen PORT pin. Das 
währe im AVR studio dann der PORTB, doch er stellt den PINB um.

von Karl H. (kbuchegg)


Lesenswert?

Daniel B. schrieb:

> so das programm in der gewünschten schreibweise. Ja ich weis das er es
> zwischen 1 und 0 umstellt. Aber wie du schon sagst einen PORT pin. Das
> währe im AVR studio dann der PORTB, doch er stellt den PINB um.

Dürfte ein Simulatorfehler sein.

von Daniel B. (dannyboy1994)


Lesenswert?

und was hat es mit dem problem des umkehrens aufsich? ist das auch ein 
simulatorfehler?

von Karl H. (kbuchegg)


Lesenswert?

Daniel B. schrieb:
> und was hat es mit dem problem des umkehrens aufsich? ist das auch ein
> simulatorfehler?

Ehe du jetzt weiter machst, dreh erst mal deine Initialisierung um:
Der Timer, und damit auch id PWM läuft los, sobald ein Vorteiler 
zugewiesen ist. D.h. du möchtest die komlpette Initialisierung machen, 
ehe du dem Timer einen Vorteiler zuweist.
Das kann insofern relevant sein, als die einzelnen PWM Modi eine 
Änderung erst dann tatsächlich durchführen, wenn der Timer seinen TOP 
Wert erreicht hat. D.h. aber auch, machst du es anders rum, würde ich 
meine Hand nicht dafür ins Feuer legen, dass bereits im ersten PWM 
Zyklus alles richtig läuft. Und ich denke nicht, dass du im Simulator 
bis zu einem Timerstand von 0xFFFF per Hand durchgesteppt bist.

von Daniel B. (dannyboy1994)


Lesenswert?

Also ich hab die initialiesierung umgedreht:

ldi r16, 0xFF
ldi r17, 0x3F

out OCR1AH, r17        // wenn der timer diesen wert erreicht schaltet 
er
              // den ausgangspin ab
out OCR1AL, r16
out OCR1BH, r17
out OCR1BL, r16
ldi r16, 0xFF
out ICR1H, r16        //soweit zählt der timer
out ICR1L, r16


ldi      r16, 1<<COM1A1 |1<<COM1B1 |1<<WGM11  //modus festlegen
out      TCCR1A, r16
ldi r16, 1<<WGM13|1<<WGM12|1<<CS10    //timer prescaler festlegen 
0b00000011= 64  0b00000111=1024
out TCCR1B, r16        // 1 im realenmodus zum verwenden. 64er prescaler 
nur zum testen im AVR studio






und er dreht immer noch um bei oxo1FF
EWs nervt langsam tierisch. iCH hör auf für heute nach 10,5 stunden 
reichts mir. ICh frag mich warum das kackteil umdreht. Davon steht 
nichts im datenblatt. Davon steht nicht auch nur irgendwo. Er soll in 
diesm modus angeblich weiter laufen bis ICR1 und dann bei 0 neu anfange, 
aber statt desen dreht er bei 0x01ff um..

von spess53 (Gast)


Lesenswert?

Hi

>Dürfte ein Simulatorfehler sein.

Nein. Im Simulator wird der Zustand des Portregisters dargestellt. Das 
OCR-Signal läuft aber nicht über das Portregister sondern über 'Port 
Value
Override Value'. Siehe Datenblatt 'Alternate Port Functions'.

Wenn ich nichts übersehen habe, sollte die PWM laufen.

>in r18, ADCH
>ldi r20, 130
>cp r18, r20
>brlt r20match

Am Verständnis des ADC musst du aber noch arbeiten.

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

>und er dreht immer noch um bei oxo1FF

Habe ich auch festgestellt. Das dürfte aber unter Simulatorfehler zu 
buchen sein. Wenn TCCR1A und TCCR1B noch nicht initialisiert sind, tritt 
es nicht auf.

MfG Spess

von Daniel B. (dannyboy1994)


Lesenswert?

warum im verständniss des ADC? Ja ich weis es währe einfacher wenn ich 
den Analog Conperator nehmen würde.....aber das währe dann in mienem 
layout ziemlich eng geworden => ADC  = anderer Pin mehr platz. Das war 
mein gedanke. und wenn ich mein layout so ansehe währe das verdammt eng 
geworden.

Das ist zwar eigentlich missbrauch, dar er ja eigentlich zum messen von 
spannungen da ist, aber das war mir egal ^^  ^^


dancke für eure hilfe

meinst du laufen auch mit diesem UMkehr fehler? oder hast du den noch 
ausm vor gelassen?

von Daniel B. (dannyboy1994)


Lesenswert?

hab hier etwas interessantes gefunden:

Fehler:


Mode  Timer/CounterMode                Fehlerbeschreibung
      of Operation
0     Normal                           kein Fehler
1     PWM, Phase Correct, 8-bit        kein Fehler
2     PWM, Phase Correct, 9-bit        kein Fehler
3     PWM, Phase Correct, 10-bit       kein Fehler
4     CTC                              kein Fehler
5     Fast PWM, 8-bit                  arbeitet wie Mode 1
6     Fast PWM, 9-bit                  arbeitet wie Mode 2
7     Fast PWM, 10-bit                 arbeitet wie Mode 3
8     PWM, Phase and Frequency Correct ignoriert ICR1, arbeitet wie Mode 
0
9     PWM, Phase and Frequency Correct ignoriert OCR1A, arbeitet wie 
Mode 1
10    PWM, Phase Correct               ignoriert ICR1, arbeitet wie Mode 
2
11    PWM, Phase Correct               ignoriert OCR1A, arbeitet wie 
Mode 3
12    CTC                              ignoriert ICR1, arbeitet wie Mode 
4(OCR1A)
13    (Reserved)
14    Fast PWM                         ignoriert OCR1A, arbeitet wie 
Mode 2
15    Fast PWM                         ignoriert ICR1, arbeitet wie Mode 
3


dar ich modus 14 verwende, werde ich zwar nicht 100% daraus schlau dar 
ich bei mir im modus 14 mehr die fehler beschreibung von 15 als 
zutreffend empfinde.

Naja. Man sollte von freeware leide rnicht zuviel verlangen -.-


lg
danny

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.