永发信息网

AD9833产生三角波的问题

答案:4  悬赏:40  手机版
解决时间 2021-02-24 03:23
  • 提问者网友:锁深秋
  • 2021-02-23 09:50
我用AD9833产生正弦波时能实现,但是想让它产生三角波时实现不了。产生三角波时,我通过FPGA向AD9833写入六组数据,分别是:0100H(将所有寄存器复位为0),2000H(将频率寄存器设置成为完整28位使用),5894H(将频率控制字的低14位写入频率寄存器0),4010H(将频率寄存器的高14位写入频率寄存器0),D000H(将相位字写入相位寄存器0),0002H(设置频率寄存器0和相位寄存器有效,禁止复位,使用MCLK,激活DAC输出,直接输出三角波)。但是将这6组数据依次写进AD9833后,AD9833产生的是正弦波,是不是我写入AD9833的控制字不对还是是什么可能的原因呢?希望高人指点!
最佳答案
  • 五星知识达人网友:从此江山别
  • 2021-02-23 10:19
有可能是你的负载上有电容,你断开其他的电路,直接去测量AD9833的输出脚就可以了,下面是一个例程,工参考
#include "head.h"
#include "cpu.h"
#include "AD9833.h"
//定义延时变量,用于宏AD9833_Delay()()
UNCHAR AD9833_delay_t;


#define AD9833_Delay()\
{\
AD9833_delay_t = (AD9833_Delay_Value);\
while ( --AD9833_delay_t!= 0 );\
}

void Delay_N_MCLK(UNCHAR N)
{
UNCHAR i,t;
for(i=0;i<=N;i++)
{
AD9833_SCLK = 1;
for(t=0;t<20;t++);
AD9833_SCLK = ~AD9833_SCLK;
for(t=0;t<20;t++);
}
}

//AD9833_16 表示写入的信息,Which_AD9833 表示写入哪个AD9833;
void Write_16bit_One(UNCHAR Char_1,UNCHAR Char_2, UNCHAR Which_AD9833_CS)
{
UNCHAR i,t;
AD9833_SCLK = 1;
switch(Which_AD9833_CS) //确定片选
{
case 1:
P1=~0x80; break;
case 2:
P1=~0x40; break;
case 3:
P1=~0x20; break;
case 4:
P1=~0x10; break;
case 5:
P1=~0x08; break;
case 6:
P1=~0x04; break;
default:
P1=~0x00; break;
}
for(i=0;i<8;i++) //对于确定次数的循环建议使用for()结构
{
if((Char_1<<i) &0x80)//确定SDATA上的数据
{
AD9833_SDATA = 1;
}
else
{
AD9833_SDATA = 0;
}
AD9833_SCLK = 0;
for(t=0;t<20;t++);
AD9833_SCLK = ~AD9833_SCLK;//在下降沿写?AD9833_Delay();
//_nop_(); AD9833_Delay();
for(t=0;t<10;t++);
}
for(i=0;i<8;i++) //对于确定次数的循环建议使用for()结构
{
if((Char_2<<i) &0x80)//确定SDATA上的数据
{
AD9833_SDATA = 1;
}
else
{
AD9833_SDATA = 0;
}
AD9833_SCLK = 0;
for(t=0;t<20;t++);
AD9833_SCLK = ~AD9833_SCLK;//在下降沿写?AD9833_Delay();
//_nop_(); AD9833_Delay();
for(t=0;t<10;t++);
}
P1 = 0xff;
}

void Write_16bit_All(UNINT AD9833_16_Data)
{
UNCHAR t,i;
i = 8;
AD9833_SCLK = 1;
P1 = 0xff; //片选
P1 = 0x03;
for(i=0;i<16;i++) //对于确定次数的循环建议使用for()结构
{
if((AD9833_16_Data<<i) &0x8000)//确定SDATA上的数据
{
AD9833_SDATA = 1;
}
else
{
AD9833_SDATA = 0;
}
AD9833_SCLK = 0;
for(t=0;t<20;t++);
AD9833_SCLK = ~AD9833_SCLK;//在下降沿写?AD9833_Delay();
//_nop_(); AD9833_Delay();
for(t=0;t<10;t++);
while (--t != 0);
}
P1 = 0xff; //片选拉高
Delay_N_MCLK(8);
}

