AVR Assembler Source Blog

Ремонт частотных преобразователей AVR Assembler Source Blog

Monday, November 4, 2013

Sinewave generator AVR131 appnote

настройка частотных преобразователей

                              ;--------------------------------------------------------
                              ; File: main.asm
                              ;
                              ; Description: Example of how to use the fast PWM of the
                              ;  ATtiny26 to generate "sine-wave" signal.
                              ;  The PWM output requires filtering to shape
                              ;  the sine wave form.
                              ;
                              ; Revision:
                              ; 1.0 Created   2002-??-?? Raapeland
                              ; 1.1 Cosmetic changes 2003-03-19 Jllassen
                              ;  1.2 Main loop reviewed 2003-03-26 Mreintz
                              ;   1.3 Changed frequencies 2003-06-30 Raapeland
                              ;----------------------------------------------------------
.include "tn26def.inc"

                              ;Interrupt vector table
 rjmp init

.org OC1Aaddr                 ; Interrupt vector for timer1 output compare match A
 rjmp OC1A_isr

                              ; Main code
init:
       ldi r16, RAMEND        ; Initiate Stack pointer
       out SP, r16

       ldi r16, 0x10          ; Load oscillator calibration byte
       out EEAR, r16
       ldi r16, (1<<EERE)
       out EECR, r16
       in r16, EEDR
       out OSCCAL, r16 


       ldi r16, (1<<PB1)      ; Set PB1 as output
       out DDRB, r16

       ldi r16, (1<<PLLE)     ; Enable PLL
       out PLLCSR, r16

waitPLL:
       in r16, PLLCSR         ; Wait for PLL to lock (approx. 100ms)
       sbrs r16, PLOCK     
       rjmp waitPLL  

       in r16, PLLCSR         ; Set PLL as PWM clock source 
       ldi r17, (1<<PCKE)
       or r16, r17
       out PLLCSR, r16
 
       ldi r16, (1<<COM1A0)|(1<<PWM1A) ; Set PWM mode: toggle OC1A on compare
       out TCCR1A, r16        ; Enable PWM

       ldi r16, 0xFF          ; Set PWM top value: OCR1C = 0xFF
       out OCR1C, r16

       ldi r16, (1<<CS11)|(1<<CS10)|(1<<CTC1)
       out TCCR1B, r16        ; Enable Timer/Set PWM clock prescaler to PCK/4 (16MHz PWM clock)

       ldi r16, (1<<OCIE1A)   ; Enable Timer1 OVF interrupt
       out TIMSK, r16

       clr r17
       clr r18

       sei                    ; Enable global interrupts

idle:
       ldi r16, (1<<SE)       ; Enable sleep
       out MCUCR, r16
       sleep
       rjmp idle

OC1A_isr:
       ldi ZH, high(sine_table*2) ; Set up Z to point to the beginning of sine_table
       ldi ZL, low(sine_table*2)
       add ZL, r17            ; Offset Z by r18:r17
       adc ZH, r18
       lpm                    ; Load sine_table[Z] into OCR1A
       out OCR1A, r0
       inc r17

       reti

sine_table:
.db 128,131,134,137,140,144,147,150,153,156,159,162,165,168,171,174
.db 177,179,182,185,188,191,193,196,199,201,204,206,209,211,213,216
.db 218,220,222,224,226,228,230,232,234,235,237,239,240,241,243,244
.db 245,246,248,249,250,250,251,252,253,253,254,254,254,254,254,254
.db 254,254,254,254,254,254,254,253,253,252,251,250,250,249,248,246
.db 245,244,243,241,240,239,237,235,234,232,230,228,226,224,222,220
.db 218,216,213,211,209,206,204,201,199,196,193,191,188,185,182,179
.db 177,174,171,168,165,162,159,156,153,150,147,144,140,137,134,131
.db 128,125,122,119,116,112,109,106,103,100,97,94,91,88,85,82
.db 79,77,74,71,68,65,63,60,57,55,52,50,47,45,43,40
.db 38,36,34,32,30,28,26,24,22,21,19,17,16,15,13,12
.db 11,10,8,7,6,6,5,4,3,3,2,2,2,1,1,1
.db 1,1,1,1,2,2,2,3,3,4,5,6,6,7,8,10
.db 11,12,13,15,16,17,19,21,22,24,26,28,30,32,34,36
.db 38,40,43,45,47,50,52,55,57,60,63,65,68,71,74,77
.db 79,82,85,88,91,94,97,100,103,106,109,112,116,119,122,125

Process control board