; ; DDS generator based on ; ; Jesper Hansen's .miniDDS ( 2000 ) ; ; and a thread at http://www.mikrocontroller.net/topic/244609#new ; ; thanks to Guest / Ulrich's brilliant ideas ; ; Description ; ; four times better resolution on phase ; four times better resolution on frequency ; almost doubles the resolution on voltage ( true 8 Bit DAC now ) ; ; compared to Jesper Hansen's design ; ; Author = Werner Braun ; Target = ATmega8 ; Date = 2012-01-26 ; ; ; PD0..7 = D/A Data out ; ; ; Output frequency (using 26 bit accumulator) : ; ; f = deltaPhase * fClock/2^26 ; ; fClock is LDS this case the CPU clock divided by the ; number of cycles to output the data ( 9 cycles ) ; ; f = r24/r25/r26 * (14745600/9)/67108864 ; .include "m8def.inc" ; ; TWI Slave Receiver Codes .equ TW_SR_SLA_ACK = 0x60; x60 01100000 (SLA+W received and ACK returned) .equ TW_SR_ARB_LOST_SLA_ACK = 0x68; x68 01101000 (Arbitration lost SLA+R/W as MASTER; SLA+W received; ACK returned .equ TW_SR_GCALL_ACK = 0x70; x70 01110000 (General Call address received; ACK returned .equ TW_SR_ARB_LOST_GCALL_ACK =0x78; x78 01111000 (Arbitration lost SLA+R/W as MASTER;General Call address received; ACK returned .equ TW_SR_DATA_ACK = 0x80; x80 10000000 (prev. adressed (SLA+W) data received; ACK returned .equ TW_SR_DATA_NACK = 0x88; x88 10001000 (prev. adressed (SLA+W) data received; ACK NOT returned .equ TW_SR_GCALL_DATA_ACK = 0x90; x90 10010000 (prev. adressed (General Call) data received; ACK returned .equ TW_SR_GCALL_DATA_NACK = 0x98; x98 10011000 (prev. adressed (General Call) data received; ACK NOT returned .equ TW_SR_STOP = 0xA0; xA0 10100000 (STOP received, or repeated START condition) ; TWI Slave Transmitter Codes .equ TW_ST_SLA_ACK = 0xA8; xA8 10101000 (SLA+R received; ACK returned) .equ TW_ST_ARB_LOST_SLA_ACK = 0xB0; xB0 10110000 (Arbitration lost SLA+R/W as MASTER, ACK returned) .equ TW_ST_DATA_ACK = 0xB8; xB8 10111000 (TWDR was tranfered; ACK received .equ TW_ST_DATA_NACK = 0xC0; xC0 11000000 (TWDR was tranfered; ACK NOT received .equ TW_ST_LAST_DATA = 0xC8; xC8 11001000 (last data byte LDS TWDR was tranfered (TWEA = "0"); Ack received .equ TW_NO_INFO = 0xF8; xF8 11111000 (no relevant state; TWINT = "0" no TWDR activity .equ TW_BUS_ERROR = 0x00; x00 00000000 (Bus-Error invalid START or STOP condition; no TWDR activity ; TWI SLAVE configuration .equ TWI_SLAVE_ADRESSE = 2 ; own SLAVE adress 1...127 .equ TWI_GENERAL_CALL_enable = 0 ; 1=Generral Call enabled / 0=disabled ; REGISTER .def Mode = r19 .def NUMBER = r18 .def ADRESS = r17 .def TEMP = r16 .def DATA = r15 .def TEMP_SREG = r14 .cseg ; Start of Code-Segment .org 0 rjmp RESET ; Reset Handler .org TWIaddr rjmp TWSI ; Two-wire Serial Interface Handler .org INT_VECTORS_SIZE RESET: ;****************************************************************************** ; code ;****************************************************************************** ldi r16,low(RAMEND) out SPL, r16 ldi r16, high(RAMEND) out SPH,r16 ; setup stack pointer clr r16 out PORTD,r16 ; clear all PORTD bits ser r16 ; out DDRD,r16 ; set all PORTD bits as output ldi r16,128 ; idle is 128 , 2.5 Volt out PORTD,r16 ; preload DAC ; TWI INITIALISIERUNG rcall TWI_INI ; start values clr DATA clr ADRESS ; set sinewave output as default ldi Mode,high(2*SineTable) ; setup adder registers ldi r24,85 ; some Value for testing ldi r25,20 ldi r26,20 ; release all Interrupts sei ; global enable interrupts ; main loop ; ; r28,r29,r30 is the phase accumulator ; r24,r25,r26 is the adder value determining frequency ; ; add value to accumulator ; load byte from current table in FLASH ; output byte to port ; repeat ; cycl. Sineloop: lpm r0,z ; 3 out PORTD,r0 ; 1 update add r28,r24 ; 1 adc r29,r25 ; 1 adc r30,r26 ; 1 adc r31,r27 ; 1 cbr r31,4 ; 1 reset to tables's orgin lpm r0,z ; 3 out PORTD,r0 ; 1 update add r28,r24 ; 1 adc r29,r25 ; 1 adc r30,r26 ; 1 adc r31,r27 ; 1 lpm r0,z ; 3 add r28,r24 ; 1 out PORTD,r0 ; 1 update adc r29,r25 ; 1 adc r30,r26 ; 1 adc r31,r27 ; 1 cbr r31,4 ; 1 reset to tables's orgin lpm r0,z ; 3 add r28,r24 ; 1 out PORTD,r0 ; 1 update adc r29,r25 ; 1 adc r30,r26 ; 1 adc r31,r27 ; 1 rjmp SineLoop ; 2 => 36 / 4 = 9 cycles UpDateMode: ret ;****************************************************************************** ; data tables ;****************************************************************************** ; force table to begin at 256 byte boundary .org 0x800 SineTable: .db 128,128,129,130,131,131,132,133,134,135,135,136,137,138,138,139 .db 140,141,142,142,143,144,145,146,146,147,148,149,149,150,151,152 .db 152,153,154,155,156,156,157,158,159,159,160,161,162,162,163,164 .db 165,165,166,167,168,168,169,170,171,171,172,173,174,174,175,176 .db 176,177,178,179,179,180,181,182,182,183,184,184,185,186,186,187 .db 188,189,189,190,191,191,192,193,193,194,195,195,196,197,197,198 .db 199,199,200,201,201,202,202,203,204,204,205,206,206,207,207,208 .db 209,209,210,211,211,212,212,213,213,214,215,215,216,216,217,217 .db 218,219,219,220,220,221,221,222,222,223,223,224,224,225,225,226 .db 226,227,227,228,228,229,229,230,230,231,231,232,232,233,233,233 .db 234,234,235,235,236,236,236,237,237,238,238,238,239,239,240,240 .db 240,241,241,241,242,242,243,243,243,244,244,244,245,245,245,245 .db 246,246,246,247,247,247,247,248,248,248,249,249,249,249,250,250 .db 250,250,250,251,251,251,251,251,252,252,252,252,252,253,253,253 .db 253,253,253,253,254,254,254,254,254,254,254,254,255,255,255,255 .db 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 .db 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 .db 255,255,255,255,255,254,254,254,254,254,254,254,254,253,253,253 .db 253,253,253,253,252,252,252,252,252,251,251,251,251,251,250,250 .db 250,250,250,249,249,249,249,248,248,248,247,247,247,247,246,246 .db 246,245,245,245,245,244,244,244,243,243,243,242,242,241,241,241 .db 240,240,240,239,239,238,238,238,237,237,236,236,236,235,235,234 .db 234,233,233,233,232,232,231,231,230,230,229,229,228,228,227,227 .db 226,226,225,225,224,224,223,223,222,222,221,221,220,220,219,219 .db 218,217,217,216,216,215,215,214,213,213,212,212,211,211,210,209 .db 209,208,207,207,206,206,205,204,204,203,202,202,201,201,200,199 .db 199,198,197,197,196,195,195,194,193,193,192,191,191,190,189,189 .db 188,187,186,186,185,184,184,183,182,182,181,180,179,179,178,177 .db 176,176,175,174,174,173,172,171,171,170,169,168,168,167,166,165 .db 165,164,163,162,162,161,160,159,159,158,157,156,156,155,154,153 .db 152,152,151,150,149,149,148,147,146,146,145,144,143,142,142,141 .db 140,139,138,138,137,136,135,135,134,133,132,131,131,130,129,128 .db 128,127,126,125,124,124,123,122,121,120,120,119,118,117,117,116 .db 115,114,113,113,112,111,110,109,109,108,107,106,106,105,104,103 .db 103,102,101,100,99,99,98,97,96,96,95,94,93,93,92,91 .db 90,90,89,88,87,87,86,85,84,84,83,82,81,81,80,79 .db 79,78,77,76,76,75,74,73,73,72,71,71,70,69,69,68 .db 67,66,66,65,64,64,63,62,62,61,60,60,59,58,58,57 .db 56,56,55,54,54,53,53,52,51,51,50,49,49,48,48,47 .db 46,46,45,44,44,43,43,42,42,41,40,40,39,39,38,38 .db 37,36,36,35,35,34,34,33,33,32,32,31,31,30,30,29 .db 29,28,28,27,27,26,26,25,25,24,24,23,23,22,22,22 .db 21,21,20,20,19,19,19,18,18,17,17,17,16,16,15,15 .db 15,14,14,14,13,13,12,12,12,11,11,11,10,10,10,10 .db 9,9,9,8,8,8,8,7,7,7,6,6,6,6,5,5 .db 5,5,5,4,4,4,4,4,3,3,3,3,3,2,2,2 .db 2,2,2,2,1,1,1,1,1,1,1,1,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2 .db 2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5 .db 5,5,5,6,6,6,6,7,7,7,8,8,8,8,9,9 .db 9,10,10,10,10,11,11,11,12,12,12,13,13,14,14,14 .db 15,15,15,16,16,17,17,17,18,18,19,19,19,20,20,21 .db 21,22,22,22,23,23,24,24,25,25,26,26,27,27,28,28 .db 29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36 .db 37,38,38,39,39,40,40,41,42,42,43,43,44,44,45,46 .db 46,47,48,48,49,49,50,51,51,52,53,53,54,54,55,56 .db 56,57,58,58,59,60,60,61,62,62,63,64,64,65,66,66 .db 67,68,69,69,70,71,71,72,73,73,74,75,76,76,77,78 .db 79,79,80,81,81,82,83,84,84,85,86,87,87,88,89,90 .db 90,91,92,93,93,94,95,96,96,97,98,99,99,100,101,102 .db 103,103,104,105,106,106,107,108,109,109,110,111,112,113,113,114 .db 115,116,117,117,118,119,120,120,121,122,123,124,124,125,126,127 .db 128,128,129,130,131,131,132,133,134,135,135,136,137,138,138,139 .db 140,141,142,142,143,144,145,146,146,147,148,149,149,150,151,152 .db 152,153,154,155,156,156,157,158,159,159,160,161,162,162,163,164 .db 165,165,166,167,168,168,169,170,171,171,172,173,174,174,175,176 .db 176,177,178,179,179,180,181,182,182,183,184,184,185,186,186,187 .db 188,189,189,190,191,191,192,193,193,194,195,195,196,197,197,198 .db 199,199,200,201,201,202,202,203,204,204,205,206,206,207,207,208 .db 209,209,210,211,211,212,212,213,213,214,215,215,216,216,217,217 .db 218,219,219,220,220,221,221,222,222,223,223,224,224,225,225,226 .db 226,227,227,228,228,229,229,230,230,231,231,232,232,233,233,233 .db 234,234,235,235,236,236,236,237,237,238,238,238,239,239,240,240 .db 240,241,241,241,242,242,243,243,243,244,244,244,245,245,245,245 .db 246,246,246,247,247,247,247,248,248,248,249,249,249,249,250,250 .db 250,250,250,251,251,251,251,251,252,252,252,252,252,253,253,253 .db 253,253,253,253,254,254,254,254,254,254,254,254,255,255,255,255 .db 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 .db 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 .db 255,255,255,255,255,254,254,254,254,254,254,254,254,253,253,253 .db 253,253,253,253,252,252,252,252,252,251,251,251,251,251,250,250 .db 250,250,250,249,249,249,249,248,248,248,247,247,247,247,246,246 .db 246,245,245,245,245,244,244,244,243,243,243,242,242,241,241,241 .db 240,240,240,239,239,238,238,238,237,237,236,236,236,235,235,234 .db 234,233,233,233,232,232,231,231,230,230,229,229,228,228,227,227 .db 226,226,225,225,224,224,223,223,222,222,221,221,220,220,219,219 .db 218,217,217,216,216,215,215,214,213,213,212,212,211,211,210,209 .db 209,208,207,207,206,206,205,204,204,203,202,202,201,201,200,199 .db 199,198,197,197,196,195,195,194,193,193,192,191,191,190,189,189 .db 188,187,186,186,185,184,184,183,182,182,181,180,179,179,178,177 .db 176,176,175,174,174,173,172,171,171,170,169,168,168,167,166,165 .db 165,164,163,162,162,161,160,159,159,158,157,156,156,155,154,153 .db 152,152,151,150,149,149,148,147,146,146,145,144,143,142,142,141 .db 140,139,138,138,137,136,135,135,134,133,132,131,131,130,129,128 .db 128,127,126,125,124,124,123,122,121,120,120,119,118,117,117,116 .db 115,114,113,113,112,111,110,109,109,108,107,106,106,105,104,103 ; TWI INTERRUPPT-Routine TWSI: in TEMP_SREG,SREG ; save SREG in temp, TWSR ; get TWI status andi temp, 0xF8 ; mask Bit0...2 (prescaler und reserve-bit) out PORTB,temp sbi portB,0 cpi temp, TW_SR_SLA_ACK ; x60 breq TWSI_TW_SR_SLA_ACK cpi temp, TW_SR_ARB_LOST_SLA_ACK ; x68 breq TWSI_END cpi temp, TW_SR_GCALL_ACK ; x70 breq TWSI_END cpi temp, TW_SR_ARB_LOST_GCALL_ACK ; x78 breq TWSI_END cpi temp, TW_SR_DATA_ACK ; x80 breq TWSI_TW_SR_DATA_ACK cpi temp, TW_SR_DATA_NACK ; x88 breq TWSI_END cpi temp, TW_SR_GCALL_DATA_ACK ; x90 breq TWSI_END cpi temp, TW_SR_GCALL_DATA_NACK ; x98 breq TWSI_END cpi temp, TW_SR_STOP ; xA0 breq TWSI_END ; cpi temp, TW_ST_SLA_ACK ; 0xA8 breq TWSI_TW_ST_SLA_ACK cpi temp, TW_ST_ARB_LOST_SLA_ACK ; 0xB0 breq TWSI_END cpi temp, TW_ST_DATA_ACK ; 0xB8 breq TWSI_TW_ST_DATA_ACK cpi temp, TW_ST_DATA_NACK ; 0xC0 breq TWSI_TW_ST_DATA_NACK cpi temp, TW_ST_LAST_DATA ; 0xC8 breq TWSI_END cpi temp, TW_NO_INFO ; 0xF8 breq TWSI_END rcall TWI_ERROR ; 0x00 TWSI_END: ; clear TWINT-Flag ldi temp, 1<