? ? ? ?在今年暑假准备电赛时接触到了AD9854模块,当时也是花了差不多两天时间才把这个玩意儿琢磨出来,现在写一篇博客来记录一下该模块的使用,或许能给才接触这个模块的小伙伴一些帮助。
本文章是基于官方驱动代码修改而来,适配与STM32 HAL库。
若文章有误或能改进的地方,多多相互交流。
导论:
? ? ? ? AD9854 数字合成器是高集成度的器件,采用先进的 DDS 技术,片内整合了两路高速、 高性能正交 D/A 转换器通过数字化编程可以输出 I、Q 两路合成信号。AD9854 的 DDS 核具 有 48 位的频率分辨率(在 300MHz 系统时钟下,频率分辨率可达 1μHz)。输出 17 位相位 截断保证了良好的无杂散动态范围指标。AD9854 允许输出的信号频率高达 150MHZ,可进 行无斜率频移键控(FSK)、斜率频移键控(RFSK)、二元相移键控(BPSK)、相移键控(PSK)、 幅度调制(AM)、脉冲调频(CHIRP)和通断整形键控(OSK),且数字调制输出频率可达 100MHZ。芯片内部高速比较器可将正弦波转换为方波输出,可方便用作时钟发生器。 AD9854 广泛应用在便携式频率特性分析仪、可编程时钟发生器、应用于雷达和扫频系统的 脉冲调频信号源、测试和测量、设备商业和业余的射频(RF)发射机等中。?
一、接线部分
使用这个模块最头疼的地方就是接线,使用这一个模块就需要接二十根左右,占用了很多单片机的引脚,密密麻麻,雀氏打脑壳。所以本人建议:需要使用该模块时,预先接上该模块,并且尽量将所需要接的线排列在一起,如PC6-PC11中引脚都接入AD9854。
//使用注意:ad9854 采用并行传输,除电源和接地外 需要全部接线。
1.1 CUBE MX STM32引脚定义
? ?(1)CLK、RST等建议全部接引脚C组,最大输出速度 --high。 ? ?(2)D0-7,A0-5 接引脚D组,注:不能接PD14,PD15。 ? ?(3)DDS上的vcc和GND 需要接单片机,形成数据、电压回路。可接上9V 电源,输出波形更加稳定。?
本人引脚定义如下:
?
?二、程序移植引脚重定义部分
在官方给的驱动 例程中并不完全适用于HAL库,所以在代码上需要进行一些修改。
注意事项:??
?(1)void AD9854_IO_Init(void);//.c文件中 需要注释,因为引脚已经默认初始化。如图:
?(2)sys.c 需要引用。//打开该文件,会显示红叉,但是编译通过,不管他。可能是软件上的问题。(咱也不懂,反正不影响使用)。如下图:
?(3)注释掉官方给的驱动文件 .c 中的延时函数:#include "delay.h"
?2.1 AD9854.c 驱动文件 修改如下:
这里只展示一部分,有需要的可以点击下方连接下载。
#define CLK_Set 15
const ulong Freq_mult_ulong = 938250;
const double Freq_mult_doulle = 938249.9223688533;
//**************************修改硬件时要修改的部分********************************
//**************************以下部分为函数定义********************************
static void AD9854_WR_Byte(uint32_t addr,uint32_t dat);
extern void AD9854_Init(void);
static void Freq_convert(long Freq);
extern void AD9854_SetSine(ulong Freq,uint Shape);
static void Freq_double_convert(double Freq);
extern void AD9854_SetSine_double(double Freq,uint Shape);
extern void AD9854_InitFSK(void);
extern void AD9854_SetFSK(ulong Freq1,ulong Freq2);
extern void AD9854_InitBPSK(void);
extern void AD9854_SetBPSK(uint Phase1,uint Phase2);
extern void AD9854_InitOSK(void);
extern void AD9854_SetOSK(uchar RateShape);
extern void AD9854_InitAM(void);
extern void AD9854_SetAM(uint Shape);
extern void AD9854_InitRFSK(void);
extern void AD9854_SetRFSK(ulong Freq_Low,ulong Freq_High,ulong Freq_Up_Down,ulong FreRate);
//void AD9854_IO_Init(void)
//{
// GPIO_InitTypeDef GPIO_InitStructure ;
//
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE); //使能PB,PE端口时钟
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
// GPIO_Init(GPIOB ,&GPIO_InitStructure) ;
//
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6| GPIO_Pin_4| GPIO_Pin_5| GPIO_Pin_8| GPIO_Pin_2;
// GPIO_Init(GPIOA ,&GPIO_InitStructure) ;
//
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All^(GPIO_Pin_14| GPIO_Pin_15);
// GPIO_Init(GPIOC ,&GPIO_InitStructure) ;
//}
//====================================================================================
//函数名称:void AD9854_WR_Byte(uchar addr,uchar dat)
//函数功能:AD9854并行口写入数据
//入口参数:addr 6位地址
// dat 写入的数据
//出口参数:无
//====================================================================================
uint32_t dat1,dat2;
void AD9854_WR_Byte(uint32_t addr,uint32_t dat)
{
dat1= dat|(addr<<8);
AD9854_AdrBus=(dat1&0x3fff)|((dat1^0x3fff)<<16);
// AD9854_AdrBus = ((addr&0x3f)<<8) | ((addr^0x3f)<<(16+8));
// AD9854_DataBus = dat|(dat^0xff)<<16;
// dat1 = ((addr&0x3f)<<8) | ((addr^0x3f)<<(16+8));
// dat2 = (dat1&0x3fff)|((dat1^0x3fff)<<16);
AD9854_WR = 0;
AD9854_WR = 1;
}
//====================================================================================
//函数名称:void AD9854_Init(void)
//函数功能:AD9854初始化
//入口参数:无
//出口参数:无
//====================================================================================
void AD9854_Init(void)
{
AD9854_WR=1;//将读、写控制端口设为无效
AD9854_RD=1;
AD9854_UDCLK=0;
AD9854_RST=1; //复位AD9854
AD9854_RST=0;
AD9854_WR_Byte(0x1d,0x00); //关闭比较器
AD9854_WR_Byte(0x1e,CLK_Set); //设置系统时钟倍频
AD9854_WR_Byte(0x1f,0x00); //设置系统为模式0,由外部更新
AD9854_WR_Byte(0x20,0x60); //设置为可调节幅度,取消插值补偿
AD9854_UDCLK=1; //更新AD9854输出
AD9854_UDCLK=0;
}
?2.2?AD9854.H 头文件修改
官方给的驱动是基于STC51写的程序,因此在引脚定义上,我们还需要进行一些修改。
因为在驱动中符号类型都是采用的uint、uchar等缩写,但是在HAL库中,这些都会报错,因此我们在头文件中定义一下这些类型。(有更好的方法可以在评论区里讨论)
?以下是修改的头文件:
#ifndef __AD9854_H
#define __AD9854_H
#include "sys.h"
#define AD9854_RST PCout(6) //AD9854复位端口
#define AD9854_UDCLK PCout(7) //AD9854更新时钟
#define AD9854_WR PCout(8) //AD9854写使能,低有效
#define AD9854_RD PCout(9) //AD9854读使能,低有效
#define AD9854_OSK PCout(10) //AD9854 OSK控制端
#define AD9854_FDATA PCout(11) //AD9854 FSK,PSK控制
#define AD9854_DataBus GPIOD->BSRR
#define AD9854_AdrBus GPIOD->BSRR
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
extern void AD9854_Init(void);
static void Freq_convert(long Freq);
extern void AD9854_SetSine(ulong Freq,uint Shape);
static void Freq_double_convert(double Freq);
extern void AD9854_SetSine_double(double Freq,uint Shape);
extern void AD9854_InitFSK(void);
extern void AD9854_SetFSK(ulong Freq1,ulong Freq2);
extern void AD9854_InitBPSK(void);
extern void AD9854_SetBPSK(uint Phase1,uint Phase2);
extern void AD9854_InitOSK(void);
extern void AD9854_SetOSK(uchar RateShape);
extern void AD9854_InitAM(void);
extern void AD9854_SetAM(uint Shape);
extern void AD9854_InitRFSK(void);
extern void AD9854_SetRFSK(ulong Freq_Low,ulong Freq_High,ulong Freq_Up_Down,ulong FreRate);
#endif
?2.3 AD9854启用代码
2.3.1 在相应区域添加头文件
?2.3.2 添加初始化代码
在main函数中,while函数之前添加 启动代码:
AD9854_Init();
AD9854_InitRFSK();
AD9854_SetSine(1000,4095);
添加完以上代码后,将程序烧录进单片机,重启。示波器探头连接AD9854输出端,即可观察相应波形。?(需要输出什么波形及频率的函数帮助 在.c文件中都有注明)
三、代码验证
?AD9854_SetSine(1000,4095);//输出1kHz的正弦波?
?四、驱动代码连接
https://download.csdn.net/download/weixin_50950983/33192991
|