
Zitat von
hegewald
Hallo Atmelfreaks,
beschäftige mich mit der Wahnsinnsmaterie PWM mit Timer1
Zu Beginn hatte ich mich mit CTC-Betrieb beschäftigt und es läuft auch.
Jetzt bin ich beim PWM-fast Betrieb und PWM Phasenkorrekt Betrieb angekommen,
und es ist ein Wahnsinn, was sich dahinter verbirgt.
Hallo Rolf,
ich bin nochmal von Deinem ersten Post ausgegangen und habe Dein Programm meinen Gedankengängen angepaßt. Nicht getestet aber nach bestem Wissen und Gewissen gearbeitet 
Code:
; Projekt: Mega8-PWM Datum: 03.11.2013
; Datei: mega8-FASTPWM01.asm
; ATmega8 Timer1 FastPWM-Betrieb Kanäle A und B
; Projekt: Mega8-PWM Datum: 03.11.2013; Datei: mega8-FASTPWM01.asm
; ATmega8 Timer1 FastPWM-Betrieb Kanäle A und B
; Port B: Ausgang Kanal A:OC1A (PB1-Pin15) Kanal B:OC1B (PB2-Pin16)
; Konfiguration: interner Oszillator 1 MHz, externes RESET-Signal
.INCLUDE "m8def.inc" ; Deklarationen für Mega8
.EQU takt = 1000000 ; Systemtakt 1 MHz intern
.DEF akku = r16
.DEF temp17 = r17
.CSEG ; Programm-Flash
rjmp start ; Reset-Einsprung
.ORG $13 ; Interrupt-Einsprünge übergehen
start:
ldi akku, LOW(RAMEND) ; Stapel anlegen
out SPL, akku ;
ldi akku, HIGH(RAMEND)
out SPH, akku
ldi akku, (1<<PB1) | (1<<PB2)
out DDRB, akku
;.equ WertH = 100 ; Konstante für OCR1AH u. OCR1BH (r16)
.equ WertL = 127 ; Konstante für OCR1AL u. OCR1BL (r17)
; Timer1 programmieren: WGM10=1<<<PWM8Bit phasenrichtig (TOPP=00FF)
; KanalA (COM1Ax) zu PB1 und KanalB (COM1Bx) zu PB2
; Set OC1A and OC1B when upcounting, clear when downcounting. COM1 bits according table 38.
ldi akku, (1<<COM1A1) |(1<<COM1A0)| (1<<COM1B1) | (1<<COM1B0)| (1<<WGM10)
out TCCR1A, akku ; Steuerregister A Timer1
clr akku
ldi akku, (1<<CS10)| (1<<CS12) ;Prescale = 1024 (PWM frequency ~ 2Hz)
out TCCR1B, akku ; Timer1 Steuerregister B
; setting of high byte register not needed in 8 bit Timer1 operation
ldi temp17, WertL ; r17 auf 127
out OCR1AL, temp17 ; Kanal A = 127 (WertL)
out OCR1BL, temp17 ; Kanal B = 127 (WertL)
loop:
rjmp loop
.EXIT
1. Die Ausdrücke, die eine 0 nach links verschieben rausgenommen - hatten sowieso keinen Effekt, löschten auch kein Bit, wenn eins vorhanden gewesen wäre!
2. 8Bit Phase Correct Modus des Timer1 belassen. (Mode 1 laut Table 39 im Datenblatt)
3. Die COMA und COMB Bits nach der Table 38 gesetzt.
4. Prescaler auf 1024 gesetzt, damit man die LEDs auch blinken sehen kann. Mit Prescaler 1 wäre die Frequenz so hoch, daß man nur ein Leuchten sehen würde.
5. Setzten der OCR1xL Register mit einem Wert (127), der etwa 50% Duty Cycle der PWM erzeugt. OCR1xH sind durch Einschaltreset des µC auf 0 und brauchen für den 8 Bit Mode des Timers auch nicht gesetzt werden.
6. Setzen der OCRx nicht mehr in der Loop.
Hoffe hab mich nirgends verrechnet oder vertan.
Zu Deinem letzten Post: Ich hatte doch nirgends vorgeschlagen WGM12 und WGM10 auf eins zu setzten?
Würde vorschlagen bei Deinem ursprünglichen Programm zu bleiben und das zum Laufen bringen. Danach kann man Veränderungen mit SBI etc einbringen oder die beiden LEDs unterschiedlich blinken lassen oder auf 16 Bit Timer Modus umschalten. Erst sollte aber, wie gesagt, Dein erstes Programm laufen.
Frag ruhig nach, warum ich was im Programm geändert habe. Ich kann es nicht Testen und es könnten Fehler drin sein.
Gruß
Searcher
Lesezeichen