PWM beim ATMega 8

Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte

Elektronik Forum Nicht eingeloggt       Einloggen       Registrieren




[Registrieren]      --     [FAQ]      --     [ Einen Link auf Ihrer Homepage zum Forum]      --     [ Themen kostenlos per RSS in ihre Homepage einbauen]      --     [Einloggen]

Suchen


Serverzeit: 05 10 2024  10:09:44      TV   VCR Aufnahme   TFT   CRT-Monitor   Netzteile   LED-FAQ   Osziloskop-Schirmbilder            


Elektronik- und Elektroforum Forum Index   >>   Microcontroller        Microcontroller : Hardware - Software - Ideen - Projekte


Autor
PWM beim ATMega 8
Suche nach: pwm (3614) atmega (404)

    







BID = 485290

RaPe

Gelegenheitsposter



Beiträge: 56
Wohnort: Radebeul
 

  


Hallo Leute,

ich möchte einen Servo mit einem Atmega8 ansteuern. Damit das Ausgangssignal so genau wie möglich ist, wollte ich die Compare Unit vom 16Bit Timer nutzen. Wenn ich das Datenblatt richtig verstanden habe, kann die Unit direkt auf ein Ausgangspin zugreifen und ich wäre nicht mehr Softwareabhängig. (Prozessor läuft mit 1MHz)

Es sollte so ablaufen:
Ich schreibe in OCR1AH / OCR1AL einen Wert. Lösche den Timer (TCNT1H / TCNT1L). Und setze den Ausgang (B1) auf „1“. Wenn der Vergleicher abgelaufen ist, soll er den Ausgang wieder auf „0“ setzen (nach 1,5ms). Nach etwa 20ms (dieser Teil des Programms ist noch nicht fertig) soll wieder alles von vorn beginnen.
Im AVR-Studio funktionert es, aber am Prozessorausgang liegt immer „0“ an!
Besser gesagt: ich habe es so geschrieben, dass es im AVR-Studio läuft!

Das die Lösung im Datenblatt liegen könnte, weiß ich! Es sind nur eine Menge Seiten und alle auf Englisch. Falls mir also jemand direkt eine Lösung vorschlagen kann, wäre das sehr hilfreich.

Mein Testprogramm:

.NOLIST
.INCLUDE "C:\m008def.inc"
.LIST

.def Temp1 = R16
.def Temp2 = R17
.def Data = R25

.cseg
.org 0x0000

Neustart:
CLR R0
CLR R1
INC R1
CLR R3
DEC R3

OUT DDRB,R3
; OUT PORTB,R0
SBI PORTB,1

LDI Temp1,HIGH(1400)
LDI Temp2,LOW(1400)
OUT OCR1AH,Temp1
OUT OCR1AL,Temp2
LDI Temp1,0b10001000
OUT TCCR1A,Temp1
OUT TCCR1B,R1

X02:
OUT TCNT1H,R0
OUT TCNT1L,R0
SBI PINB,1

LDI Data,250
X01:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DEC Data
BRNE X01
RJMP X02

BID = 485294

Morgoth

Schreibmaschine



Beiträge: 2930
Wohnort: Rockenhausen (Pfalz)

 

  

Wenn du jetzt noch das programm kommentierst, sodass wir wissen, was du denkst dass deine Befehle machen, dann ist dir einfacher zu helfen...

edit:
Und du musst die PWM zuerst aktivieren, bevor du das Compare-Register beschreiben kannst.
also zuerst TCCR1A und TCCR1B schreiben, und dann OCR1AH und OCR1AL.
OCR1AL muss als letztes geschrieben werden, da nach diesem Schreibvorgang die PWM aktualisiert wird (aber das hast du ja richtig)

edit2:
Und was willst du mit "SBI PinB, 1" bewirken?
PinB ist ein "ReadOnly"-Register... "SBI PortB, 1" macht wohl eher was du willst

wobei ich ohnehin nicht verstehe, was du damit bezwecken willst bei weiterhin aktivierter PWM an diesem Pin rumzumanipulieren...

_________________
Es irrt der Mensch solang er strebt


