2016. február 18., csütörtök

AD9833 függvénygenerátor

Az AD9833 egy digitálisjelalak generátor, amely képes szinusz, négyszög és háromszög jelalakok generálására, állítható fázissal és frekvenciával, egészen 12.5MHz-ig.



1. COMP –a digitális-analóg átalakító kikapcsolására szolgál (energiatakarékosság szempontjából).
2. VDD – a Digitális és analóg áramkörök pozitív tápfeszültsége (2.3V-5.5V)
              - egy 100nF-os kondenzátorral az AGND lábra kell kötni.
3. CAP/2.5V –ez egy kimenet,a digitális áramkörök pozitív tápfeszültsége (2.5V) van rajta
            - egy 100nF-os kondenzátorral a DGND lábra kell kötni.
            - ha az IC-t 2.5V-2.7V feszültséggel üzemeltetjük, akkor közvetlenül a VDD lábra köthtető a kivezetés.
4. DGND – a digitális áramkörök földje.
5. MCLK – órajel bemenet. A kimenő frekvenciák ebből osztódnak le, pontosságuk és fázis-zajuk ettől függ.
6. SDATA – soros adatbemenet. Az IC itt fogadja a 16 bites adatokat és parancsokat.
7. SCLK – soros órajel bemenet. Ennek a lemenő élénél tologatja be az adatokat, parancsokat.
8. FSYNC – ennek logikai 0-ra állításával jelezzük, hogy adatokat szeretnénk küldeni az IC-nek.
9. AGND – az analóg áramkörök földje.
10. VOUT –az analóg és digitális áramkörök jelkimenete. Innen vehetők le a jelalakok.



REGULATOR (szabályzó)
Szétválasztja a tápfeszültséget a digitális és az analóg áramkörök számára. Míg az analóg áramkörök működnek az IC tápfeszültségének teljes tartományában (2.5V -5.5V), addig a digitális áramkörök csak 2.5V-al üzemelhetnek. Ha az IC-t 2.5V-tal tápláljuk, akkor a VDD és CAP/2.5 lábakat összekötjük, áthidalva a szabályzót.

SERIAL INTERFACE AND CONTROL LOGIC (soros interfész és logikai vezérlő)
Az IC a 16-bites adatot az SDATA lábon fogadja be az SCLK lábra érkező órajel segítségével, mikor az FSYNC láb alacsony szinten van. Ennek az idődiagramja a következő:



Amint az FSYNC lábat alacsonyra kapcsoljuk, az adat 16 SCLK óraimpulzus alatt betolódik az IC regiszterébe. Ezután ismét fel kell húzni az FSYNC szintjét, de több adat esetén folyamatosan alacsonyan lehet tartani. Fontos, hogy az SCLK magas szinten legyen, amikor az FSYNC lábat alacsonyra kapcsoljuk. Ha egy AVR mikrovezérlővel szeretnénk az adatokat az IC-nek küldeni, akkor ezeket a lábakat annak SPI interfészére csatlakoztatjuk:

SPI (mikorvezérlő)
3-wire (AD9833)
I/O láb
FSYNC
MOSI
SDATA
SCK
SCLK

A MISO lábra nincs szükség mert a kommunikáció egy irányú, az IC-től nem várunk visszajelzést.

CONTROL REGISTER (vezérlő regiszter)
A soros interfészen betologatott adat ebbe a 16 bites regiszterbe kerül. Az IC csak akkor veszi beállítási parancsnak az adatot, ha annak az első 2 bitje nulla (D15=0 és D14=0). Ellenkező esetben a frekvencia- vagy fázisregiszterek feltöltését jelenti. A parancsbitek a következők:

