簡易AVR-DDS 1KHz発振器
提供:泣かないでゆり子
ナビゲーションに移動検索に移動手元に古いAVRマイコンAT90S2313が転がってて、しかもPLLの基準信号用に1KHzが欲しかったので、AVR-DDSを作ってみた♪
基準信号作るのに74HC192とかを何石も使って分周すると、基板面積を食うので1石で1KHzの信号作れるのはイイ。
なお、さらに実装面積をケチれるように、8pinのATtiny13Aでも1KHz発振できるようにした。条件コンパイルを使ってどちらのCPUでも、同じコードで動作するようにした♪
ただしATtiny13Aは外部水晶振動子が使えず、内蔵CR発振器による動作になるので、あまり周波数精度を高くできない・・・
C言語コード
main()関数内のfreq変数を変更すれば任意の周波数で発振可能。
クロックは8MHz水晶 or 9.6MHz内蔵発振器としているが、異なる周波数を使用する場合はF_CPUを違う値に変えればおk。
なお、define定義は_AVR_ATtiny2313A_H_となっているが、AT90S2313やATtiny2313でも実行可能。
コード
/* * ATtiny2313-DDS.c * * Created: 2016/04/08 12:50:12 * Author: 市川ゆり子 */ #include <avr/interrupt.h> #include <avr/io.h> #include <avr/fuse.h> #include <avr/signature.h> //#include <io2313.h> //Define clkCPU #ifdef _AVR_ATtiny2313A_H_ #define F_CPU 8000000UL //tiny2313 Ext.XTAL 8MHz //#define F_CPU 8000000UL //90S2313 Ext.XTAL 8MHz #elif _AVR_ATTINY13A_H_ #define F_CPU 9600000UL //tiny13 Internal OSC 9.6MHz #endif #ifdef _AVR_ATTINY13A_H_ FUSES = { .low = (FUSE_SPIEN & FUSE_SUT0 & FUSE_CKSEL0), //SPIEN, InterOSC 9.6MHz 14CK 64ms .high = FUSE_BODLEVEL0 //BODLEVEL 1.8V }; #elif _AVR_ATtiny2313A_H_ //stub #endif volatile uint16_t freq; //Calling interval 31.25KHz (8MHz/256) #ifdef _AVR_ATtiny2313A_H_ ISR(TIMER0_OVF_vect){ #elif _AVR_ATTINY13A_H_ ISR(TIM0_OVF_vect){ #endif static uint32_t p; if (p < F_CPU/512) { PORTB |= _BV(PINB0); } else { PORTB &= ~_BV(PINB0); } p+=freq; if (p > F_CPU/256) { p = 0; } } int main(void) { //All Ports set OUTPUT #ifdef _AVR_ATtiny2313A_H_ DDRD = 0b01111111; #endif DDRB = 0b11111111; TCCR0B = _BV(CS00);//Timer Clock Source: clkI/O //Enable Interrupt Timer0 Overflow #ifdef _AVR_ATtiny2313A_H_ TIMSK = _BV(TOIE0); #elif _AVR_ATTINY13A_H_ TIMSK0 = _BV(TOIE0); #endif freq = 1000; sei(); while(1) { } }