//---------------------------------------------------------------- // AVR-Direct Digital Synthesiser // sine wave generator // // 2009-01-25 www.henteko.org //---------------------------------------------------------------- #include #include #include #include #include #include "lcd.h" #define cbi(addr,bit) addr &= ~(1<> 8; PORTD = pgm_read_byte(&sinewave[pos]); } //---------------------------------------------------------------- // Pin changed interrupt // ロータリーエンコーダからの信号で割り込み。 // 右回りか左回りかを判別してDDS周波数を増減 //---------------------------------------------------------------- ISR(SIG_PIN_CHANGE1) { if(bit_is_set(PINC, PC4)){ if(bit_is_clear(PINC, PC5)) renc_now = 0; else renc_now = 1; } else { if(bit_is_set(PINC, PC5)) renc_now = 2; else renc_now = 3; } if((renc_now + 3 + 1) % 3 == renc_old) { if(freq > 4000) freq -= diff; } if((renc_now + 3 - 1) % 3 == renc_old) { if(freq < 14000) freq += diff; } renc_old = renc_now; delta = freq * ACCU / SF; } int main() { unsigned char sw0_state; DDRB = 0b11111111; // LCD Output DDRC = 0b00000001; // pc1 SW pc4,5 r-enc input pc0 led DDRD = 0b11111111; // DDS Output PORTD = 0b00000000; // PORTC = 0b00000010; // pull up lcd_init(); lcd_cls(); fp = fdevopen(lcd_putch, NULL); // LCD出力ファイルディスクプリタ sw0_state = 0; PCICR = _BV(PCIE1); PCMSK1 = _BV(PCINT12)|_BV(PCINT13); TCCR1B = 0b01001001; // Timer1 プリスケーラ 1/1 TIMSK1 = _BV(OCIE1A); // Timer1 compare match A interrupt OCR1A = 124; // 20MHz sampling 200kHz 20000000/160000=125(-1) phe = 0; diff = 1; // Frequency Up Down default 1Hz freq = 10000; delta = freq * ACCU / SF; lcd_goto(0, 0); fprintf(fp, "%8d", freq); lcd_goto(1, 0); fprintf(fp, "%8ld", (unsigned long)freq * 1024l); sei(); while(1) { if(bit_is_clear(PINC, PC1)) { sw0_state = 1; delay_ms(10); } if(sw0_state && bit_is_set(PINC, PC1)) { sw0_state = 0; if(diff == 1) { diff = 10; sbi(PORTC, PC0); } else { diff = 1; cbi(PORTC, PC0); } } lcd_goto(0, 0); fprintf(fp, "%8d", freq); lcd_goto(1, 0); fprintf(fp, "%8ld", (unsigned long)freq * 1024l); } }