当前位置:   article > 正文

AD9833介绍与应用(C语言实现)

ad9833

1.特性

  • 低功耗、可编程波形发生器,能产生正弦波、三角波和方波的输出;

  • 主频时钟为25MHz时,可实现0.1Hz的分辨率;主频时钟为1MHz时,可实现0.004Hz的分辨率;

  • 三线式串行接口(SDATA、SCLK、FSYNC)写入数据,最高能以40MHz的时钟速率工作,支持SPI通信,一个输出信号接口(VOUT),输出信号没有负电压,输出最大电压值为650mv,输出最小电压值为38mv,不是为0;

  • 输出频率范围在0MHz至12.5MHz;

注意:方波输出的最大的电压值为供电电压值3.3V,并非650mv,其是作为时钟源使用。

2.引脚配置与功能描述

 

注意:MCLK是数字时钟输入,可接一个有源晶振,若直接连接到MCU上,可用PWM波或定时器去拉高拉低控制,但最好外接一个晶振,输出频率会受此时钟引脚的控制。

3.功能框图说明

 由功能框图可看出:

输入:AD9833的输入由FSYNC引脚、SCLK引脚、SDATA引脚来控制。

寄存器:AD9833有1个控制寄存器、两个频率寄存器、两个相位寄存器、1个相位累加器。

输出:VOUT输出波形主要根据10位DAC输出正弦波和三角波,或MSB直接输出以及MSB/2输出方波。

工作流程:通过FSYNC引脚、SCLK引脚、SDATA引脚对控制寄存器、频率寄存器、相位寄存器进行写入,频率寄存器中的值输入到相位累加器中,再与相位寄存器中的值来进行相位偏移,但输出会被截断至12位,并在SIN ROM中寻找相对应相位的DAC的值经过10DAC输出或MSB直接输出或MSB/2输出到VOUT上。

注意:MSB输出的是方波,是用作时钟源使用的,输出的是供电电压3.3V,MSB输出的时钟频率是MSB/2的两倍。

4.时序特性

 由时序图可看到:

  • MCLK的一个周期时间最小值为40ns,即时钟频率最大为25MHZ;

  • 进行串行数据传输是,先拉低FSYNC引脚,串行数据会在16个时钟脉冲的SCLK下降沿移入器件的输入移位寄存器中。注意FSYNC拉低后至SCLK拉低之间的建立时间为5ns。

  • 在FSYNC变为低电平时,SCLK必须为处于高电平。

5.寄存器及功能描述

5.1 频率和相位寄存器

        AD9833包含两个28位的频率寄存器和两个12位的相位寄存器:

5.2 控制寄存器

        AD9833包含一个16位的控制寄存器,可实现配置AD9833的操作,mode位之外的所有控制位均在MCLK的内部下降沿采样。

 

5.1.1 写入频率寄存器

        需将BIT D15和BIT D14设置为频率寄存器的地址,BIT D15和BIT D14设置为01,写入到频率寄存器0,BIT D15和BIT D14设置为10,写入到频率寄存器1。

         28位频率寄存器第一次写入包含14个LSB,第二次写入包含14个MSB。

        当更改频率寄存器全部内容时,需对同一个频率寄存器地址连续写入两次数据,此时需要将B28(D13)控制位置1.

        当只需更新频率寄存器的14个MSB或14个LSB时,将B28(D13)控制位置0,此时可单独更新频率寄存器的14个MSB或14个LSB,同时要将HLD(D12)这个位中确定要更新的具体14个位,HLD(D12)置0,即更新14个LSB,HLD(D12)置1,则更新14个MSB。

 5.1.2 写入相位寄存器​​​​​​​

        需将BIT D15和BIT D14设置为相位寄存器的地址,即将BIT D15和BIT D14设置为11,BIT D13确定将载入的相位寄存器,BIT D13置0时,写入到相位寄存器0,BIT D13置1时,写入到相位寄存器1,

 5.1.3 复位功能(D8控制)

        复位操作不会使相位、频率或控制寄存器复位,会使相应的内部寄存器复位为0。

        在AD9833上电时,器件应该复位一次。

        reset置0后的8个MCLK周期内,DAC输出端会出现信号。

 5.1.4 SLEEP功能

        可降低功耗。

5.1.5 VOUT输出

        VOUT输出包括DAC数据的MSB、正弦波输出或三角波输出。由OPBINTEN(D5)和mode(D1)bit控制。

6.C语言实现