Bit
A bit neve
A bit értékének jelentése
D13
B28
A frekvenciaregiszterek beállítása (lásd lennebb)
D12
HLB
A frekvenciaregiszterek beállítása (lásd lennebb)
D11
FSELECT
0: a FREQ0 regisztert használja a fázis akkumulátor
1: a FREQ1 regisztert használja a fázis akkumulátor
D10
PSELECT
0: a PHASE0 regisztert adja hozzá a fázis akkumulátor kimenetéhez
1: a PHASE1 regisztert adja hozzá a fázis akkumulátor kimenetéhez
D9,D4,D2,D0
Fenntartott
0
D8
RESET
0: nem történik semmi
1: miden regisztert lenulláz
D7-D6
SLEEP1-SLEEP12
0-0: minden áramkör működik
0-1: a DAC kikapcsol
1-0: a belső órajel leáll
1-1: minden kikapcsol
D5-D1-D3
OPBITEN-MODE-DIV2
0-0-X: a kimenet szinusz jelalak
0-1-X: a kimenet háromszög jelalak
1-0-0: a kimenet a DAC adat MSB/2-je (négyszög jelalak)
1-0-1: a kimenet a DAC adat MSB-je (négyszög jelalak)
1-1-X: fenntartott

A D13 és D12 bitek a frekvenciaregiszterek beállítására szolgálnak. Mindkét regiszter 28 bites, ezért két írás szükséges ezek feltöltésére.

D13 (B28):
1: engedélyezi egyik frekvenciaregiszter teljes feltöltését két egymást követő írási folyamattal, melyből az első a kódszó 14 LSB-jét, a második pedig a 14 MSB-jét írja be. A regiszter csak a második írási folyamat után veszi fel az új értéket, ellenkező esetben változatlan marad. Mindkét 16 bites szó első két bitje a frekvenciaregiszterre utal, amelybe az írás történik. A frekvenciaregiszterek címei a következők:

D15-D14
Frekvenciaregiszter
0-1
FREQ0
1-0
FREQ1

0: a 28 bites frekvenciaregiszter két 14 bites regiszterként működik, melyek közül egyik a 14 bites MSB-t, másik a 14 bites LSB-t tartalmazza. Ez lehetővé teszi az LSB vagy MSB független módosítását. Hogy melyiket változtatjuk ezek közül, azt a D12 bittel adjuk meg.

D12 (HLB): csak akkor érvényes, ha a D13 bit nulla. Az LSB és MSB közti választást teszi lehetővé.
1: 14 bit MSB beírása a felosztott frekvenciaregiszterbe
0: 14 bit LSB beírása a felosztott frekvenciaregiszterbe

A fázisregiszterekbe is hasonlóképp történik az írás, ám ezek 12 bitesek így nincs szükség a működési módjukat változtató bitekre a vezérlőregiszterben, hiszen egyetlen írással teljesen feltölthetőek. A 16 bites szó első 4 bitje a fázisregiszter címére utal:

D15-D14-D13-D12
Fázisregiszter
1-1-0-X
PHASE0
1-1-1-X
PHASE1

FREQ0, FREQ1, PHASE0, PHASE1(frekvencia és fázis regiszterek)
Amikor az IC-be írt adat nem parancs, akkor az értékek a frekvencia vagy a fázis regiszterekbe töltődnek. A frekvenciaregiszterek a kimenet frekvenciáját, a fázisregiszterek pedig a kimenet fázisát határozzák meg:

\[\text{Frekvencia} = \frac{f_{MCLK}}{2^{29}}\cdot \text{FREQ regiszter}\] \[\text{Fázis} = \frac{2\pi}{4096}\cdot \text{PHASE regiszter}\]

Azért van kettő mindenikből, mert ha mindkettőt feltöltjük különböző értékekkel, akkor modulált jelet alkothatunk a kimeneten (FSK és PSK moduláció). Ezt persze úgy is lehet, hogy mindenik modulálandó bitnél átírjuk a regiszterek tartalmát, de sokkal gyorsabb az FSELECT vagy PSELECT biteket változtatgatni. A MUX azt a regisztert kacsolja a kimenetére, amelyiket beállítottunk a parancsban.

