I am trying to generate sine wave using programmable waveform generator AD9833 with ATmega32-A micro controller.(MCLK =8MHz clock frequency). I am using USART communication and so if i change frequency in hyper terminal then the waveform frequency has to change.
I wrote small code for this as shown below.
but from the above code I am generating sine wave but if I want to change frequency of signal to 125KHz then I have to enter 499.9KHz at hyperteminal.If i enter 125 KHz then it is showing 31.2KHz. I don’t know why it is generating like that and what mistake I did? and also it is changing the waveform until 500KHz frequency suppose if i enter frequency of wave form around 1000KHz but there is no change in the frequency of the signal it is showing only 125KHz.
finally i want to generate waveform with different frequency’s. If I change frequency at hyper terminal or putty then what ever frequency I enter it has to generate waveform with that frequency.
This is my first post so if any grammatical mistakes are there then please excuse me.
Thanks in advance.
void unicom(void){
switch(Command){
case(WGF):
if(Param < 500)
SetWGFreq(Param);
Command = 0;
break;
case....
case....
default:
}
void main(void){
SetWGFreq(125);
-----------
--------
}
Hi Once Again,
This time i am trying programming AD9833 with SM470R1B1M-HT microcontroller via SPI. I am fallowing the same principle as explained by the “ross” below.
It seems i am not able to change sinewave frequency.
Below is the code i am trying, I set the same configuration with clocks as before.
void SetupSPI(void);
unsigned char spi(unsigned char data);
void SetWGFreq(unsigned int);
void setFrequencyA(unsigned long fdata);
void WG_CS_Status(int status);
int main(void)
{
GCR &= ~ZPLL_MULT4;
GCR &= ~ZPLL_CLK_DIV_PRE1;
GCR &= ~ZPLL_CLK_DIV_PRE2;
GCR &= ~ZPLL_CLK_DIV_PRE3;
PCR = CLKDIV_1; // ICLK = SYSCLK
PCR |= PENABLE; // Enable peripherals
GIODIRA |= X7;
CLKCNTL |= CLKDIR | CLKSR_ICLK;
SetupSPI();
for(;;)
{
//SetWGFreq(25);
setFrequencyA(1045200);
} // Wait in endless loop
}
void SetupSPI(void)
{
int data = 0;
SPI2CTRL1 = CHARLEN_8 + PRESCALE_4; // 8 bits per xfer
SPI2CTRL2 |= CLKMOD + MASTER + POLARITY; // We are the master
SPI2PC6 |= SOMI_FUN | SIMO_FUN | CLK_FUN;
// SPI2PC6 |= 0x0E;
// enable
SPI2CTRL2 |= SPIEN;
data = SPI2BUF;
}
unsigned char spi(unsigned char data)
{
SPI2DAT1 = data;
while(!(SPI2CTRL3 & 0x01)){} // Wait for RxFlag to get set
return (SPI2BUF & 0x000000FF); // Read SPIBUF
}
void setFrequencyA(unsigned long fdata)
{
WG_CS_Status(0);
while(GIODOUTA&X7); // Delay
spi(0x20); // Initiate loading of frequence register 0 by 28 bits.
spi(0x00);
spi(( 0x40 | (0x3F & (fdata >> 8)))); // load bit 8-13 + 0x40.
spi(fdata); // load bit 0-7
spi(( 0x40 | (0x3F & (fdata >> 22)))); // load bit 22-27 + 0x40.
spi(fdata >> 14); // load bit 14-21
spi(0); // dummy write
WG_CS_Status(1);
}
void WG_CS_Status(int status)
{
if(status == 0)
{
// Make Chip Select low
GIODOUTA &= ~X7;
}
else
{
// Make Chip select high
GIODOUTA |= X7;
}
}
I am attaching the SPI guide i fallowed for this controller and AD9833 programming not.SPI guide AD9833
When you’re converting the frequency to the two blocks of 14-bit numbers the AD9833 needs, you’re OR’ing in the D14 and D15 of the frequency register. There are two problems there.
The first problem is that you’re losing 4 bits (2 bits of a time) of your freg value.
The second problem is that you need the bits 15 and 14 to be exactly 0x40. Right now with OR’ing in the data the result could be 0xC0 if data had already been there based on your frequency.
As a minor note I see no reason to use masks when assigning to
fByte0-3, as you’re using as assignment.So, combining the two fixes and simplifying the masks gives:
I think that’ll get you where you want to be.