Hallo, du must das System von DDS richtig kapieren. Deine Tabelle hat 256 Einträge (hier Sinuswerte für eine Periode). Dein Timer macht ein festes Zeitfenster (CTC mit reload). Nehmen wir an, das Zeitfenster ist 39,0625 µS (Nachladewert 144 TZ) und du gibst jedesmal denn nächsten Tabellenwert aus bedeutet das für eine Periode (Tabelle 0-255) 10 ms (256*39,0625 µs) => eine Frequenz von 100 Hz. Das Bedeutet du hast eine Grundfrequenz von 100 Hz. Du willst jetzt aber 300 Hz ausgeben. Dann mußt du bei jedem Interrupt nicht eine sondern 3 Positionen weiterspringen. Dein Additionswert ist jetzt 3. -> Tabellenposition += Additionswert im Interrupt mit Additionswert = Ausgabefrequenz / Gundfquenz Was ist aber bei 25 HZ? Wir brauchen Nachkommastellen. Additionswert = 25 / 100 = 0,25 Ein UINT16 besteht aus 16 Bit. Wir denken uns jetzt ein Komma zwischen HighByte und LowByte. Für die 3 von oben steht dann binär 0000 0011 (,) 0000 0000 und für unsere 0,25 binär 0000 0000 (,) 0100 0000 Unser Tabellenzähler ist jetzt natürlich auch UINT16, das Highbyte ist dabei unsere Tabellenposition für den Sinuswert. Wenn man das sauber weiterrechnet kommt man auf die einfache Endformel (bei 256 Werten): Additionswert = Ausgabefrequenz * Aulösung_max * Nachladewert_Timer/Fosc hier Auflösung_max = 2^16 (16Bit Zählerbreite) Je höher die Auflösung umso feiner kann abgestuft werden, ein schneller Fosc sorgt für saubere Signale bei größerer Ausgabefrequenz. Ich hoffe, so ist es verständlich erklärt. Gruß Hansl ; Sinusausgabe aus Tabelle ; Ein Sinussignal wird an Port B ausgegeben ; R2R-Netzwerk zur DA-Wandlung ; Testprogramm mit ATTINY2313 .include "tn2313def.inc" .equ F_CPU = 20000000 ; Systemtakt in Hz .equ BAUD = 9600 ; Baudrate ; Berechnungen .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!" .endif .def ssreg = r1 .def temp1 = r16 .def adwh = r17 ; Additionswert High-Byte .def adwm = r18 ; Additionswert Middle-Byte .def adwl = r19 ; Additionswert Low-Byte .def psinh = r30 ; Sinus-Zäher High-Byte ; direkt auf ZL gelegt .def psinm = r20 ; Sinus-Zäher Middle-Byte .def psinl = r21 ; Sinus-Zäher Low-Byte .cseg .org 0x0000 rjmp main .org OC1Aaddr ; Ausgaberoutine direkt auf Interruptvektor in ssreg,sreg add psinl,adwl adc psinm,adwm adc psinh,adwh lpm out PORTB,R0 out sreg,ssreg reti main: ldi temp1,RAMEND ; Stackpointer initialisieren out SPL, temp1 ; Baudrate einstellen ldi temp1, HIGH(UBRR_VAL) out UBRRH, temp1 ldi temp1, LOW(UBRR_VAL) out UBRRL, temp1 ; Frame-Format: 8 Bit ldi temp1, (3< 1,5 * Grundfrequen = 3 kHz ldi psinh,0 ; Sinuszähler auf 0 ldi psinl,0 ldi temp1,0 ; Timer1 Mode 4 CTC out TCCR1A,temp1 ldi temp1,0x09 out TCCR1B,temp1 ldi temp1,0x26 ; TOP 0x0026 -> 512 kHz bei Fosc 20 MHz out OCR1AL,temp1 ; Sinus Grundfrequenz 2 kHz ldi temp1,0x00 ; bei Additionswert 0x0100 out OCR1AH,temp1 ldi temp1,0x40 ; mit Interrupt out TIMSK,temp1 sei ; Ausgbe mit Interruptfreigabe Starten eloop: ; hier z.B. Additionswert einlesen nop rjmp eloop .org 0x0300 ; Startadresse mit Low-Byte auf 0 sinustab: ; 256 step sinewave table .db 0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae .db 0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8 .db 0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5 .db 0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff .db 0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7 .db 0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc .db 0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3 .db 0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83 .db 0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51 .db 0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27 .db 0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a .db 0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00 .db 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08 .db 0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23 .db 0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c .db 0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c