PHASE ACCUMULATOR
Úgy lehet rá tekinteni, mint egy számlálóra. Egy 28 bites regiszterből és egy összegzőből áll. A regiszterbe betölti a frekvenciaszót, majd az órajel minden ciklusánál hozzáadja bemenő frekvenciaszóhoz. A kimenet ezért fokozatosan nő, minden óraciklusban a frekvenciaszó értékével lesz nagyobb. Egy bizonyos számú összegzés után a regiszter túlcsordul és a számlálás alaphelyzetbe áll. Ez pontosan egy teljes periódus után következik be. A kimenet tehát egy fűrészfogjel, ahol a fogak hosszúsága megfelel a kívánt frekvencia periódusával. Ez egy összegzőbe kerül, ahol a fázisértékkel adódik össze, aminek eredményeképp hamarább történik túlcsordulás, a jel tehát késleltethető. Az összegző kimenete 12 bitre van csonkítva. Ennek előnye, hogy a SIN ROM kisebb lookup táblázatot is használhat.

SIN ROM
Egy memória, ami a lookup (keresési) táblázatot tartalmazza. Ennek segítségével alakítja át a bemenő fázisinformációt szinusz hullámmá. Ez a táblázat minden fázisadathoz egy amplitúdóértéket rendel, így a memóriából szinusz jelalakhoz tartozó amplitúdó értékek olvashatóak ki. A kimenetén lévő MUX azért van, hogy mikor nem szinusz kimenetet konfigurálunk be, akkor átkapcsol és a 12 bites fűrészfogjelet adja a DAC-ra.

DAC(Digitális - Analóg átalakító)
Felbontása 10 bit és feladata, hogy a bináris értékeket analóg feszültségszintté alakítsa. A szinusz és a háromszögjelnél működik. A kimenő feszültsége 0.6V csúcstól csúcsig, ami a VOUT kimenő lábra van vezetve közvetlenül. A DAC-nek van egy referenciafeszültsége (ON-BOARD REFERENCE), amitől a kivezérlési tartomány függ. A kivezérlési tartományt a FULL-SCALE CONTROL állítgatja a referenciafeszültséghez képest úgy, hogy a DAC semmiképp se telítődjön túl. A kimeneten lennie kell egy minimális terhelésnek, ami egy 200 ohmos ellenállásként van beépítve az IC-be.

MSB, DIVIDE BY 2, MUX
Ha kimenetnek négyszögjelet választunk, akkor a DAC adatok MSB-je kerül a kimenetre. Ez egyébként folyton jelen van az IC-ben, csupán az OPBITEN bit nullán tartása gátolja, hogy a kimenő lábra kerüljön. Ha a MUX-ot a DIVIDE BY 2 blokkra kapcsoljuk (a DIV2 bittel), akkor a négyszögjel frekvenciája a felére csökken.

Tesztáramkör


A következő kapcsolás egy ATMega8 mikrovezérlővel kapcsolja össze az AD9833-at. Ehhez 3 kivezetés szükséges. Az utasítások átadása akár 40MHz-es frekvencián is történhet (ami a modulációknál hasznos), ám ezúttal a mikrovezérlő belső 8MHz-es órajelét használjuk. Az AD9833 órajelét az MCLK kivezetésre kell csatlakoztatni, és ebből osztja majd le a kimenő jelalakok frekvenciáját. Ennek legnagyobb értéke 25MHz lehet amikor is a maximális kimenő frekvencia:

\[Frekvencia = \frac{25MHz}{2^{28}}\cdot 0x7FFFFFF=\frac{25000000}{268435456}\cdot 134217727=\] \[=12.5MHz\]

25MHz MCLK frekvencián a felbontás 0.1Hz. Kisebb órajelnél, például 1MHz-en a felbontás 0.004Hz-re javul. Ebben az esetben 25MHz-es órajelet adunk az áramkörnek. VCC=5V és a kimenő jelalakot az AD9833 IC VOUT kivezetésén mérjük.



Tesztprogram


A következő program a mikrocontroller.net fórum egyik topikjából van átírva. Szinusz, négyszög és háromszögjeleket képes produkálni 12.5MHz-ig változtatható frekvencián.

#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>

//Stringek
#define Kikapcs   0
#define Szinusz   1
#define Negyszog  2
#define Haromszog 3

//Parancsbitek
#define B28       13
#define HLB       12
#define FSELECT   11
#define PSELECT   10
#define RESET     8
#define SLEEP1    7
#define SLEEP12   6
#define OPBITEN   5
#define DIV2      3
#define MODE      1