6.1 ad9833.h文件

  1. #ifndef _AD9833_H
  2. #define _AD9833_H
  3. #include "sys.h"
  4. //AD9833 GPIO
  5. #define AD9833_SDATA PAout(7) //SDATA
  6. #define AD9833_SCLK   PAout(5) //SCLK
  7. #define AD9833_FSYNC PAout(4) //FSYNC
  8. /* WaveMode */
  9. #define AD9833_OUT_SINUS ((0 << 5) | (0 << 1) | (0 << 3))
  10. #define AD9833_OUT_TRIANGLE ((0 << 5) | (1 << 1) | (0 << 3))
  11. #define AD9833_OUT_MSB ((1 << 5) | (0 << 1) | (1 << 3))
  12. #define AD9833_OUT_MSB2 ((1 << 5) | (0 << 1) | (0 << 3))
  13. /* Registers */
  14. #define AD9833_REG_CMD (0 << 14)
  15. #define AD9833_REG_FREQ0 (1 << 14)
  16. #define AD9833_REG_FREQ1 (2 << 14)
  17. #define AD9833_REG_PHASE0 (6 << 13)
  18. #define AD9833_REG_PHASE1 (7 << 13)
  19. /* Command Control Bits */
  20. #define AD9833_B28 (1 << 13)
  21. #define AD9833_HLB (1 << 12)
  22. #define AD9833_FSEL0 (0 << 11)
  23. #define AD9833_FSEL1 (1 << 11)
  24. #define AD9833_PSEL0 (0 << 10)
  25. #define AD9833_PSEL1 (1 << 10)
  26. #define AD9833_PIN_SW (1 << 9)
  27. #define AD9833_RESET (1 << 8)
  28. #define AD9833_CLEAR_RESET (0 << 8)
  29. #define AD9833_SLEEP1 (1 << 7)
  30. #define AD9833_SLEEP12 (1 << 6)
  31. #define AD9833_OPBITEN (1 << 5)
  32. #define AD9833_SIGN_PIB (1 << 4)
  33. #define AD9833_DIV2 (1 << 3)
  34. #define AD9833_MODE (1 << 1)
  35. void AD9833_Init(void);
  36. static void AD9833_Delay(void);
  37. void AD9833_WriteData(u16 txdata);
  38. void AD9833_SetFrequency(unsigned short reg, double fout);
  39. void AD9833_SetPhase(unsigned short reg, unsigned short val);
  40. void AD9833_SetWave(unsigned int WaveMode,unsigned int Freq_SFR,unsigned int Phase_SFR);
  41. void AD9833_Setup(unsigned int Freq_SFR,double Freq,unsigned int Phase_SFR,unsigned int Phase,unsigned int WaveMode);
  42. #endif