//主要实现控制寄存器的D8位的RESET 置1,使得内部所有寄存器
//初始化为频率为50,相位移为0
void AD9833_Init(void)
{
Write_16bit_All_Two(0x21,0x00); //RESET=1,
//Write_28bit_One_FR(1, 0, 0x4000,0x0000 );//改FREG0
//AD9833_50HZ_0Ps_Init();//初始化为标准三相电源
Write_16bit_All_Two(0x00,0x00); //RESET=0,
}

//初始化为频率为50,相位移为0
void AD9833_50HZ_0Ps_Init(void)
{
Write_28bit_One_FR(1, 0, 0x6a,0x40,0x40,0x13 );//改FREG0
Write_28bit_One_FR(1, 1, 0xaa,0x40,0x80,0x13);//改FREG1
Write_12bit_One_PR(1, 0, 0, 0,0);//改PREG0
Write_12bit_One_PR(1, 1, 0, 0,0);//改PREG1
}

//if_to_all 0:表示写向单个AD9833;--1:表示写向所有AD9833;
//Phase_0_or_1 表示写向哪一个相位寄存器--0:表示写向pREQ0-- 1:表示写向pREQ1
//Phase_12_Data: 表示相位信息;
//Which_AD9833_CS: 若if_to_all=0, 则使用该变量表示写向哪个AD9833
void Write_12bit_One_PR(bit If_to_all, bit Phase_0_or_1, UNCHAR Char_1,UNCHAR
Char_2,UNCHAR Which_AD9833_CS)
{
UNINT word_12;
if (Phase_0_or_1 == 1)//确定写入的14位信息
word_12= Char_1 |0xE0; //写向PREQ1
else
word_12= Char_1 |0xC0; //写向PREQ0
if (If_to_all == 1) //写动作
{//写向所有的AD9833
Write_16bit_All_Two(word_12,Char_2);
}
else //写向单个的AD9833
{
Write_16bit_One(word_12,Char_2,Which_AD9833_CS);
}
}

//Msbs_or_Lsbs 0:表示写向单个AD9833的LSBs; 1:表示写向所有
AD9833的MSBs;
//If_to_All 0: 表示写向单个AD9833; 1: 表示写向所有
AD9833;
//FREQ0_or_1 0:表示写向FREQ0 1:表示写向FREQ1
//Msbs_or_Lsbs_14_Data : 表示要写入的内容
//Which_AD9833_CS : 如果If_to_All=0, 则使用该变量表示写向哪个
AD9833
void Write_14bit_One_FR( bit Msbs_or_Lsbs, bit If_to_All,UNCHAR
FREQ0_or_1,UNCHAR Char_1,UNCHAR Char_2,UNCHAR Which_AD9833_CS)
{
UNCHAR word_14_h,control_word_h,control_word_l;
if (FREQ0_or_1 == 1) //确定写入的14位信息
{ //写向FREQ1
word_14_h= Char_1 |0x80;
}
else //写向FREQ0
{
word_14_h= Char_2 |0x40;
}
if(Msbs_or_Lsbs == 1) //确定控制寄存器的内容
{// 1:表示写向所有AD9833的MSBs;
control_word_h= 0x10 ;
control_word_l = 0x00;
}
else
{ // 0:表示写向单个AD9833的LSBs;
control_word_h= 0x00 ;
control_word_l = 0x00;
}
if (If_to_All == 1) //写动作
{ //写向所有的AD9833
Write_16bit_All_Two(0x20,0x00);
Write_16bit_All_Two(word_14_h,Char_2);
}
else //写向单个的AD9833
{
Write_16bit_One(0x20,0x00, Which_AD9833_CS);
Write_16bit_One(word_14_h,Char_2, Which_AD9833_CS);
}
}