//SPI lábak
#define MOSI    3    //PB3
#define SCK     5    //PB5
#define FSYNC   2    //PB2

//Globális változók
uint16_t stats = 0;
uint16_t tosend = 0;

void DDS_write(uint16_t data)
{
     PORTB &= ~(1<<FSYNC);           // a küldés alatt az FSYNC alacsony
     SPDR = (uint8_t)(data>>8);      // LSB - utolsó 8 bit
     while(!(SPSR & (1<<SPIF)));     // várunk míg átmegy
     SPDR = (uint8_t)(data & 255);   // MSB - elsõ 8 bit
     while(!(SPSR & (1<<SPIF)));     // várunk míg átmegy
     PORTB |= (1<<FSYNC);            //a küldés után az FSYNC újr magas
}

void DDS_off(void)
{
     // teljes frekvenciaszó, nullázás, MCLK kikapcs
     stats = (1<<B28)|(1<<RESET)|(1<<SLEEP1);
     DDS_write(stats);
     stats &= ~(1<<RESET); // RESET láb felold
     _delay_ms(1);
     DDS_write(stats);
}

void DDS_init(void)
{
     DDRB|=(1<<MOSI)|(1<<SCK)|(1<<FSYNC);       // kimenetek
     PORTB|=(1<<FSYNC);                         // FSYNC magas
     SPCR=(1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<SPR0);
     // SPI enable, Master mode, SCK=f/16, SCK=high when idle
     DDS_off(); // Kezdetben kikapcs, amig a beallitasok tortennek.
}

void DDS_signal(uint8_t signal)
{
     stats&=~(1<<SLEEP1); //minden áramkör mûködik
     switch (signal)
     {
           case Kikapcs:
                DDS_off();
                break;
           case Szinusz:
                stats &=~((1<<OPBITEN)|(1<<MODE));
                break;
           case Negyszog:
                stats|=(1<<OPBITEN)|(1<<DIV2);
                stats&=~(1<<MODE);
                break;
           case Haromszog:
                stats&=~(1<<OPBITEN);
                stats|=(1<<MODE);
                break;
           default:
                stats|=(1<<OPBITEN)|(1<<MODE);
     }
     DDS_write(stats);
}

void DDS_freq(uint32_t f)
{
     double temp = (double)f/25000000;
     uint32_t regist = temp*268435456; //2^28, (1<<28);
    
     tosend = regist & 16383;
     tosend |= (1<<14);
     DDS_write(tosend);
    
     tosend = (regist & ~16383)>>14;
     tosend |= (1<<14);
     DDS_write(tosend);
}

int main(void)
{
 DDS_init();               // portok, regiszterek inicializálása
 DDS_signal(Negyszog);     // Jelalak megadása
 DDS_freq(12500000);       // Frekvencia megadása Hz-ben
}

A kimeneti jelalakok 1kHz-en és azon a legnagyobb frekvencián, ahol még nem torzulnak:



A szinusz-hullám 4MHz fölött már lépcsősödni kezd, a háromszögjelnek a csúcsai 1MHz  fölött egyre jobban eltompulnak, a négyszögjel viszont megőrzi formáját a végsőkig (12.5MHz). A Szinusz és a háromszögjel átmegy az AD9833 digitális-analóg átalakítóján, ezért ezek amplitúdója (csúcstól csúcsig) 0.6V. Ám ahogy a frekvencia növekszik az amplitúdó is csökken: az 1MHz-es háromszögjelnél 0.5V-ra, a 4MHz-es szinusznál 0.35V-ra esett. A négyszögjelnél nincs ilyen probléma, mert az megkerüli a DAC-t és közvetlenül a kimenetre kerül, így annak amplitúdója a tápfeszültséggel azonos (itt kb. 5V).

Ezek után már csak pár nyomógomb szükséges a jelalak valamint a frekvencia változtatgatására és esetleg egy LCD kijelző amin visszajelzést kapunk a beállított értékről és máris kész a függvénygenerátor.