6.2 ad9833.c文件

  1. #include "ad9833.h"
  2. /**************************************
  3. * 函 数 名: ad9833_init
  4. * 功能说明: ad9833初始化
  5. * 形   参: 无
  6. * 返 回 值: 无
  7. *************************************/
  8. void AD9833_Init(void)
  9. {
  10. GPIO_InitTypeDef GPIO_InitStructure;
  11. RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA,ENABLE );;
  12. GPIO_InitStructure.GPIO_Pin =GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_7;
  13. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出
  14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  15. GPIO_Init(GPIOA, &GPIO_InitStructure);
  16. GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7);
  17. }
  18. /**************************************
  19. * 函 数 名: AD9833_Delay
  20. * 功能说明: ad9833延迟
  21. * 形   参: 无
  22. * 返 回 值: 无
  23. *************************************/
  24. static void AD9833_Delay(void)
  25. {
  26. uint16_t i;
  27. for (i = 0; i < 1; i++);
  28. }
  29. /**************************************
  30. * 函 数 名: ad9833_write_data
  31. * 功能说明: ad9833写入16位数据
  32. * 形   参: txdata:待写入的16位数据
  33. * 返 回 值: 无
  34. *************************************/
  35. void AD9833_WriteData(u16 txdata)
  36. {
  37. int i;
  38. AD9833_SCLK=1;
  39. AD9833_FSYNC=1;
  40. AD9833_FSYNC=0;
  41. //16位数据
  42. for(i=0;i<16;i++)
  43. {
  44. if (txdata & 0x8000)
  45. AD9833_SDATA=1;
  46. else
  47. AD9833_SDATA=0;
  48. AD9833_Delay();
  49. AD9833_SCLK=0;
  50. AD9833_Delay();
  51. AD9833_SCLK=1;
  52. txdata<<=1;
  53. }
  54. AD9833_FSYNC=1;
  55. }
  56. /**************************************
  57. * 函 数 名: AD9833_SetFrequency
  58. * 功能说明: ad9833设置频率寄存器
  59. * 形   参: reg:待写入的频率寄存器
  60. fout:频率值
  61. * 返 回 值: 无
  62. *************************************/
  63. void AD9833_SetFrequency(unsigned short reg, double fout)
  64. {
  65. int frequence_LSB,frequence_MSB;
  66. double   frequence_mid,frequence_DATA;
  67. long int frequence_hex;
  68. /*********************************计算频率的16进制值***********************************/
  69. frequence_mid=268435456/25;//适合25M晶振
  70. //如果时钟频率不为25MHZ,修改该处的频率值,单位MHz ,AD9833最大支持25MHz
  71. frequence_DATA=fout;
  72. frequence_DATA=frequence_DATA/1000000;
  73. frequence_DATA=frequence_DATA*frequence_mid;
  74. frequence_hex=frequence_DATA; //这个frequence_hex的值是32位的一个很大的数字,需要拆分成两个14位进行处理;
  75. frequence_LSB=frequence_hex; //frequence_hex低16位送给frequence_LSB
  76. frequence_LSB=frequence_LSB&0x3fff;//去除最高两位,16位数换去掉高位后变成了14
  77. frequence_MSB=frequence_hex>>14; //frequence_hex高16位送给frequence_HSB
  78. frequence_MSB=frequence_MSB&0x3fff;//去除最高两位,16位数换去掉高位后变成了14
  79. frequence_LSB=frequence_LSB|reg;
  80. frequence_MSB=frequence_MSB|reg;
  81. AD9833_WriteData(0x2100); //选择数据一次写入,B28位和RESET位为1
  82. AD9833_WriteData(frequence_LSB);
  83. AD9833_WriteData(frequence_MSB);
  84. }
  85. /**************************************
  86. * 函 数 名: ad9833_write_data
  87. * 功能说明: ad9833设置相位寄存器
  88. * 形   参: reg:待写入的相位寄存器
  89. fout:相位值
  90. * 返 回 值: 无
  91. *************************************/
  92. void AD9833_SetPhase(unsigned short reg, unsigned short val)
  93. {
  94. unsigned short phase = reg;
  95. phase |= val;
  96. AD9833_WriteData(phase);
  97. }
  98. /**************************************
  99. * 函 数 名: AD9833_SetWave
  100. * 功能说明: ad9833设置波形
  101. * 形   参: WaveMode:输出波形类型
  102. Freq_SFR:输出的频率寄存器类型
  103. Phase_SFR:输出的相位寄存器类型
  104. * 返 回 值: 无
  105. *************************************/
  106. void AD9833_SetWave(unsigned int WaveMode,unsigned int Freq_SFR,unsigned int Phase_SFR)
  107. {
  108. unsigned int val = 0;
  109. val = (val | WaveMode | Freq_SFR | Phase_SFR);
  110. AD9833_WriteData(val);
  111. }
  112. /**************************************
  113. * 函 数 名: AD9833_Setup
  114. * 功能说明: ad9833设置输出
  115. * 形   参: Freq_SFR:频率寄存器类型
  116. Freq :频率值
  117. Phase_SFR:相位寄存器类型
  118. Phase:相位值
  119. WaveMode:波形类型
  120. * 返 回 值: 无
  121. *************************************/
  122. void AD9833_Setup(unsigned int Freq_SFR,double Freq,unsigned int Phase_SFR,unsigned int Phase,unsigned int WaveMode)
  123. {
  124. unsigned int Fsel,Psel;
  125. AD9833_WriteData(0x0100); //复位AD9833,即RESET位为1
  126. AD9833_WriteData(0x2100); //选择数据一次写入,B28位和RESET位为1
  127. AD9833_SetFrequency(Freq_SFR,Freq);
  128. AD9833_SetPhase(Phase_SFR,Phase);
  129. if(Freq_SFR == AD9833_REG_FREQ0)
  130. {
  131. Fsel = AD9833_FSEL0;
  132. }
  133. else
  134. {
  135. Fsel = AD9833_FSEL1;
  136. }
  137. if(Phase_SFR == AD9833_REG_PHASE0)
  138. {
  139. Psel = AD9833_PSEL0;
  140. }
  141. else
  142. {
  143. Psel = AD9833_PSEL1;
  144. }
  145. AD9833_SetWave(WaveMode,Fsel,Psel);
  146. }

6.3 main.c文件

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "ad9833.h"
  5. int main(void)
  6. {
  7. u8 t=0;
  8. delay_init();   //延时函数初始化  
  9. uart_init(115200); //串口初始化为9600
  10. AD9833_Init();
  11. //输出三角波
  12. AD9833_Setup(AD9833_REG_FREQ0,10000.0,AD9833_REG_PHASE1,1024,AD9833_OUT_TRIANGLE);
  13. while(1)
  14. {
  15. printf("t:%d\n",t);
  16. delay_ms(500);
  17. t++;
  18. }
  19. }
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
  

闽ICP备14008679号