//if_to_all 0:表示写向单个AD9833; 1:表示写向所有
AD9833;
//FREQ0_or_1 0:表示写向FREQ0 1:表示写向
FREQ1
void Write_28bit_One_FR(bit If_to_all, UNCHAR FREQ0_or_1, UNCHAR
low_14_h,UNCHAR low_14_l,UNCHAR high_14_h,UNCHAR high_14_l)
{
if (If_to_all==1) //写动作
{ //写向所有的AD9833
Write_16bit_All_Two(0x20,0x00);
Write_16bit_All_Two(low_14_h,low_14_l);
Write_16bit_All_Two(high_14_h,high_14_l);
}
else
{ //写向单个的AD9833
Write_16bit_One(0x20,0x00, FREQ0_or_1);
Write_16bit_One(low_14_h,low_14_l, FREQ0_or_1);
Write_16bit_One(high_14_h,high_14_l, FREQ0_or_1);
}
}
////////////////////替代void Write_16bit_All(UNINT AD9833_16_Data),
//,一下函数可以用
void Write_16bit_All_Two(UNCHAR Char_1,UNCHAR Char_2)
{
UNCHAR t,i;
i = 8;
AD9833_SCLK = 1;
P1 = 0xff; //片选
P1 = 0x03;

for(i=0;i<8;i++) //对于确定次数的循环建议使用for()结构
{// _nop_();
if((Char_1<<i) &0x80)//确定SDATA上的数据
{
AD9833_SDATA = 1;
}
else
{
AD9833_SDATA = 0;
}
AD9833_SCLK = 0;
for(t=0;t<20;t++);
AD9833_SCLK = ~AD9833_SCLK;//在下降沿写?AD9833_Delay();
//_nop_(); AD9833_Delay();
for(t=0;t<10;t++);
}
for(i=0;i<8;i++) //对于确定次数的循环建议使用for()结构
{
if((Char_2<<i) &0x80)//确定SDATA上的数据
{
AD9833_SDATA = 1;
}
else
{
AD9833_SDATA = 0;
}
AD9833_SCLK = 0;
for(t=0;t<20;t++);
AD9833_SCLK = ~AD9833_SCLK;//在下降沿写?AD9833_Delay();
//_nop_(); AD9833_Delay();
for(t=0;t<10;t++);
}
P1 = 0xff; //片选拉高
Delay_N_MCLK(8);
}
全部回答
  • 1楼网友:一袍清酒付
  • 2021-02-23 13:24
sf
  • 2楼网友:洒脱疯子
  • 2021-02-23 12:40
不会是烧了吧,都超过5v了!~
  • 3楼网友:想偏头吻你
  • 2021-02-23 11:41