[ Diese Nachricht wurde geändert von: Morgoth am 28 Dez 2007 12:48 ]

BID = 485301

RaPe

Gelegenheitsposter



Beiträge: 56
Wohnort: Radebeul

Wie gesagt, das Programm ist so geschrieben, damit es erstmal im AVR_Studio läuft, was es auch tut!

Die mit "*" gekennzeichneten Sachen, sind wahrscheinlich sinnlos, hatte sie aber zum Ausprobieren mal eingebaut.

OUT DDRB,R3 ;---Port auf Ausgang*
; OUT PORTB,R0
SBI PORTB,1 ;---war nur für mich zur Orientierung*

LDI Temp1,HIGH(1400)
LDI Temp2,LOW(1400)
OUT OCR1AH,Temp1 ;---Vergleichsregister mit 1400 füllen (ca 1,5ms)
OUT OCR1AL,Temp2
LDI Temp1,0b10001000
OUT TCCR1A,Temp1 ;---Die Vergleichsfunktion für Ausgang aktivieren
OUT TCCR1B,R1 ;---Teilfaktor = 1

X02:
OUT TCNT1H,R0 ;---Timerstand auf 0 setzen
OUT TCNT1L,R0
SBI PINB,1 ;---nur so funktioierte es im AVR-Studio*

LDI Data,250 ;---Pause bis Timer abgelaufen, dann Neustart.
X01: ;---während dieser Pause hat der Timer im AVR-Studio nur das PinB,1 wieder auf 0 gesetzt
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DEC Data
BRNE X01
RJMP X02

BID = 485304

Morgoth

Schreibmaschine



Beiträge: 2930
Wohnort: Rockenhausen (Pfalz)

wenn du das Setzen des DataDirectionRegister für warhscheinlich unnötig hälst... dann solltest du vielleicht doch noch etwas im Datenblatt schmökern...
Ansonsten initialisier halt mal zuerst die PWM, bevor du das Vergleichsregister beschreibst, dann sollte die Mühle laufen.

_________________
Es irrt der Mensch solang er strebt

BID = 485379

RaPe

Gelegenheitsposter



Beiträge: 56
Wohnort: Radebeul


Zitat :
Morgoth hat am 28 Dez 2007 13:15 geschrieben :

wenn du das Setzen des DataDirectionRegister für warhscheinlich unnötig hälst... dann solltest du vielleicht doch noch etwas im Datenblatt schmökern...


Eh Morgoth, kannst du erstmal deine Birne einschalten, bevor du dein Maul aufreist? Ich glaub ni!

Wenn man z.B. mit dem USART arbeitet und ihn aktiviert, übernimmt er von alleine die Steuerung über das DDRD,0 & 1 Pin.
Soweit wie ich bis jetzt in die Materie vorgedrungen bin, gehe ich auch hier davon aus, dass die PWM die Ausgänge von selbst steuert und es dem Prozessor völlig egal ist, was ich in das DDRB schreibe!!! Solltest du wissen, dass es in diesem Fall anders ist, dann sag es und eiere hier nicht rum.
Also, wenn du nur hier bist, um deinen Senf dazu zu geben, anstatt Lösungen oder voranbringende Hilfe beizusteuern, dann lass es bitte.


BID = 485381

Morgoth

Schreibmaschine



Beiträge: 2930
Wohnort: Rockenhausen (Pfalz)

Thema für mich erledigt.
Ich habe dir zweimal gesagt was falsch ist an deinem Programm, darauf gehst du weiterhin nicht ein, und jetzt ist dir auch noch jeglicher Anstand verloren gegangen.

_________________
Es irrt der Mensch solang er strebt

BID = 485389

admin

Administrator



Beiträge: 5025
Wohnort: Heilbronn
Zur Homepage von admin


Zitat :
RaPe hat am 28 Dez 2007 16:46 geschrieben :

....

Eh Morgoth, kannst du erstmal deine Birne einschalten, bevor du dein Maul aufreist? Ich glaub ni!
....


@RaPe bitte nicht in solch einem Ton !

admin

BID = 485392

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

Moin,

