回路中でアナログな波形が欲しいことがあります、とくに正弦波。オペアンプでウイーンブリッジやクワドラチャを組む、、、とか、マイコンやFPGAでR-2R DACを構成する、、、とか、マイコンやFPGAでPWM的DACで出す、、、とか、ありますが、どれも長所短所があって、なかなかに難しい問題です。で、それを一気に解決してくれる夢のICがAD9833です。専用ICなので、柔軟性と安定性が両立しているのが魅力です。で、親切にもすぐ使えるようにしてあるモジュールが手に入るので、まずはこれで試してみようと思います。
RSでAD9833を買うと1106円、上記モジュールは998円、、、なんだかなぁ、、、
で、結線します。
SPIモードについて、データシートによると
となっていて、
アナログデバイセズのAD9833のページの下のほうにあるドキュメントのうちAN-1248を見てみると、
ということですので、AD9833の場合、FSYNC立下りでSCLKはHなので、Modeは2または3ということがわかり、SCLKの立下りで取り込んでいるよう(日本語版データシートの9ページ目に記述あり)なので、Mode2だということがわかります。
アナログデバイセズのAD9833のページの下のほうにあるドキュメントのうちAN-1070を参考に(ていうかそのまんま)書くとうまく動かない。他の人のをみると31行目が0x2000となっているので、そうすると、動きました、、、ていうかそれすらなくしても動くのはなぜか、、、
- #include "SPI.h"
- #define AD9833_FSYNC (7)
- #define AD9833_SDATA (10)
- #define AD9833_SCLK (8)
- #define SPI_MISO (9)
- #define MCLK (25000000)
- SPIClass mySPI(&sercom0,SPI_MISO,AD9833_SCLK,AD9833_SDATA,SPI_PAD_2_SCK_3,SERCOM_RX_PAD_0);
- void WriteRegAD9833(uint16_t wd){
- digitalWrite(AD9833_FSYNC,LOW);
- mySPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE2));
- mySPI.transfer16(wd);
- mySPI.endTransaction();
- digitalWrite(AD9833_FSYNC,HIGH);
- }
- void SetAD9833(uint32_t frequency){
- uint64_t temp;
- uint32_t FREQREG;
- uint16_t FREQ01,FREQ00;
- temp=((uint64_t)frequency)<<28;
- temp=temp/((uint64_t)MCLK);
- FREQREG=(uint32_t)(temp&0x00000000FFFFFFFF);
- FREQ01=(uint16_t)((FREQREG>>14)&0x3FFF);
- FREQ00=(uint16_t)((FREQREG>>0)&0x03FFF);
- SerialUSB.println(FREQREG,HEX);
- SerialUSB.println(FREQ01,HEX);
- SerialUSB.println(FREQ00,HEX);
- // WriteRegAD9833(0x2000);
- WriteRegAD9833(0x4000|FREQ00);
- WriteRegAD9833(0x4000|FREQ01);
- WriteRegAD9833(0xC000);
- WriteRegAD9833(0x2000);
- }
- void setup() {
- SerialUSB.begin(115200);
- while(!SerialUSB){
- //wait for SerialUSB stabled
- }
- pinMode(AD9833_FSYNC,OUTPUT);
- digitalWrite(AD9833_FSYNC,HIGH);
- mySPI.begin();
- delay(100);
- SetAD9833(2500000);
- }
- void loop() {
- }
できた!けど、MCLK=25MHzでFout=2.5MHzだと結構カクカク、、、
MCLK=10MHzで1.5MHzを出したいんだけど、、、だめかな、、、
コメントをお書きください