有可能是你的负载上有电容,你断开其他的电路,直接去测量AD9833的输出脚就可以了,下面是一个例程,工参考 #include "head.h" #include "cpu.h" #include "AD9833.h" //定义延时变量,用于宏AD9833_Delay()() UNCHAR AD9833_delay_t; #define AD9833_Delay()\ {\ AD9833_delay_t = (AD9833_Delay_Value);\ while ( --AD9833_delay_t!= 0 );\ } void Delay_N_MCLK(UNCHAR N) { UNCHAR i,t; for(i=0;i<=N;i++) { AD9833_SCLK = 1; for(t=0;t<20;t++); AD9833_SCLK = ~AD9833_SCLK; for(t=0;t<20;t++); } } //AD9833_16 表示写入的信息,Which_AD9833 表示写入哪个AD9833; void Write_16bit_One(UNCHAR Char_1,UNCHAR Char_2, UNCHAR Which_AD9833_CS) { UNCHAR i,t; AD9833_SCLK = 1; switch(Which_AD9833_CS) //确定片选 { case 1: P1=~0x80; break; case 2: P1=~0x40; break; case 3: P1=~0x20; break; case 4: P1=~0x10; break; case 5: P1=~0x08; break; case 6: P1=~0x04; break; default: P1=~0x00; break; } for(i=0;i<8;i++) //对于确定次数的循环建议使用for()结构 { if((Char_1<<i) &0x80)//确定SDATA上的数据 { AD9833_SDATA = 1; } else { AD9833_SDATA = 0; } AD9833_SCLK = 0; for(t=0;t<20;t++); AD9833_SCLK = ~AD9833_SCLK;//在下降沿写?AD9833_Delay(); //_nop_(); AD9833_Delay(); for(t=0;t<10;t++); } for(i=0;i<8;i++) //对于确定次数的循环建议使用for()结构 { if((Char_2<<i) &0x80)//确定SDATA上的数据 { AD9833_SDATA = 1; } else { AD9833_SDATA = 0; } AD9833_SCLK = 0; for(t=0;t<20;t++); AD9833_SCLK = ~AD9833_SCLK;//在下降沿写?AD9833_Delay(); //_nop_(); AD9833_Delay(); for(t=0;t<10;t++); } P1 = 0xff; } void Write_16bit_All(UNINT AD9833_16_Data) { UNCHAR t,i; i = 8; AD9833_SCLK = 1; P1 = 0xff; //片选 P1 = 0x03; for(i=0;i<16;i++) //对于确定次数的循环建议使用for()结构 { if((AD9833_16_Data<<i) &0x8000)//确定SDATA上的数据 { AD9833_SDATA = 1; } else { AD9833_SDATA = 0; } AD9833_SCLK = 0; for(t=0;t<20;t++); AD9833_SCLK = ~AD9833_SCLK;//在下降沿写?AD9833_Delay(); //_nop_(); AD9833_Delay(); for(t=0;t<10;t++); while (--t != 0); } P1 = 0xff; //片选拉高 Delay_N_MCLK(8); } //主要实现控制寄存器的D8位的RESET 置1,使得内部所有寄存器 //初始化为频率为50,相位移为0 void AD9833_Init(void) { Write_16bit_All_Two(0x21,0x00); //RESET=1, //Write_28bit_One_FR(1, 0, 0x4000,0x0000 );//改FREG0 //AD9833_50HZ_0Ps_Init();//初始化为标准三相电源 Write_16bit_All_Two(0x00,0x00); //RESET=0, } //初始化为频率为50,相位移为0 void AD9833_50HZ_0Ps_Init(void) { Write_28bit_One_FR(1, 0, 0x6a,0x40,0x40,0x13 );//改FREG0 Write_28bit_One_FR(1, 1, 0xaa,0x40,0x80,0x13);//改FREG1 Write_12bit_One_PR(1, 0, 0, 0,0);//改PREG0 Write_12bit_One_PR(1, 1, 0, 0,0);//改PREG1 } //if_to_all 0:表示写向单个AD9833;--1:表示写向所有AD9833; //Phase_0_or_1 表示写向哪一个相位寄存器--0:表示写向pREQ0-- 1:表示写向pREQ1 //Phase_12_Data: 表示相位信息; //Which_AD9833_CS: 若if_to_all=0, 则使用该变量表示写向哪个AD9833 void Write_12bit_One_PR(bit If_to_all, bit Phase_0_or_1, UNCHAR Char_1,UNCHAR Char_2,UNCHAR Which_AD9833_CS) { UNINT word_12; if (Phase_0_or_1 == 1)//确定写入的14位信息 word_12= Char_1 |0xE0; //写向PREQ1 else word_12= Char_1 |0xC0; //写向PREQ0 if (If_to_all == 1) //写动作 {//写向所有的AD9833 Write_16bit_All_Two(word_12,Char_2); } else //写向单个的AD9833 { Write_16bit_One(word_12,Char_2,Which_AD9833_CS); } } //Msbs_or_Lsbs 0:表示写向单个AD9833的LSBs; 1:表示写向所有 AD9833的MSBs; //If_to_All 0: 表示写向单个AD9833; 1: 表示写向所有 AD9833; //FREQ0_or_1 0:表示写向FREQ0 1:表示写向FREQ1 //Msbs_or_Lsbs_14_Data : 表示要写入的内容 //Which_AD9833_CS : 如果If_to_All=0, 则使用该变量表示写向哪个 AD9833 void Write_14bit_One_FR( bit Msbs_or_Lsbs, bit If_to_All,UNCHAR FREQ0_or_1,UNCHAR Char_1,UNCHAR Char_2,UNCHAR Which_AD9833_CS) { UNCHAR word_14_h,control_word_h,control_word_l; if (FREQ0_or_1 == 1) //确定写入的14位信息 { //写向FREQ1 word_14_h= Char_1 |0x80; } else //写向FREQ0 { word_14_h= Char_2 |0x40; } if(Msbs_or_Lsbs == 1) //确定控制寄存器的内容 {// 1:表示写向所有AD9833的MSBs; control_word_h= 0x10 ; control_word_l = 0x00; } else { // 0:表示写向单个AD9833的LSBs; control_word_h= 0x00 ; control_word_l = 0x00; } if (If_to_All == 1) //写动作 { //写向所有的AD9833 Write_16bit_All_Two(0x20,0x00); Write_16bit_All_Two(word_14_h,Char_2); } else //写向单个的AD9833 { Write_16bit_One(0x20,0x00, Which_AD9833_CS); Write_16bit_One(word_14_h,Char_2, Which_AD9833_CS); } } //if_to_all 0:表示写向单个AD9833; 1:表示写向所有 AD9833; //FREQ0_or_1 0:表示写向FREQ0 1:表示写向 FREQ1 void Write_28bit_One_FR(bit If_to_all, UNCHAR FREQ0_or_1, UNCHAR low_14_h,UNCHAR low_14_l,UNCHAR high_14_h,UNCHAR high_14_l) { if (If_to_all==1) //写动作 { //写向所有的AD9833 Write_16bit_All_Two(0x20,0x00); Write_16bit_All_Two(low_14_h,low_14_l); Write_16bit_All_Two(high_14_h,high_14_l); } else { //写向单个的AD9833 Write_16bit_One(0x20,0x00, FREQ0_or_1); Write_16bit_One(low_14_h,low_14_l, FREQ0_or_1); Write_16bit_One(high_14_h,high_14_l, FREQ0_or_1); } } ////////////////////替代void Write_16bit_All(UNINT AD9833_16_Data), //,一下函数可以用 void Write_16bit_All_Two(UNCHAR Char_1,UNCHAR Char_2) { UNCHAR t,i; i = 8; AD9833_SCLK = 1; P1 = 0xff; //片选 P1 = 0x03; for(i=0;i<8;i++) //对于确定次数的循环建议使用for()结构 {// _nop_(); if((Char_1<<i) &0x80)//确定SDATA上的数据 { AD9833_SDATA = 1; } else { AD9833_SDATA = 0; } AD9833_SCLK = 0; for(t=0;t<20;t++); AD9833_SCLK = ~AD9833_SCLK;//在下降沿写?AD9833_Delay(); //_nop_(); AD9833_Delay(); for(t=0;t<10;t++); } for(i=0;i<8;i++) //对于确定次数的循环建议使用for()结构 { if((Char_2<<i) &0x80)//确定SDATA上的数据 { AD9833_SDATA = 1; } else { AD9833_SDATA = 0; } AD9833_SCLK = 0; for(t=0;t<20;t++); AD9833_SCLK = ~AD9833_SCLK;//在下降沿写?AD9833_Delay(); //_nop_(); AD9833_Delay(); for(t=0;t<10;t++); } P1 = 0xff; //片选拉高 Delay_N_MCLK(8); }
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