eher allgemein:
Die PWM-Hardware kann nicht jeden beliebigen Pin, sondern nur den OC-Pin ansteuern.
Dies stellt man im Timer Control Register ein.

Wird ein anderer Pin benötigt, so muss es etwas anders gemacht werden:
Der Timer wird im CTC-Modus initialisiert, in jedem Compare Match Interrupt wird dann beispielsweise ein Pin angeknipst und im Überlauf-Interrupt wieder ausgeschaltet.

Das bedeutet für den Prozessor zwar ein kleines bischen mehr Zeit, aber die Hardware ist wesentlich anpassbarer.

Willst du die PWM automatisch laufen lassen, musst du dich also auf den OC-Pin beschränken, und dem tut es gut, wenn man ihn einmalig als Ausgang definiert, ob das jetzt andere Hardware (UART, I²C, etc.) automatisch macht oder nicht. Das steht so auch im Datenblatt.


Zitat :

The general I/O port function is overridden by the Output Compare (OC1x) from the
waveform generator if either of the COM1x1:0 bits are set. However, the OC1x pin
direction (input or output) is still controlled by the Data Direction Register (DDR) for the
port pin. The Data Direction Register bit for the OC1x pin (DDR_OC1x) must be set as
output before the OC1x value is visible on the pin.
The port override function is generally
independent of the Waveform Generation mode, but there are some exceptions. Refer
to Table 36, Table 37 and Table 38 for details.


Seite 85


Und dein Verhalten gegenüber Helfenden sollte sich bessern, sonst werde auch ich schweigen!

_________________


[ Diese Nachricht wurde geändert von: DonComi am 28 Dez 2007 17:20 ]

BID = 485398

RaPe

Gelegenheitsposter



Beiträge: 56
Wohnort: Radebeul


Zitat :
Morgoth hat am 28 Dez 2007 16:52 geschrieben :

Ich habe dir zweimal gesagt was falsch ist an deinem Programm, darauf gehst du weiterhin nicht ein, ...


Hatte ihn auch ausprobiert, obwohl ich nicht vom Erfolg überzeugt war. Was sich bei der Messung auch so rausgestellt. Es hat sich nichts am Ausgang verändert.
Der Grund warum ich an deinen Vorschlag nicht glaubte lag darin, dass es aus meiner Sicht nicht gehen kann, den PWM zu starten, bevor man die Rahmenbedingungen (wie den Vergleichswert) geladen hat, oder?
Schließlich wirst du auch vorher auf die Landkarte schauen, bevor du mit dem Auto losfährst und nicht erst losfahren und unterwegs auf die Karte sehen, um festzustellen, dass du in die falsche Richtung fährst.

Also, wenn du Vorschläge hast, dann sag sie mir bitte, aber es wäre schön, wenn die funktionieren.

BID = 485409

RaPe

Gelegenheitsposter



Beiträge: 56
Wohnort: Radebeul

[quote]
DonComi schrieb am 2007-12-28 17:11 :

Willst du die PWM automatisch laufen lassen, musst du dich also auf den OC-Pin beschränken, und dem tut es gut, wenn man ihn einmalig als Ausgang definiert, ob das jetzt andere Hardware (UART, I²C, etc.) automatisch macht oder nicht. Das steht so auch im Datenblatt.

[quote]

Das klingt auf alle Fälle schon mal einleuchtend. Glücklicherweise habe ich (obwohl ich am Anfang nicht daran glaubte) das PIN schon auf Ausgang gestellt, geht aber wie gesagt nicht, weißt du zufällig noch wie es jetzt weiter geht?

Ich möchte auch das entsprechende OC-Pin nutzen, was in diesem Fall des ATmega8 B,1 sein müsste!

BID = 485416

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

Moin,

Du musst einfach alle wichtigen Register mit dem korrekten Wert laden, mit dem Setzen der CSxn-Bits in den Kontrollregistern wird der Timer gestartet.

Nachdem alle wichtigen Register initialisiert sind, kann sich der Kontroller anderen Aufgaben widmen, da die PWM ab nun selbstständig läuft.


Welche Werte z.b. im OC-Register stehen müssen, oder welcher Vorteiler benötigt wird, musst du errechnen, indem du das als Formel darstellst.


