;*************************************************************************** ; AT45 microdds sine wave generator incl sweep, ok ; ; timer 0 interrupt used to read ADC @ 30.5 ms or inc sweep ; timer 1 pwm @ 230kHz with PLL enabled ; filter OC1A output with LC 1 mH 3 nF ; Range: 15Hz - 31 kHz ; ; changed to ATtiny45 GS 2009 ; The fuse is set for 8 MHz internal osc ; ;*************************************************************************** ; ; ATtiny45 dip ;(PCINT5/RESET/ADC0/dW) PB5 VCC ;(PCINT3/XTAL1/CLKI/OC1B/ADC3) PB3 PB2 (SCK/USCK/SCL/ADC1/T0/INT0/PCINT2) ;(PCINT4/XTAL2/CLKO/OC1B/ADC2) PB4 PB1 (MISO/DO/AIN1/OC0B/OC1A/PCINT1) ; GND PB0 (MOSI/DI/SDA/AIN0/OC0A/OC1A/AREF/PCINT0) ; ;*************************************************************************** ; ; PB4: input ADC1 0-5 Volt set frequency ; PB3: output ; PB2: input high: read ADC, low: sweep up from last frequency ; PB1: output OC1A frequency out, filter output for sine ; PB0: output toggle, shows TC0 overflow ; ;*************************************************************************** ; ; Output frequency (using 16 bit accumulator) : ; ; f = deltaPhase * fClock/2^16 ; ; fClock is the CPU clock divided by the ; number of cycles to output the data ( 8 cycles ) ; ; f = Delta1,Delta2 * (clock/8)/65536 ; ; f = Delta1,Delta2 * 15.26 @ 8Mhz ; fmax = 2046 * 15.26 = 31219 Hz ; ; ;*************************************************************************** .DEVICE ATtiny45 ;for gavrasm .equ DDRB_config = 0b00001011 .equ portB_config = 0b00000100 ; set port .equ ADC_poti = 0b00000010 ; frequency set by ADC2 pin3 (poti) .equ ADC_start = 0b11010110 ; ADC init single conversion prescale 16 .equ maxpwm = 255 ; .equ defpwm = 128 ; init duty cycle for pwm, sine out .equ T1_on = 0b01100001 ; PCk 230 kHz .equ sweepstep = 1 ; sweepstep * 15.26 Hz for sweep .equ sweeplen = 255 ; sweeplen * sweepstep * 15.26 Hz total sweep .equ toggle = PB0 .equ ADconv = PB3 ;************ .def av_l = r10 ; Average Low Byte (ADC Measurement) .def av_h = r11 ; Average High Byte (ADC Measurement) .def zero = r12 ; zero .def ri = r15 ; Sreg .def temp = r16 ; Temporary Register .def temp1 = r17 ; Temporary Register .def sweepcnt = r18 ; sweeplen counter .def sweepL = r24 ; sweeplen counter .def sweepH = r25 ; sweeplen counter .def Delta1 = r26 ; deltaPhase .def Delta2 = r27 .def Dds1 = r29 ; 2 byte DDS accumulator .def Dds2 = r30 ;*************************************************************************** .Cseg .Org $0000 ; Reset-vector to adress 0000 rjmp RESET ; Reset Handler reti ; IRQ0 Handler reti ; PCINT0 Handler reti ; Timer1 CompareA Handler reti ; Timer1 Overflow Handler rjmp TIM0_OVF ; Timer0 Overflow Handler ;*************************************************************************** ; Interrupt-Service-Routine Timer0 Overflow Handler ;*************************************************************************** TIM0_OVF: in ri,SREG ; save the flag register sbi PinB, toggle ; Flip Pb0 @ 30.5 ms sbis PINB, PINB2 rjmp T0_sweep ; if low, sweep T0_start: sbi Portb, ADconv ; short pulse ldi temp1, ADC_start ; get ADC value for frequency setting out ADCSRA,temp1 ; Start A/D Conversion T0_waitc1: sbis ADCSRA, ADIF rjmp T0_waitc1 ; add result in temp1, ADCL add av_l, temp1 in temp1, ADCH adc av_h, temp1 ; Add new value to old value cbi Portb, ADconv tst av_l ; no zeros in phase register brne T0_go tst av_h brne T0_go inc av_l ; else inc if zero T0_go: mov Delta1, av_l ; move to phase mov Delta2, av_h ; range 1..2046 lsr av_h ror av_l ; average div by 2 T0_ex: out SREG,ri ; restore flag register reti ; Return from interrupt T0_sweep: subi Delta1, -sweepstep ; sweep up from old frequency adc Delta2, zero dec sweepcnt ; reached end ? brne T0_ex ; 0x07ff rjmp T0_start ; set phase to sweep start frequency ;*************************************************************************** RESET: ldi temp, low(RAMEND) out SPL, temp ; setup stack pointer ldi temp, high(RAMEND) out SPH, temp ; setup stack pointer ; writing the calibration byte to the OSCCAL Register. ;ldi temp,0xf0 ; test ;out OSCCAL,temp ; adjust the clock nop ; PLL setup ldi temp, (1<