Zitat Zitat von hegewald Beitrag anzeigen
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