Hallo,

ich möchte eine Servosteuerung bauen und verwende gerade den ATmega8515L. Da ich eine recht kleine Schritte benötige, möchte ich den 16-Bit Timer im Fast-PWM-Modus betreiben.

Nun das Problem:
Laut Datenblatt stelle ich nun alles so ein, dass ich das ICR-Register als TOP-Wert nehme und das OCR1A-Register als Vergleichswert. Lasse ich das ganze dann im Simulator des AVR-Studios laufen, zählt das TCNT-Register erst hoch bis 0x01FF, dann aber wieder runter auf 0. Sieht nach Phase-Correct-Mode aus, wobei aber nicht einmal der TOP-Wert stimmt. Hinzu kommt noch, dass wenn ich den Vergleichswert setze (hier bei mir auf 1500 = 0x05dc), er jedesmal nach dem initialisieren der Steuerregister (TCCR) auf 0x01dc gesetzt wird.

Den Quellcode hab ich mal mit beigefügt, damit ihr seht, was ich da getippt habe und es besser nachvollziehen könnt.

Mache ich da was falsch oder kann ich das Datenblatt einfach nicht richtig interpretieren? Beim 8-Bit Timer mit PWM geht alles super, brauche aber eben den mit 16-Bit.
Würde mich freuen wenn ihr mir weiterhelfen könnt.

Lg gun22

Code:
.include "m8515def.inc"

; Konstanten
.equ		pwm_top	       = 20000		    ; für ICR1-Register
.equ		ps_min		 = 1000		      ; Minimum für PWM-Signale
.equ		ps_max		= 2000		     ; Maximum für PWM-Signale
.equ		pwm_ctrl1	= 0b11000010	; Fast-PWM-Mode; TOP = ICR1;
.equ		pwm_ctrl2	= 0b00011000	; Takt = ClK/1

; Variablen
.def		temp		= r16
.def		temp_s	       = r17			; temp für Status

; Makros
.macro	     out_16
		 ldi		 temp,high(@2)
		 out		@0,temp
		 ldi		 temp,low(@2)
		 out		@1,temp
.endmacro


.CSEG
.ORG	      0x00						; Startadresse 0x00
		 rjmp		reset				  ; zur reset-Routine


;********************************************************************
; pwm_init:
; Die Register von Timer1 werden so gesetzt, dass er im PWM-Modus
; läuft. Zusätzlich wird PORTD als Ausgang für das Compare-Flag
; benutzt.
;********************************************************************
pwm_init:	in		temp_s,SREG	   ; SREG sichern und
		     cli					 ; globale Interrupts sperren

		     ldi	     temp,0b00100000  ; Pin5 an PortD als
		     out	    DDRD,temp	        ; Ausgang für Compare-Flag

		     ldi	     temp,pwm_ctrl1	; Steuerbefehle für den
		     out	    TCCR1A,temp	      ; Timer schreiben
		     ldi	     temp,pwm_ctrl2
		     out	    TCCR1B,temp

		     out_16 ICR1H,ICR1L,pwm_top	; Top-Wert schreiben
								  ; Signal-Wert schreiben
		     out_16 OCR1AH,OCR1AL,ps_min+((ps_max-ps_min)/2)

		     in		      temp,TCCR1B
		     ori	      temp,0b00000001
		     out	     TCCR1B,temp

		     out	     SREG,temp_s	; SREG zurückschreiben
		     ret


;********************************************************************
; reset:
; Hier werden nur allgemeine Einstellungen gemacht, wie z.B. den
; Stack einrichten usw.
;********************************************************************
reset:		   ldi		     temp,high(RAMEND)
		     out	      SPH,temp
	             ldi		temp,low(RAMEND)
		     out	      SPL,temp


;********************************************************************
; main:
; Das Hauptprogramm ruft die Unterprogramme zum Initialisieren auf
; und springt dann in eine Endlosschleife.
;********************************************************************
main:		rcall	       pwm_init			; Timer initialisieren
loop:		 rjmp	       loop