; ; DDS generator ; ; SINE and TRIANGLE based on ... ; -------------------------- ; Jesper Hansen's .miniDDS ( 2000 ) ; and a thread at http://www.mikrocontroller.net/topic/244609#new ; many thanks to guest Ulrich ; Resolution on phase, frequency and voltage is improved. ; True 8 Bit and also 9 Bit D/A versions. ; ; RECTANGLE ; --------- ; Better resolution and less Jitter. ; An optional version with adjustable duty cycle. ; ; SAWTOOTH ; -------- ; SLOW and FAST version * ; calculated on the run, no tables used, 9 and 8 Bit ; ; PRECISE version * ; same as sine and triangle (SLOW) ; ; NOISE generation based on ... ; ------------------------- ; a PDF from FELJC@LTAM ; (he/she does not mention his/her name) ; ; CONTROL ; ------- ; The Mega88 is connected via TWI. ; Loops are interrupted by TWI activities. ; It respond to all TWI addresses, address equals command number. ; Next awaiting a value ; Author = Werner Braun ; Target = ATmega8 ; Date = 2012-03-01 ; ; PC6 = RESET ; PC5 = SCL TWI ; PC4 = SDA TWI ; PC3 = out READY ; PC1 = 22pF addon ; PC0 = Glitch capacitor on / off ; PB6 = crystal 22 Mc ; PB7 = crystal 22 Mc ; PB1 = D/A Data out 8 ; PD0..7 = D/A Data out 0..7 ; ; .include "m88def.inc"a ; ; MODE Codes .equ RectangleFastMode = 11 .equ SawtoothMode_precise = 10 .equ RectangleMode_var = 9 .equ RectangleMode_fixed = 8 .equ TriangleMode_fast = 7 .equ TriangleMode_slow = 6 .equ SineMode_fast = 5 .equ SineMode_slow = 4 .equ SawtoothMode_fast = 3 .equ SawtoothMode_slow = 2 .equ NoiseMode = 1 .equ OffMode = 0 ; ; ; TWI Slave Receiver Codes .equ TW_SR_SLA_ACK = 0x60;(SLA+W received and ACK returned) .equ TW_SR_ARB_LOST_SLA_ACK = 0x68;(Arbitration lost SLA+R/W as MASTER; ; SLA+W received; ACK returned .equ TW_SR_GCALL_ACK = 0x70;(General Call address received;ACK returned .equ TW_SR_ARB_LOST_GCALL_ACK = 0x78;(Arbitration lost SLA+R/W as MASTER; ; General Call address received;ACK returned .equ TW_SR_DATA_ACK = 0x80;(prev. adressed (SLA+W) data received;ACK returned .equ TW_SR_DATA_NACK = 0x88;(prev. adressed (SLA+W) data received;ACK NOT returned .equ TW_SR_GCALL_DATA_ACK = 0x90;(prev. adressed (General Call) data received;ACK returned .equ TW_SR_GCALL_DATA_NACK = 0x98;(prev. adressed (General Call) data received;ACK NOT returned .equ TW_SR_STOP = 0xA0;(STOP received, or repeated START condition) ; TWI SLAVE configuration .equ TWI_SLAVE_ADRESSE = 0x02 ; own SLAVE ADDRESS 1...127 .equ TWI_GENERAL_CALL_enable = 0 ; 1=Generral Call enabled / 0=disabled ; REGISTER .def MODE = r19 .def ADDRESS = r17 .def TEMP = r16 .def DATA = r15 .def TEMP_SREG = r14 .def DUTY = r13 .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 TEMP,0xFF out SPL,TEMP ldi TEMP,0x04 out SPH,TEMP ; TWI initialization ; TWI TWBR ldi TEMP, 65 sts TWBR,TEMP ; TWI TWCR control-register ldi TEMP, 1< 32 / 4 = 8 cycles TableLoop: ; 2.2 Mc sampling rate ; 26 Bit resolution on frequency ; 360/1024° resolution on phase ; 9 Bit resolution on voltage ; Data tables in FLASH sbi DDRB,1 ; Bit 8 is on sbi DDRC,0 ; deglitch is needed cbi PORTC,0 sbi DDRC,1 ; addon is wanted cbi PORTC,1 clr r27 TL1: ; cycl. lpm r0,z ; 3 out PORTD,r0 ; 1 update BIT 0..7 out PortB,r31 ; 1 update Bit 8 add r28,r24 ; 1 adc r29,r25 ; 1 adc r30,r26 ; 1 adc r31,r27 ; 1 cbr r31,4 ; 1 limit to 1.5 * table length lpm r0,z ; 3 out PORTD,r0 ; 1 update BIT 0..7 out PortB,r31 ; 1 update Bit 8 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 BIT 0..7 out PortB,r31 ; 1 update Bit 8 adc r29,r25 ; 1 adc r30,r26 ; 1 adc r31,r27 ; 1 cbr r31,4 ; 1 limit to 1.5 * table length lpm r0,z ; 3 add r28,r24 ; 1 out PORTD,r0 ; 1 update BIT 0..7 out PortB,r31 ; 1 update Bit 8 adc r29,r25 ; 1 adc r30,r26 ; 1 adc r31,r27 ; 1 rjmp TL1 ; 2 => 40 / 4 = 10 cycles SawtoothLoop: ST_slow: ; 2.75 Mc sampling rate ; 25 Bit resolution on frequency ; 360/512° resolution on phase ; 9 Bit resolution on voltage sbi DDRB,1 ; Bit 8 is on sbi DDRC,0 ; deglitch is needed cbi PORTC,0 sbi DDRC,1 ; addon is wanted cbi PORTC,1 ldi r31,1 clr r28 clr r29 clr r30 add r28,r24 STL1: adc r29,r25 ; 1 adc r30,r26 ; 1 adc r31,r27 ; 1 ori r31,1 ; 1 out PORTD,r30 ; 1 update Bit 0..7 out PORTB,r31 ; 1 update Bit 8 add r28,r24 ; 1 adc r29,r25 ; 1 adc r30,r26 ; 1 adc r31,r27 ; 1 add r28,r24 ; 1 ori r31,1 ; 1 out PORTD,r30 ; 1 update Bit 0..7 out PORTB,r31 ; 1 update Bit 8 rjmp STL1; ; 2 16 / 2 = 8 cycles ST_fast: ; 4.4 Mc sampling rate ; 24 Bit resolution on frequency ; 360/256° resolution on phase ; 8 Bit resolution on voltage cbi DDRB,1 ; Bit 8 is off cbi PORTB,1 cbi DDRC,0 ; deglitch not needed cbi PORTC,0 cbi DDRC,1 ; addon not wanted cbi PORTC,1 clr r28 clr r29 clr r30 add r28,r24 STL2: adc r29,r25 ; 1 adc r30,r26 ; 1 out PORTD,r30 ; 1 update Bit 0..7 add r28,r24 ; 1 adc r29,r25 ; 1 adc r30,r26 ; 1 add r28,r24 ; 1 out PORTD,r30 ; 1 update Bit 0..7 rjmp STL2; ; 2 10 / 2 = 5 cycles RectangleMode_fast: ; 3.666 Mc sampling rate ; 17 Bit resolution on frequency ; 360/512° resolution on phase ; 1 Bit resolution on voltage cbi DDRB,1 ; Bit 8 is off cbi PORTB,1 cbi DDRC,0 ; deglitch not needed cbi PORTC,0 cbi DDRC,1 ; addon not wanted cbi PORTC,1 ser r31 ; initial out PORTD,r31 RM1: add r28,r24 ; 1 adc r29,r25 ; 1 brcc out11 ; 2 out PIND,r31 ; toggle Bit 0..7 out11: rjmp RM1; ; 2 6 cycles RectangleMode_f: ; 3.14 Mc sampling rate ; 25 Bit resolution on frequency ; 360/512° resolution on phase ; 1 Bit resolution on voltage cbi DDRB,1 ; Bit 8 is off cbi PORTB,1 cbi DDRC,0 ; deglitch not needed cbi PORTC,0 cbi DDRC,1 ; addon not wanted cbi PORTC,1 ser r31 ; initial out PORTD,r31 RM2: add r28,r24 ; 1 adc r29,r25 ; 1 adc r30,r26 ; 1 brcc out1 ; 2 out PIND,r31 ; toggle Bit 0..7 out1: rjmp RM2; ; 2 7 cycles RectangleMode_v: ; 2.444 Mc sampling rate ; 24 Bit resolution on frequency ; 360/256° resolution on phase ; 1 Bit resolution on voltage ; Duty cycle 0 to 255 cbi DDRB,1 ; Bit 8 is off cbi PORTB,1 cbi DDRC,0 ; deglitch not needed cbi PORTC,0 cbi DDRC,1 ; addon not wanted cbi PORTC,1 ser r31 clr r27 RM11: ; on off add r28,r24 ; 1 1 adc r29,r25 ; 1 1 adc r30,r26 ; 1 1 cp r30,DUTY ; 1 1 brsh off ; 2 1 nop ; 1 out PORTD,r31 ; 1 rjmp RM11 ; 2 off: out PORTD,r27 ; 1 rjmp RM11 ; 2 9 cycles NoiseLoop: ; Linear Feedback Register LFR sbi DDRB,1 ; Bit 8 = PORTB1 cbi DDRC,0 ; deglitch not needed cbi PORTC,0 cbi DDRC,1 ; addon not wanted cbi PORTC,1 ldi r21,0 ; used for XOR ldi r22,0 ; used for XOR ldi r28,0x5C ; starting value ldi r29,0xD3 ldi r30,0xBC ldi r31,0xB4 N0: ldi TEMP,0xFF ldi R20,32 ; 4*8 = 32 BIT N1: rol r28 ; rotate 3 bytes over carry rol r30 rol r31 bst r31,7 out PortB,r31 ; have some glitch bld r21,0 bst r30,5 out PORTD,r30 bld r22,0 eor r21,r22 bst r28,2 bld r22,0 eor r21,r22 bst r28,0 bld r22,0 eor r21,r22 bst r21,0 bld r28,0 dec r20 ; finished ? brne N1 ; no, go on rjmp N0 ; TWI INTERRUPPT-Routine TWSI: in TEMP_SREG,SREG ; save SREG lds TEMP, TWSR ; get TWI status andi TEMP, 0xF8 ; mask Bit3..7 (prescaler and reserve-BIT) cpi TEMP, TW_SR_SLA_ACK ; x60 breq TWSI_TW_SR_SLA_ACK cpi TEMP, TW_SR_DATA_ACK ; x80 breq TWSI_TW_SR_DATA_ACK cpi TEMP, TW_SR_STOP ; xA0 breq TWSI_TW_SR_STOP ; TWI_ERROR: ; TWI STOP ldi TEMP, (1<