_________________

BID = 485582

Jornbyte

Moderator



Beiträge: 7149



Code :

;**********************************

;PWM.ASM
;this is a very simple program
;which write a value from the
;register: pwm, to the pwm pin PD5.
;**********************************

.include "c:\avrtools\appnotes\8515def.inc"
;8515 an Mega 8 anpassen ! ! !
; und dein verstreutes *.inc mal in ein Verzeichnis packen
; damit ist diese Zeile -> .INCLUDE "C:m008def.inc" gemeint
; wobei auch noch ein \ fehlt


.def temp = r16
.def pwm = r17

.cseg
.org [1code];**********************************
;PWM.ASM
;this is a very simple program
;which write a value from the
;register: pwm, to the pwm pin PD5.
;**********************************

.include "c:\avrtools\appnotes\8515def.inc"
;8515 an Mega 8 anpassen ! ! !
; und dein verstreutes *.inc mal in ein Verzeichnis packen
; damit ist diese Zeile -> .INCLUDE "C:m008def.inc" gemeint
; wobei auch noch ein \ fehlt


.def temp = r16
.def pwm = r17

.cseg
.org $000
rjmp reset ;reset handle

reset: rjmp init ;start init

init: ldi temp,ramend
out spl,temp ;set spl
ldi temp,high(ramend)
out sph,temp ;set sph

ldi temp,0b11111111 ;portb = output
out ddrd,temp

out portb,temp ;switch led's off

ldi temp,0b10000001 ;init PWM... (choose 8-Bit PWM etc...)
out tccr1a,temp

ldi temp,0
out ocr1ah,temp

ldi temp,1
out ocr1al,temp

ldi temp,0b00000001
out tccr1b,temp

sei ;enable interrupts

rjmp loop

loop: ldi pwm,230 ;choose the value for pwm
out ocr1al,pwm
rjmp loop[/code1]0
rjmp reset ;reset handle

reset: rjmp init ;start init

init: ldi temp,ramend
out spl,temp ;set spl
ldi temp,high(ramend)
out sph,temp ;set sph

ldi temp,0b11111111 ;portb = output
out ddrd,temp

out portb,temp ;switch led's off

ldi temp,0b10000001 ;init PWM... (choose 8-Bit PWM etc...)
out tccr1a,temp

ldi temp,0
out ocr1ah,temp

ldi temp,1
out ocr1al,temp

ldi temp,0b00000001
out tccr1b,temp

sei ;enable interrupts

rjmp loop

loop: ldi pwm,230 ;choose the value for pwm
out ocr1al,pwm
rjmp loop





_________________
mfg Jornbyte

Es handelt sich bei dem Tipp nicht um eine Rechtsverbindliche Auskunft und
wer Tippfehler findet, kann sie behalten.

BID = 485597

Kleinspannung

Urgestein



Beiträge: 13356
Wohnort: Tal der Ahnungslosen


Ich bin zwar im Bereich µC fast völlig unbeleckt,aber die PWM von einem Mega8 habe selbst ich (mit Bascom)im zweiten Versuch hinbekommen.
Also kann das nun wirklich nicht so schwer sein...

_________________
Manche Männer bemühen sich lebenslang, das Wesen einer Frau zu verstehen. Andere befassen sich mit weniger schwierigen Dingen z.B. der Relativitätstheorie.
(Albert Einstein)

BID = 485602

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

Ja, mit Bascom...
Da braucht man nichtmal das Datenblatt aufschalgen, oder irgendwelche Registerbezeichnungen benutzen. Das macht Bascom ja alles von allein, nachdem man ihm das per Config PWM = ... mitgeteilt hat.



Zitat :

Ich schreibe in OCR1AH / OCR1AL einen Wert. Lösche den Timer (TCNT1H / TCNT1L). Und setze den Ausgang (B1) auf „1“. Wenn der Vergleicher abgelaufen ist, soll er den Ausgang wieder auf „0“ setzen (nach 1,5ms). Nach etwa 20ms (dieser Teil des Programms ist noch nicht fertig) soll wieder alles von vorn beginnen.


