cancel
Showing results for 
Search instead for 
Did you mean: 

AD9833 Module Control

BTaşk.1
Associate II

Hello,

I want to control the ad9833 module with the stm32f4 development board. I have a library but I couldn't get SPI communication. I cannot get any wave output from the module. I cannot adjust frequency. where can the problem be? I need to create this project with CUBEMX and do the work using the Keil development environment. I am using the SPI1 module of the board. I use PA5 pin as SCK, PA7 pin as MOSI and PB2 pin as GPIO reset. Below is the code part that i tried to spi communication. 

void ad9833_send(uint16_t dat)
{ 
   unsigned char i; 
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET); //clk = 1
 
 
   for(i=0; i<16; i++)
   {
 
      if (dat & 0x8000)
      {
         HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET); 
      }
      else
      {
         HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET); 
 
      }
      HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); 
 
      dat <<= 1;     
      __NOP();
      __NOP();			
      HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); 
   }
	//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); 
 
}

5 REPLIES 5
TDK
Guru

It looks like you're bit banging the SPI communication. Which is fine. Are you initializing PA5 and PA7 as output pins beforehand?

Although the first write to PA5 seems like it would generate an unwanted clock.

If you feel a post has answered your question, please click "Accept as Solution".
BTaşk.1
Associate II

Hello,

Thank you for your answer. I set CUBEMX SPIsettings as attached. When I want to change the frequency, I send data like the code below.

void AD9833setFrequency(long frequency, int Waveform) {
  
  long FreqWord = (frequency * pow(2, 28)) / refFreq;
 
  uint16_t MSB = ((FreqWord & 0xFFFC000) >> 14);    //Only lower 14 bits are used for data
  uint16_t LSB = (FreqWord & 0x3FFF);
  
  //Set control bits 15 ande 14 to 0 and 1, respectively, for frequency register 0
  LSB |= 0x4000;
  MSB |= 0x4000; 
   AD_FSYNC_LO();
   _delay_us(5);  
  ad9833_send(0x2100);   
  ad9833_send(LSB);                  // Write lower 16 bits to AD9833 registers
  ad9833_send(MSB);                  // Write upper 16 bits to AD9833 registers.
  ad9833_send(0xC000);               // Phase register
  ad9833_send(Waveform);             // Exit & Reset to SINE, SQUARE or TRIANGLE
   _delay_us(5);
   AD_FSYNC_HI();
}

I am HIGH and RESET with the PB2 GPIO pin defined in the header file of the FSYNC pin.

//
 
#define AD_FSYNC_HI() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
#define AD_FSYNC_LO()  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
 
//

turboscrew
Senior III

What's GPIO reset, and where's your FSYNC (chip select)?

 Also, maybe you should invert the clock inside the loop. The data state change should take place when the clock is high.

And to be on the safe side, DSB might be a good idea.

I'm also a bit worried about T8max.

BTaşk.1
Associate II

Hello,

Thank you for answer. GPIO reset for FSYNC pin. "Active Low Control Input. FSYNC is the frame synchronization signal for the input data. When FSYNC is taking low, the internal logic is informed that a new word is being loaded into the device." In ad9833 datasheet, it is given in table 4. https://www.analog.com/media/en/technical-documentation/data-sheets/AD9833.pdf

GPIO reset in header file.

You're not using SPI1, configure the pins in a GPIO mode, and sequence them per the data sheet​.

Review signals with a scope or analyzer.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..