写在前面 --Fraay
大家好我又来了,本次带来的是AD9910模块的数据手册、使用方法详解,以及如何根据AD9910的原理进行编程,实现DDS的功能。这次文章可以说是对数据手册的一个整理,也是对我自己这一阶段学习的一个记录。
其实网上有现成的例程供各位参考,甚至只需要修改引脚便可使用,但是本着学习的态度,还是很有必要深入了解数据手册,并且对应着数据手册来看别人代码的底层,是如何控制相应寄存器来完成功能的。这也是可编程芯片的魅力所在吧!
硬件/软件准备
使用的是康威电子的AD9910模块,淘宝店有卖的,如图
这个板子300+的价格,工艺是十分精良的,有条件的可以入手一块;条件不够可以不买,仅仅来学习也是非常好的一个平台。
(千万不要试图自己用覆铜板做,因为会出现很多pcb布局布线的问题,导致失败。毕竟单独的AD9910芯片价格也在100+)
单片机我选择的是STM32ZET6,不过这个并不是必须的,只是因为我开发板恰好是这个型号的,控制这个模块只需要13个(大约)管脚就够了用万能的C8T6也可以实现。
软件我使用的是CUBEMX,我没有工程模板并且很懒CUBEMX有强大的代码自动配置功能,并且十分稳定不会出错,代码系统化,可维护性高,使用十分方便。
硬件介绍
如图
数据手册详述(部分功能)
AD9910的数据手册英文版一共65页,我学习的时候是硬啃的,现在好在有中文翻译版,我就按照中文版进行再次翻译成人话(我认为能被更好的理解的并表达方式)不过大家有时间还是应该多多训练阅读英文数据手册的能力。
总体概述
如图,说白了就是最多400M的模拟输出;串行/并行数据通信;扫频/扫幅等;应用领域:本振产生;雷达的线性调频chrip的生成等。
管脚
先跳过管脚的含义,因为管脚配置跟完成的功能息息相关,100+个管教很多都是可以固定配置死的,而且若详细描述各个管脚篇幅过长,所以在应用中讲配置管脚。
工作模式
重点来了,AD9910的四种工作模式由于篇幅的考虑,这次文章只记录最AD9910模块最实用的单频调制功能。
单频调制
说白了就是我直接通过32给他传数据,规定他的振幅/频率/相位,他按照我给的参数来输出相应的正弦波
原理
那我32把数据传给谁?
答案是8个内部编程寄存器Profile 0-7。
如何选择我要往那个寄存器里面读和写?
答案是利用外部引脚PROFILE[2:0]进行选择(这就是我之前说的在应用中讲管脚)
32在PROFILE输出000那就是选择profile0,001->profile1......
并且在下一个时钟上升沿自动更新profile0-7的数据
AD9910怎么计算输出的振幅/频率/相位?
如图,说白了就是f_sysclk平均分成2^32份,输出频率等于FTW *(f_sysclk / 2^32)
此处需要注意的是,FTW是32位的,但是他最多只能表示0-2^31-1这么多的数,因为奈奎斯特采样频率的限制,最多取1/2的f_sysclk才能还原信号。
如图,幅度和相位跟频率类似,这里的POW就相当于FTW,而ASF表示相对于满量程的比例因子,输出的幅度(14位ADC)即
(ASF/2^14)* 满量程输出的幅度
写到这基本单频调制模式的基础已经明了了具体步骤如下
配置管脚信息(32发控制字给dds)使模块为单频调制模式->给确定的profile0-7(任意一个即可,不过要和你FROFILE引脚配置的相符)寄存器写值->发送ioupdate信号更新数据->输出
通信协议
可以看出32必须要与dds通信才可以实现功能,因此就要涉及串行数据的传递(先不考虑并行接口的使用)
这一段话我们知道了通信包含写指令+写数据,指令包括地址+读写位,并且完成同i性能之后要更新ioupdate
上图是指令的具体格式
上图是相关的通信管脚
说白了就是先要复位ioreset,拉低cs,然后32模拟一个时钟,MSB/LSB传输,每当输出完成之后要ioupdate
这样看起来一点都不直观,那就说一点人话,贴底层发送代码
//======================八位发送程序================================
void txd_8bit(uchar txdat)
{
uchar i,sbt;
sbt=0x80;
SCLK=0;
for (i=0;i<8;i++)
{
if ((txdat & sbt)==0)
AD9910_SDIO=0;
else
AD9910_SDIO=1;
SCLK=1;
sbt=sbt>>1;
SCLK=0;
}
}
代码+时序图可以看到:首先sclk=0(空闲),0x80=1000_0000。8个循环内,把发送数组跟sbt相与看是否最高位是0(其他位肯定都为0)是的话就操作SDIO=0,否则SDIO=1,然后sclk拉高,数据成功发送,紧接着把sbt右移一位变成0100_0000判断tsdat第二位,进行发送。以此类推完成8位数组的发送,可见完全符合上图的通信协议
给谁通信?
搞明白传数据的流程之后,下面就要涉及到给谁传数据?
下面介绍一系列需要通信的寄存器
3个CRF寄存器
上图三张位于PDF的第50页,有兴趣的话可以看看
CRF我自己的理解就是先对AD9910进行一个模式的配置,不给参数,主要是决定他的初始化设置,具体每一位怎么配置,有什么功能,都在PDF的55页。这个表格太长了而且很详细,就不描述了.
但是我们通过这个表格可以知道,我要往0x00/01/02这三个地址依次写数据,回答了给谁通信的问题。
还是贴底层代码来看通信过程
//======================ad9910发送cfr控制字=======================
//crf1/2/3的值所代表的含义,在PDF55页有详细描述,根据配置需求来
//我这里用的值适应于单频调制功能
//uchar cfr1[]={0x00,0x40,0x00,0x00}; //cfr1
//uchar cfr2[]={0x01,0x00,0x00,0x00}; //cfr2
//const uchar cfr3[]={0x05,0x0F,0x41,0x32}; //cfr3 40M 输入时钟 25倍频 VC0=101
//ICP=001;
void Txcfr(void)
{
uchar m,k;
CS=0;
txd_8bit(0x00); //cfr1地址
for (m=0;m<4;m++)
txd_8bit(cfr1[m]);
CS=1;
for (k=0;k<10;k++);
CS=0;
txd_8bit(0x01); //cfr2地址
for (m=0;m<4;m++)
txd_8bit(cfr2[m]);
CS=1;
for (k=0;k<10;k++);
CS=0;
txd_8bit(0x02); //cfr3地址
for (m=0;m<4;m++)
txd_8bit(cfr3[m]);
CS=1;
for (k=0;k<10;k++);
UP_DAT=1;
for(k=0;k<10;k++);
UP_DAT=0;
delay_ms(1);
}
上图根据前面的内容不难理解,分别经历了片选cs,写命令,写数据,ioupdate操作。
Profile 0寄存器
把CRF配置好了之后,AD9910初始化也就成功了,已经进入单频调制功能了
接下来由于总体程序里面写了PROFILE1/2/3=0,即选中了profile0这个寄存器,所以就要往这个寄存器里面写数据
上图位profile0的描述,可以看到地址是0x0E,一共64个位,不同的位代表不同的意思,这个就是单频调制的参数选择,然后AD9910就会自动按照这个参数产生正弦波。
同样,贴底层
//===================设置频率===================//
void Freq_convert(ulong Freq)
{
ulong Temp;
if(Freq > 400000000)
Freq = 400000000;
Temp=(ulong)Freq*4.294967296; // 4.294967296=(2^32)/1000000000
// 把1G的内部时钟分为2^32份
profile0[7]=(uchar)Temp; //可以看到profile0在频率控制字一共有4个字节
profile0[6]=(uchar)(Temp>>8);//所以分四次发送
profile0[5]=(uchar)(Temp>>16);
profile0[4]=(uchar)(Temp>>24);
Txprofile();
}
//===================ad9910·发送profile0控制字======================
void Txprofile(void)
{
uchar m,k;
CS=0;
txd_8bit(0x0e); //profile0地址
for (m=0;m<8;m++)
txd_8bit(profile0[m]); //分8次把所有的profile0数据全发送出去
CS=1;
for(k=0;k<10;k++);//等待
UP_DAT=1;
for(k=0;k<10;k++);//等待
UP_DAT=0;
delay_ms(1);
}
上图只是写了设置频率的部分,设置幅度和相位同理。
把这些部分完成之后,AD9910就会以单频调制的模式输出固定参数的正弦波,也就达到了dds的基本功能,后面再接混频电路或者其他的设计都可以。
总结一下,单频调制的步骤发送cfr1/2/3->发送profile0
结尾
以上内容介绍了单频调制如何实现,并且讲解了底层最重要的代码的原理,希望大家看了之后会对代码完成的工作有个具体的认识。后面的RAM、DRG等功能可以参考数据手册的相关章节。放出我自己的单频调制程序+数据手册,如果无法上传的话,,需要的可以留言,我挨个发。
最后希望能给小丁同学带来帮助,脚踏实地的学习。
2020.9.20于湖北工业大学