Wenn ich dich recht verstehe, hat also die resultierende Frequenz eine Periodendauer von ca. 21,5ms.
Damit lässt sich der erwünschte Wert für das OC-Register errechnen. Der Vergleichswert muss so gewählt werden, dass nach 1,5ms der OC-Pin wieder gelöscht wird. Der Timer zählt nun weiter, bis ein Überlauf stattfindet. Nach diesem Überlauf wird der OC-Pin wieder gelöscht.

Das Problem ist, dass die Freqnenz von ca. 47Hz nicht so einfach zu erzeugen ist. Wenn du einen Wert für das OC-Register von 0x531B nimmst, dann findet alle 21,5ms ein positiver Vergleich statt. Wenn der Timer den Wert 0x4FC erreicht, dann muss der Pin gesetzt, bei 0x531B wieder gelöscht werden.


Edit:
du lädsts eine Zahl ins TCNT1-Register, die so errechnet wurde, dass der Timer, der ab diesem Wert beginnt, zu zählen, exakt 21,5ms bis zum nächsten Überlauf braucht.
Einstellbar ist, dass der OC-Pin beim Überlauf (MAX) gesetzt wird.
Ins OC-Register kommt der Wert, der angibt, wann ein positiver Vergleich stattfindet, also exakt 1,5ms nach dem Überlauf.
Im Timerüberlaufsinterrupt muss dann erneut dieser bestimmte Wert geladen werden.

Errechnet habe ich den Wert fürs TCNT1-Register = ~(0x531B) und für das OCR-Register ~(0x04FC).
Die Tilde bedeutet davon das Komplement, also bitte vorher alle Bits invertieren .

Und eben der Wert ~(0x531B) muss in jedem Timer1-Überlaufsinterrupt neu geschrieben werden, da der Timer ab diesem Wert anfangen soll, zu zählen. Sonst bekommt man die gewünschten Periodendauern nicht hin.

P.S. Ich hoffe, mich nirgends verrechnet zu haben...



_________________


[ Diese Nachricht wurde geändert von: DonComi am 29 Dez 2007  2:25 ]

BID = 486006

RaPe

Gelegenheitsposter



Beiträge: 56
Wohnort: Radebeul

Eure Tips waren zwar nicht schlecht, passten aber nicht ganz in mein Konzept. Sie vertrugen sich nicht mit dem restlichen Programm. Aber ich habe endlich einen Weg gefunden, wie es funktioniert!

OUT TCCR1B,R0 ;Da Endlosschleife -> für Bearbeitung Timer stoppen
OUT OCR1AH,R0 ;Vergleicher auf 1 stellen (R0=0 / R1=1)
OUT OCR1AL,R1
OUT TCNT1H,R0 ;Timer auf 0 stellen
OUT TCNT1L,R0
LDI Temp1,0b11000000 ;Ausgang auf High, wenn Vergleicher = Timer
OUT TCCR1A,Temp1
OUT TCCR1B,R1 ;Timer aktivieren
… ;Berechnung der Endzeit / Inzwischen Ausgang = High
...
OUT OCR1AH,Temp1 ;Eingabe der Endzeit
OUT OCR1AL,Temp2
LDI Temp1,0b10000000 ; Ausgang auf Low, wenn Vergleicher = Timer
OUT TCCR1A,Temp1
... ;Rest des Programms / aller 20ms wird diese Schleife Wiederholt (durch einen anderen Timer) und erzeugt ein Ausgangsimpuls von ca. 1,5ms


Danke für euer Bemühen


Zurück zur Seite 1 im Unterforum          Vorheriges Thema Nächstes Thema 


Zum Ersatzteileshop


Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum       Datenschutz       Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland       

gerechnet auf die letzten 30 Tage haben wir 19 Beiträge im Durchschnitt pro Tag       heute wurden bisher 8 Beiträge verfasst
© x sparkkelsputz        Besucher : 182127542   Heute : 1345    Gestern : 5499    Online : 462        5.10.2024    10:09
3 Besucher in den letzten 60 Sekunden        alle 20.00 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
xcvb ycvb
0.0964179039001