Controlling AD9833 with STM32F4 Discovery Board

Discussion in 'Embedded Systems and Microcontrollers' started by solijoli, Nov 20, 2014.

  1. solijoli

    Thread Starter New Member

    Nov 20, 2014
    3
    0
    Hello, I have the module of the AD9833 wave generator chip as in the link:

    https://www.google.com/search?q=ad9833 module&biw=1600&bih=799&noj=1&source=lnms&tbm=isch&sa=X&ei=tC9uVPGZLYmqywOl5IL4Ag&ved=0CAkQ_AUoAg

    I'm trying to control the chip with the STM32F4 Discovery board via SPI. I need the user to be able to select the waveform type (sinusoidal, square or triangular) and select the frequency and phase for the signal. I don't have much experience with ARM based controllers but I've written a code like this:

    Code (Text):
    1.  
    2. #include "stm32f4xx.h"
    3. #include "stm32f4xx_rcc.h"
    4. #include "stm32f4xx_gpio.h"
    5. #include "stm32f4xx_spi.h"
    6.  
    7.  
    8. #define AD_MCLK 25000000
    9. uint16_t stats = 0;
    10. uint16_t tosend = 0;
    11. #define constant1   268435456 //2^28, (1<<28)
    12. #define constant2   4096 //2^12, (1<<12)
    13.  
    14. #define pi2       6.2832
    15.  
    16. #define AD_B28     13
    17. #define AD_HLB     12
    18. #define AD_FSELECT 11
    19. #define AD_PSELECT 10
    20. #define AD_RESET   8
    21. #define AD_SLEEP1  7
    22. #define AD_SLEEP12 6
    23. #define AD_OPBITEN 5
    24. #define AD_DIV2    3
    25. #define AD_MODE    1
    26.  
    27. #define AD_OFF       0
    28. #define AD_SINUS     1
    29. #define AD_RECT1     2
    30. #define AD_RECT2     3
    31. #define AD_TRIANGLE  4
    32.  
    33. #define AD_FREQ0     18
    34. #define AD_FREQ1     28
    35. #define AD_PHASE0    38
    36. #define AD_PHASE1    48
    37.  
    38. void Delay1ms(uint32_t nCount);
    39. volatile uint32_t delay1ms;
    40.  
    41. void Delay1ms(uint32_t nCount)
    42. {
    43.   delay1ms = nCount;
    44.   while(delay1ms);
    45. }
    46.  
    47. void SysTick_Handler(void)
    48. {
    49. if(delay1ms) delay1ms--;
    50. }
    51.  
    52.  
    53. void AD9833_write(uint16_t data)
    54. {
    55.  
    56.     GPIO_ResetBits(GPIOE, GPIO_Pin_7);
    57.  
    58.     SPI_I2S_SendData(SPI1, (data>>8)); //MSB_First
    59.     //while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); // wait until transmit complete
    60.     while(SPI_I2S_GetFlagStatus (SPI1, SPI_I2S_FLAG_BSY) == SET); // wait until SPI is not busy anymore
    61.     SPI_I2S_SendData(SPI1, (uint8_t)(data & 255));  //LSB
    62.     //while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); // wait until transmit complete
    63.     while(SPI_I2S_GetFlagStatus (SPI1, SPI_I2S_FLAG_BSY) == SET); // wait until SPI is not busy anymore
    64.  
    65.     GPIO_SetBits(GPIOE, GPIO_Pin_7);
    66. }
    67.  
    68.  
    69. void AD9833_setfreq(uint32_t frequency, uint8_t reg){
    70.     double temp = ((double)frequency/(double)AD_MCLK);
    71.     uint32_t regist = temp * constant1;
    72.     tosend = regist & 0x3FFF;
    73.     if (reg == AD_FREQ0){tosend |= (1<<14);}
    74.     if (reg == AD_FREQ1){tosend |= (1<<15);}
    75.     Delay1ms(5);
    76.     AD9833_write(tosend);
    77.     Delay1ms(5);
    78.     tosend = (regist & ~0x3FFF)>>14;
    79.     if (reg == AD_FREQ0){tosend |= (1<<14);}
    80.     if (reg == AD_FREQ1){tosend |= (1<<15);}
    81.     AD9833_write(tosend);
    82.  
    83. }
    84.  
    85. void AD9833_setphase(uint16_t phase, uint8_t reg){
    86.     uint16_t regist = (uint16_t) (phase*constant2)/pi2;
    87.     tosend = (1<<15) | (1<<14);
    88.     if (reg == AD_PHASE1){tosend |= (1<<13);}
    89.     AD9833_write(tosend | regist);
    90. }
    91.  
    92. void AD9833_setmode(uint8_t signal){
    93.     switch (signal){
    94.         case AD_OFF:
    95.             AD9833_off();
    96.             break;
    97.         case AD_SINUS:
    98.             stats &=  ~((1<<AD_OPBITEN) | (1<<AD_MODE) | (1<<AD_SLEEP1));
    99.             break;
    100.         case AD_RECT2:
    101.             stats &=  ~((1<<AD_MODE) | (1<<AD_DIV2) | (1<<AD_SLEEP1));
    102.             stats |= (1<<AD_OPBITEN);
    103.             break;
    104.         case AD_RECT1:
    105.             stats |= (1<<AD_OPBITEN) | (1<<AD_DIV2);
    106.             stats &= ~((1<<AD_MODE) | (1<<AD_SLEEP1));
    107.             break;
    108.         case AD_TRIANGLE:
    109.             stats &= ~((1<<AD_OPBITEN) | (1<<AD_SLEEP1));
    110.             stats |= (1<<AD_MODE);
    111.             break;
    112.         default:
    113.             stats |= (1<<AD_OPBITEN) | (1<<AD_MODE);
    114.     }
    115.     AD9833_write(stats);
    116. }
    117.  
    118. void AD9833_reg(uint8_t reg){
    119.     switch (reg){
    120.         case AD_FREQ0:
    121.             stats &= ~(1<<AD_FSELECT);
    122.             break;
    123.         case AD_FREQ1:
    124.             stats |= (1<<AD_FSELECT);
    125.             break;
    126.         case AD_PHASE0:
    127.             stats &= ~(1<<AD_PSELECT);
    128.             break;
    129.         case AD_PHASE1:
    130.             stats |= (1<<AD_PSELECT);
    131.             break;
    132.         default:
    133.             stats &= ~((1<<AD_FSELECT) | (1<<AD_PSELECT));
    134.     }
    135.     AD9833_write(stats);
    136. }
    137.  
    138.  
    139. void init_SPI1(void)
    140.   {
    141.  
    142.         GPIO_InitTypeDef GPIO_InitStruct;
    143.         SPI_InitTypeDef SPI_InitStruct;
    144.  
    145.  
    146.            // enable peripheral clock
    147.            RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    148.  
    149.  
    150.            SPI_InitStruct.SPI_Direction = SPI_Direction_1Line_Tx;
    151.            SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
    152.            SPI_InitStruct.SPI_DataSize = SPI_DataSize_16b;
    153.            SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
    154.            SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
    155.            SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
    156.            SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
    157.            SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
    158.            SPI_Init(SPI1, &SPI_InitStruct);
    159.  
    160.  
    161.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    162.         /* configure pins used by SPI1
    163.          * PA5 = SCK
    164.          * PA6 = MISO
    165.          * PA7 = MOSI
    166.          */
    167.         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_5;
    168.         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    169.         GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    170.         GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    171.         GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    172.         GPIO_Init(GPIOA, &GPIO_InitStruct);
    173.  
    174.         // connect SPI1 pins to SPI alternate function
    175.         GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
    176.         GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
    177.  
    178.         // enable clock for used IO pins
    179.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
    180.  
    181.         /* Configure the chip select pin
    182.            we will use PE7 */
    183.         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
    184.         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    185.         GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    186.         GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    187.         GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    188.         GPIO_Init(GPIOE, &GPIO_InitStruct);
    189.  
    190.  
    191.         GPIO_SetBits(GPIOE, GPIO_Pin_7); // set PE7 high
    192.  
    193.         SPI_Cmd(SPI1, ENABLE); // enable SPI1
    194.     }
    195.  
    196. int main(void) {
    197.  
    198.     init_SPI1();
    199.  
    200.     AD9833_setmode(AD_SINUS);
    201.     AD9833_setfreq(1000, AD_FREQ0);
    202.     AD9833_setphase(0,AD_PHASE0);
    203.  
    204.  
    205.     while(1){
    206.  
    207.     }
    208. }
    209.  
    But the code doesn't function properly. I couldn't tell if my SPI configuration or the way I send data is wrong or if there any other bugs. Where am I doing wrong and how can this be fixed? Thanks for the help!

    Link for AD9833 datasheet if needed:

    http://www.analog.com/static/imported-files/data_sheets/AD9833.pdf
     
  2. MrChips

    Moderator

    Oct 2, 2009
    12,446
    3,362
    That doesn't give us much to work on. Tell us what it does and what it doesn't.

    So you have setmode, setfreq and setphase. But you haven't told it to do anything.

    Do you have access to an oscilloscope?
     
  3. solijoli

    Thread Starter New Member

    Nov 20, 2014
    3
    0
    I'm sorry, there was a mistake, can you consider this code:

    Code (Text):
    1.  
    2. #include "stm32f4xx.h"
    3. #include "stm32f4xx_rcc.h"
    4. #include "stm32f4xx_gpio.h"
    5. #include "stm32f4xx_spi.h"
    6.  
    7.  
    8. #define AD_F_MCLK 25000000 //Clock speed of the ad9833 reference clock
    9. #define AD_2POW28 268435456 //used in calculating output freq
    10. #define AD_FREQ_CALC(freq) (uint32_t)(((double)AD_2POW28/(double)AD_F_MCLK*freq))
    11. #define AD_PHASE_CALC(phase_deg) (uint16_t)((512*phase_deg)/45)
    12. static uint16_t CONTROL_REGISTER;
    13.  
    14. #define USE_FREQ0_REG             0
    15. #define USE_FREQ1_REG             1
    16. #define USE_PHASE0_REG             0
    17. #define USE_PHASE1_REG             1
    18.  
    19. #define WRITE_TO_FREQ1_REG         0x8000
    20. #define WRITE_TO_FREQ0_REG         0x4000
    21. #define WRITE_TO_PHASE1_REG         0xE000
    22. #define WRITE_TO_PHASE0_REG         0xC000
    23.  
    24. #define AD_B28     13
    25. #define AD_HLB     12
    26. #define AD_FSELECT 11
    27. #define AD_PSELECT 10
    28. #define AD_RESET   8
    29. #define AD_SLEEP1  7
    30. #define AD_SLEEP12 6
    31. #define AD_OPBITEN 5
    32. #define AD_DIV2    3
    33. #define AD_MODE    1
    34.  
    35. #define AD_OFF      0
    36. #define AD_TRIANGLE 1
    37. #define AD_SQUARE   2
    38. #define AD_SINE     3
    39.  
    40.  
    41. typedef struct {
    42. uint8_t  freq_out;
    43. uint8_t  phase_out;
    44. uint8_t  mode;
    45. uint16_t command_reg;
    46. } ad9833_settings_t;
    47.  
    48. typedef struct {
    49.     float    freq[2];
    50.     float    phase[2];
    51. } ad9833_settings_f;
    52.  
    53.  
    54. ad9833_settings_t ad_settings;
    55. ad9833_settings_f ad_settings2;
    56.  
    57.  
    58. void delay(__IO uint32_t nCount)
    59. {
    60.   while(nCount--)
    61.   {
    62.   }
    63. }
    64.  
    65.  
    66. static void AD9833_word(uint16_t data)
    67. {
    68.     SPI1->DR = (data>>8); // High 8 bits, MSB first
    69.     while(!(SPI1->SR & SPI_I2S_FLAG_TXE));
    70.     while( SPI1->SR & SPI_I2S_FLAG_BSY );
    71.     SPI1->DR = (uint8_t) data; // Low 8 bits
    72.     while(!(SPI1->SR & SPI_I2S_FLAG_TXE));
    73.     while( SPI1->SR & SPI_I2S_FLAG_BSY );
    74. }
    75.  
    76. static void AD9833_write(uint16_t data)
    77. {
    78.     GPIO_ResetBits(GPIOE, GPIO_Pin_7);
    79.     delay(0xFFF);
    80.     AD9833_word(data);
    81.     delay(0xFFF);
    82.     GPIO_SetBits(GPIOE, GPIO_Pin_7);
    83.     delay(0xFFF);
    84. }
    85.  
    86. void ad9833_setPhase(uint8_t reg, double phase){
    87.     uint16_t reg_reg;
    88.     if (reg==1)
    89.         reg_reg = WRITE_TO_PHASE1_REG;
    90.     else
    91.         reg_reg = WRITE_TO_PHASE0_REG;
    92.  
    93.     ad_settings2.phase[reg] = phase;
    94.  
    95.     GPIO_ResetBits(GPIOE, GPIO_Pin_7);
    96.     delay(0xFFF);
    97.     AD9833_word(reg_reg | AD_PHASE_CALC(ad_settings2.phase[reg]));
    98.     delay(0xFFF);
    99.     GPIO_SetBits(GPIOE, GPIO_Pin_7);
    100. }
    101.  
    102. void AD9833_setFreq(uint8_t reg, double freq)
    103. {/* WRITE 28-BIT FREQUENCE */
    104.     uint32_t freq_reg;
    105.     uint16_t reg_reg;
    106.     freq_reg = AD_FREQ_CALC(freq);
    107.     ad_settings2.freq[reg] = freq;
    108.     if (reg==1)
    109.         reg_reg = WRITE_TO_FREQ1_REG;
    110.     else
    111.         reg_reg = WRITE_TO_FREQ0_REG;
    112.  
    113.     GPIO_ResetBits(GPIOE, GPIO_Pin_7);
    114.     delay(0xFFF);
    115.     AD9833_write((1<<AD_B28) | ad_settings.command_reg);
    116.     AD9833_word(reg_reg | (0x3FFF&(uint16_t)(freq_reg>>2 )));
    117.     AD9833_word(reg_reg | (0x3FFF&(uint16_t)(freq_reg>>16)));
    118.     delay(0xFFF);
    119.     GPIO_SetBits(GPIOE, GPIO_Pin_7);
    120. }
    121.  
    122.  
    123. void AD9833_setMode(uint8_t mode)
    124. {
    125.  
    126.     ad_settings.mode = mode;
    127.     switch(mode)
    128.     {
    129.  
    130.             case AD_OFF:
    131.                 ad_settings.command_reg |= (1<<AD_SLEEP12);
    132.                 ad_settings.command_reg |= (1<<AD_SLEEP1);
    133.                 break;
    134.             case AD_TRIANGLE:
    135.                 ad_settings.command_reg &= ~(1<<AD_OPBITEN);
    136.                 ad_settings.command_reg |=  (1<<AD_MODE);
    137.                 ad_settings.command_reg &= ~(1<<AD_SLEEP12);
    138.                 ad_settings.command_reg &= ~(1<<AD_SLEEP1);
    139.                 break;
    140.             case AD_SQUARE:
    141.                 ad_settings.command_reg |=  (1<<AD_OPBITEN);
    142.                 ad_settings.command_reg &= ~(1<<AD_MODE);
    143.                 ad_settings.command_reg |=  (1<<AD_DIV2);
    144.                 ad_settings.command_reg &= ~(1<<AD_SLEEP12);
    145.                 ad_settings.command_reg &= ~(1<<AD_SLEEP1);
    146.                 break;
    147.             case AD_SINE:
    148.                 ad_settings.command_reg &= ~(1<<AD_OPBITEN);
    149.                 ad_settings.command_reg &= ~(1<<AD_MODE);
    150.                 ad_settings.command_reg &= ~(1<<AD_SLEEP12);
    151.                 ad_settings.command_reg &= ~(1<<AD_SLEEP1);
    152.                 break;
    153.     }
    154.  
    155.     AD9833_write(ad_settings.command_reg); // Send selected MODE to AD9833
    156. }
    157.  
    158.  
    159. void init_SPI1(void)
    160.   {
    161.  
    162.         GPIO_InitTypeDef GPIO_InitStruct;
    163.         SPI_InitTypeDef SPI_InitStruct;
    164.  
    165.  
    166.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    167.         /* configure pins used by SPI1
    168.          * PA5 = SCK
    169.          * PA6 = MISO
    170.          * PA7 = MOSI
    171.          */
    172.         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_5;
    173.         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    174.         GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    175.         GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    176.         GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    177.         GPIO_Init(GPIOA, &GPIO_InitStruct);
    178.  
    179.         // connect SPI1 pins to SPI alternate function
    180.         GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
    181.         GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
    182.  
    183.         // enable clock for used IO pins
    184.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
    185.  
    186.         /* Configure the chip select pin
    187.            in this case we will use PE7 */
    188.         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
    189.         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    190.         GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    191.         GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    192.         GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    193.         GPIO_Init(GPIOE, &GPIO_InitStruct);
    194.  
    195.         GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 high
    196.  
    197.         // enable peripheral clock
    198.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    199.  
    200.         /* configure SPI1 in Mode 0
    201.          * CPOL = 1 --> clock is high when idle
    202.          * CPHA = 0 --> data is sampled at the first edge
    203.          */
    204.         SPI_InitStruct.SPI_Direction = SPI_Direction_1Line_Tx;
    205.         SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has to be always high
    206.         SPI_InitStruct.SPI_DataSize = SPI_DataSize_16b; // one packet of data is 8 bits wide
    207.         SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;        // clock is low when idle
    208.         SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
    209.         SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
    210.         SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // SPI frequency is APB2 frequency / 4
    211.         SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
    212.         SPI_Init(SPI1, &SPI_InitStruct);
    213.  
    214.         SPI_Cmd(SPI1, ENABLE); // enable SPI1
    215.     }
    216.  
    217. int main(void) {
    218.  
    219.     init_SPI1();
    220.     CONTROL_REGISTER |= (1<<AD_B28)|(1<<AD_RESET)|(1<<AD_DIV2);
    221.     AD9833_write(CONTROL_REGISTER);
    222.  
    223.     AD9833_setFreq(0, 1000);
    224.     ad9833_setPhase(0, 0);
    225.     AD9833_setMode(AD_TRIANGLE);
    226.     while(1){
    227.  
    228.     }
    229. }
    230.  
    In this code, I was able to generate the desired signals but I can't change the frequency or the phase. The signals are always in the same frequency. What do you think is wrong and how can it be fixed. Thanks a lot.

    Edit:
    I realized when AD9833_setMode() is written above of AD9833_setFreq() and AD9833_setPhase() in the main part, I get a sinusoidal signal whether I chose the mode to be square or triangular. I couldn't understand why or if it is important but I wanted to let you know.
     
    Last edited: Nov 20, 2014
  4. solijoli

    Thread Starter New Member

    Nov 20, 2014
    3
    0
    So is there anyone who can tell why the frequency and phase can't change? This is my current code:
    Code (Text):
    1.  
    2. #include "stm32f4xx.h"
    3. #include "stm32f4xx_rcc.h"
    4. #include "stm32f4xx_gpio.h"
    5. #include "stm32f4xx_spi.h"
    6.  
    7.  
    8. #define AD_F_MCLK 25000000 //Clock speed of the ad9833 reference clock
    9. #define AD_2POW28 268435456 //used in calculating output freq
    10. #define AD_FREQ_CALC(freq) (uint32_t)(((double)AD_2POW28/(double)AD_F_MCLK*freq))
    11. #define AD_PHASE_CALC(phase_deg) (uint16_t)((4096*phase_deg)/360)
    12. static uint16_t CONTROL_REGISTER;
    13.  
    14.  
    15. #define WRITE_TO_FREQ1_REG         0x8000
    16. #define WRITE_TO_FREQ0_REG         0x4000
    17. #define WRITE_TO_PHASE1_REG         0xE000
    18. #define WRITE_TO_PHASE0_REG         0xC000
    19.  
    20. #define AD_B28     13
    21. #define AD_HLB     12
    22. #define AD_FSELECT 11
    23. #define AD_PSELECT 10
    24. #define AD_RESET   8
    25. #define AD_SLEEP1  7
    26. #define AD_SLEEP12 6
    27. #define AD_OPBITEN 5
    28. #define AD_DIV2    3
    29. #define AD_MODE    1
    30.  
    31. #define AD_OFF      0
    32. #define AD_TRIANGLE 1
    33. #define AD_SQUARE   2
    34. #define AD_SINE     3
    35.  
    36.  
    37. typedef struct {
    38. uint8_t  freq_out;
    39. uint8_t  phase_out;
    40. uint8_t  mode;
    41. uint16_t command_reg;
    42. } ad9833_settings_t;
    43.  
    44. typedef struct {
    45.     float    freq[2];
    46.     float    phase[2];
    47. } ad9833_settings_f;
    48.  
    49.  
    50. ad9833_settings_t ad_settings;
    51. ad9833_settings_f ad_settings2;
    52.  
    53.  
    54. void delay(__IO uint32_t nCount)
    55. {
    56.   while(nCount--)
    57.   {
    58.   }
    59. }
    60.  
    61.  
    62. static void AD9833_word(uint16_t data)
    63. {
    64.     SPI1->DR = (data>>8); // High 8 bits, MSB first
    65.     while(!(SPI1->SR & SPI_I2S_FLAG_TXE));
    66.     while( SPI1->SR & SPI_I2S_FLAG_BSY );
    67.     SPI1->DR = (uint8_t) data; // Low 8 bits
    68.     while(!(SPI1->SR & SPI_I2S_FLAG_TXE));
    69.     while( SPI1->SR & SPI_I2S_FLAG_BSY );
    70. }
    71.  
    72. static void AD9833_write(uint16_t data)
    73. {
    74.     GPIO_ResetBits(GPIOE, GPIO_Pin_7);
    75.     delay(0xFFF);
    76.     AD9833_word(data);
    77.     delay(0xFFF);
    78.     GPIO_SetBits(GPIOE, GPIO_Pin_7);
    79.     delay(0xFFF);
    80. }
    81.  
    82. void AD9833_setPhase(uint8_t reg, double phase){
    83.     uint16_t reg_reg;
    84.     if (reg==1)
    85.         reg_reg = WRITE_TO_PHASE1_REG;
    86.     else
    87.         reg_reg = WRITE_TO_PHASE0_REG;
    88.  
    89.     ad_settings2.phase[reg] = phase;
    90.  
    91.     GPIO_ResetBits(GPIOE, GPIO_Pin_7);
    92.     delay(0xFFF);
    93.     AD9833_word(reg_reg | AD_PHASE_CALC(ad_settings2.phase[reg]));
    94.     delay(0xFFF);
    95.     GPIO_SetBits(GPIOE, GPIO_Pin_7);
    96. }
    97.  
    98. void AD9833_setPhaseOut(uint8_t phase_out){
    99.     ad_settings.phase_out = phase_out;
    100.     switch (phase_out){
    101.         case 0:
    102.             ad_settings.command_reg &= ~(1<<AD_PSELECT);
    103.             break;
    104.         case 1:
    105.             ad_settings.command_reg |= (1<<AD_PSELECT);
    106.             break;
    107.         case 2:
    108.             //TODO
    109.             break;
    110.     }
    111.  
    112.     AD9833_write(ad_settings.command_reg);
    113.  
    114. }
    115.  
    116. void AD9833_setFreq(uint8_t reg, double freq)
    117. {/* WRITE 28-BIT FREQUENCE */
    118.     uint32_t freq_reg;
    119.     uint16_t reg_reg;
    120.     freq_reg = AD_FREQ_CALC(freq);
    121.     ad_settings2.freq[reg] = freq;
    122.     if (reg==1)
    123.         reg_reg = WRITE_TO_FREQ1_REG;
    124.     else
    125.         reg_reg = WRITE_TO_FREQ0_REG;
    126.  
    127.     GPIO_ResetBits(GPIOE, GPIO_Pin_7);
    128.     delay(0xFFF);
    129.     //AD9833_word((1<<AD_B28) | ad_settings.command_reg);
    130.     AD9833_word(reg_reg | (0x3FFF & (uint16_t) (freq_reg)));
    131.     AD9833_word(reg_reg | (0x3FFF & (uint16_t) (freq_reg>>14)));
    132.     delay(0xFFF);
    133.     GPIO_SetBits(GPIOE, GPIO_Pin_7);
    134. }
    135.  
    136. void AD9833_setFreqOut(uint8_t freq_out){
    137.     ad_settings.freq_out = freq_out;
    138.     switch (freq_out){
    139.         case 0:
    140.             ad_settings.command_reg &= ~(1<<AD_FSELECT);
    141.             break;
    142.         case 1:
    143.             ad_settings.command_reg |= (1<<AD_FSELECT);
    144.             break;
    145.         case 2:
    146.             //TODO
    147.             break;
    148.     }
    149.     AD9833_write(ad_settings.command_reg);
    150.  
    151. }
    152.  
    153.  
    154. void AD9833_setMode(uint8_t mode)
    155. {
    156.  
    157.     ad_settings.mode = mode;
    158.     switch(mode)
    159.     {
    160.  
    161.             case AD_OFF:
    162.                 ad_settings.command_reg |= (1<<AD_SLEEP12);
    163.                 ad_settings.command_reg |= (1<<AD_SLEEP1);
    164.                 break;
    165.             case AD_TRIANGLE:
    166.                 ad_settings.command_reg &= ~(1<<AD_OPBITEN);
    167.                 ad_settings.command_reg |=  (1<<AD_MODE);
    168.                 ad_settings.command_reg &= ~(1<<AD_SLEEP12);
    169.                 ad_settings.command_reg &= ~(1<<AD_SLEEP1);
    170.                 break;
    171.             case AD_SQUARE:
    172.                 ad_settings.command_reg |=  (1<<AD_OPBITEN);
    173.                 ad_settings.command_reg &= ~(1<<AD_MODE);
    174.                 ad_settings.command_reg |=  (1<<AD_DIV2);
    175.                 ad_settings.command_reg &= ~(1<<AD_SLEEP12);
    176.                 ad_settings.command_reg &= ~(1<<AD_SLEEP1);
    177.                 break;
    178.             case AD_SINE:
    179.                 ad_settings.command_reg &= ~(1<<AD_OPBITEN);
    180.                 ad_settings.command_reg &= ~(1<<AD_MODE);
    181.                 ad_settings.command_reg &= ~(1<<AD_SLEEP12);
    182.                 ad_settings.command_reg &= ~(1<<AD_SLEEP1);
    183.                 break;
    184.     }
    185.  
    186.     AD9833_write(ad_settings.command_reg); // Send selected MODE to AD9833
    187. }
    188.  
    189.  
    190. void init_SPI1(void)
    191.   {
    192.  
    193.         GPIO_InitTypeDef GPIO_InitStruct;
    194.         SPI_InitTypeDef SPI_InitStruct;
    195.  
    196.  
    197.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    198.         /* configure pins used by SPI1
    199.          * PA5 = SCK
    200.          * PA6 = MISO
    201.          * PA7 = MOSI
    202.          */
    203.         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_5;
    204.         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    205.         GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    206.         GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    207.         GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    208.         GPIO_Init(GPIOA, &GPIO_InitStruct);
    209.  
    210.         // connect SPI1 pins to SPI alternate function
    211.         GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
    212.         GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
    213.  
    214.         // enable clock for used IO pins
    215.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
    216.  
    217.         /* Configure the chip select pin
    218.            in this case we will use PE7 */
    219.         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
    220.         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    221.         GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    222.         GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    223.         GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    224.         GPIO_Init(GPIOE, &GPIO_InitStruct);
    225.  
    226.         GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 high
    227.  
    228.         // enable peripheral clock
    229.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    230.  
    231.         /* configure SPI1 in Mode 0
    232.          * CPOL = 1 --> clock is high when idle
    233.          * CPHA = 0 --> data is sampled at the first edge
    234.          */
    235.         SPI_InitStruct.SPI_Direction = SPI_Direction_1Line_Tx;
    236.         SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has to be always high
    237.         SPI_InitStruct.SPI_DataSize = SPI_DataSize_16b; // one packet of data is 8 bits wide
    238.         SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;        // clock is low when idle
    239.         SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
    240.         SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
    241.         SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // SPI frequency is APB2 frequency / 4
    242.         SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
    243.         SPI_Init(SPI1, &SPI_InitStruct);
    244.  
    245.         SPI_Cmd(SPI1, ENABLE); // enable SPI1
    246.     }
    247.  
    248.  
    249.  
    250. int main(void) {
    251.  
    252.     init_SPI1();
    253.     CONTROL_REGISTER |= (1<<AD_B28)|(1<<AD_RESET)|(1<<AD_DIV2);
    254.     AD9833_write(CONTROL_REGISTER);
    255.  
    256.     AD9833_setPhase(0, 1);
    257.     AD9833_setPhaseOut(0);
    258.     AD9833_setFreq(0, 1000);
    259.     AD9833_setFreqOut(0);
    260.     AD9833_setMode(AD_SQUARE);
    261.  
    262.     while(1){
    263.     }
    264. }
    265.  
    I really appreciate the help!
     
Loading...