//==============================================================
#include <msp430x14x.h>
#include <INTRINSICS.h>
#include "Config.h" //配置头文件,与硬件相关的配置在这里更改
//============================================================================
//单片机和AD9854硬件接口定义
#define DDS_WR_H P1OUT|=BIT0 //(WR) 写使能信号 P1.0输出置高
#define DDS_WR_L P1OUT &= ~BIT0 //(WR) 写使能信号 P1.0输出置低
#define DDS_RD_H P1OUT|=BIT1 //(RD) 读使能信号 P1.2输出置高
#define DDS_RD_L P1OUT &= ~BIT1 //(RD) 读使能信号 P1.2输出置低
#define DDS_RST_H P1OUT|=BIT2 //(RST)复位信号 P1.3输出置高
#define DDS_RST_L P1OUT &= ~BIT2 //(RST)复位信号 P1.3输出置低
#define DDS_UPD_H P1OUT|=BIT3 //(UPD)频率控制字更新信号 P1.1输出置高
#define DDS_UPD_L P1OUT &= ~BIT3 //(UPD)频率控制字更新信号 P1.1输出置低
/******SP串并行 接VCC 用并行模式*******/
#define DDS_FSK_H P1OUT |= BIT5 //fsk
#define DDS_FSK_L P1OUT &= ~BIT5
#define DDS_ADDR_PORT P3OUT //地址口 A0~A5为AD9854地址线 P3
#define DDS_DATA_PORT P5OUT //数据口 DB0~DB7为AD9854数据线 P5
unsigned char FreqWord[6]; //6个字节频率控制字
const ulong Freq_mult_ulong=938249; // 2^48/300000000 整数
const double Freq_mult_doulle=938249.922; //带有小数点
/********************************************************************
初始化IO口子程序
********************************************************************/
void Port_Init()
{
P1SEL = 0x00; //设置IO口为普通I/O模式
P1DIR = 0xff; //IO口方向为输出
P1OUT = 0x00; //初始设置 输出为0
P3SEL = 0x00; //设置IO口为普通I/O模式
P3DIR|= 0xff; //P3^0~P3^5为AD9854地址线 设置为输出
P3OUT = 0x00; //初始设置为00
P5SEL = 0x00; //设置IO口为普通I/O模式
P5DIR = 0xff; //设置IO口方向为输出
P5OUT = 0x00; //初始设置为00
}
/**************************************************************************
* 函数名 :WriteByte
* 描述 : 子函数,从AD9854中写1个字节
* 输入 : strAddr strByte
* 输出 : 无
* 返回值 : 无
* 说明 : 无
**************************************************************************/
void WriteByte(unsigned char strAddr , unsigned char strByte)
{
unsigned char port ; //定义一个8位无符号变量 port
DDS_DATA_PORT = strByte ; //将strByte赋值给P4口
port = DDS_ADDR_PORT ; //将P4口数据赋值给port
port = (port & 0xc0) + strAddr ; //port最高位与次高位不变与strAddr相加
DDS_ADDR_PORT = port ; //将port数据赋值给P4口
DDS_WR_L ; //数据在上升沿锁存
DDS_WR_H ;
}
/**************************************************************************
* 函数名 :ReadByte
* 描述 : 子函数,从AD9854中读取1个字节
* 输入 : strAddr
* 输出 : result
* 返回值 : 0 或 strAddr
* 说明 : 无
*************************************************************************
unsigned char ReadByte(unsigned char strAddr)
{
unsigned char result = 0;
DDS_RD_H; //读使能信号为1
DDS_ADDR_PORT = strAddr; // 将strAddr赋值给P4口
DDS_RD_L; //读使能信号为0
result = DDS_DATA_PORT; //P0口赋值给result
DDS_RD_H; //读使能信号为1
return result; //返回 result的值
}
/**************************************************************************
* 函数名 :Freq_convert
* 描述 : 子函数,频率寄存器1控制字
* 输入 : 无符号字符指针freq的值
* 输出 : 无
* 返回值 : 无
* 说明 : 该算法为多字节相乘算法,公式FTW=(Desired Output Frequency *2N)/SYSCLK
其中N=48,Desird Output Frequency为所需的频率,即Freq,SYSCLK为可编程的系统时钟
FTW为48Bit的频率控制字,即FreqWord[6]
**************************************************************************/
void Freq_convert(long Freq)
{
ulong FreqBuf;
ulong Temp=Freq_mult_ulong;
uchar Array_Freq[4]; //将输入频率因子分为四个字节
Array_Freq[0]=(uchar)Freq;
Array_Freq[1]=(uchar)(Freq>>8);
Array_Freq[2]=(uchar)(Freq>>16);
Array_Freq[3]=(uchar)(Freq>>24);
FreqBuf=Temp*Array_Freq[0];
FreqWord[0]=FreqBuf;
FreqBuf>>=8;
FreqBuf+=(Temp*Array_Freq[1]);
FreqWord[1]=FreqBuf;
FreqBuf>>=8;
FreqBuf+=(Temp*Array_Freq[2]);
FreqWord[2]=FreqBuf;
FreqBuf>>=8;
FreqBuf+=(Temp*Array_Freq[3]);
FreqWord[3]=FreqBuf;
FreqBuf>>=8;
FreqWord[4]=FreqBuf;
FreqWord[5]=FreqBuf>>8;
}
/**************************************************************************
* 函数名 :AD9854_SetDFW
* 描述 : 子函数,频率步进量设置
* 输入 : 无符号字符指针delta的值
* 输出 : 无
* 返回值 : 无
* 说明 : 无
**************************************************************************/
void AD9854_SetDFW(unsigned char *delta)
{
unsigned char i = 0 ;
unsigned char delta_addr = 0 ;
delta_addr = 0x10 ; //48位频率步进量最高位起始地址为 0x10
for( i = 0 ; i < 6 ; i ++ )
{
WriteByte( delta_addr + i , delta[i]);
}
}
/*******************************************************************************
* 函数名 : AD9854_SetUDClk
* 描述 : 子函数,内部时钟寄存器控制字设置
* 输入 : 无符号字符指针uclk的值
* 输出 : 无
* 返回值 : 无
* 说明 : 无
*******************************************************************************/
void AD9854_SetUDClk(unsigned char *uclk)
{
unsigned char i ;
unsigned char uclk_addr = 0 ;
uclk_addr = 0x16 ; //32位更新时钟计数器最高位地址为0x16
for( i = 0 ; i < 4 ; i ++ )
{
WriteByte(uclk_addr + i , uclk[i]);
}
}
/*******************************************************************************
* 函数名 :AD9854_SetSpecialWord
* 描述 : 子函数,设置32位特殊功能寄存器
* 输入 : 无符号字符指针SWord的值 以0x1D为首地址 陆续赋值 写入数据
* 输出 : 无
* 返回值 : 无
* 说明 : 节电控制为0x00, 时钟倍频控制为0x46, 清零控制为0x25, 传输控制模式为0x10
*******************************************************************************/
void AD9854_SetSpecialWord(unsigned char *SWord)
{
unsigned char i ;
unsigned char Special_addr = 0;
Special_addr = 0x1D; //特殊功能寄存器首地址 0x1D
for( i = 0 ; i < 4 ; i ++ )
{
WriteByte( Special_addr + i , SWord[i]);
}
}
/*******************************************************************************
* 函数名 :AD9854_SetOutkeyQ
* 描述 : 子函数,8位输出边沿变化率控制字
* 输入 : 无符号字符 Key_ramp
* 输出 : 无
* 返回值 : 无
* 说明 : 无
*******************************************************************************/
void AD9854_SetOutkeyRamp(unsigned char Key_ramp)
{
WriteByte(0x25, Key_ramp); //8位输出边沿变化率最高位位0x25
}
/*******************************************************************************
* 函数名 :AD9854_SetQDAC
* 描述 : 子函数,12位Q通道DAC输入控制字
* 输入 : 无符号字符指针QDAC的值
* 输出 : 无
* 返回值 : 无
* 说明 : 无
*******************************************************************************/
void AD9854_SetQDAC(unsigned char *QDAC)
{
WriteByte(0x26 , QDAC[0]);
WriteByte(0x27 , QDAC[1]);
}
/**************************************************************************
* 函数名 : AD9854_Reset
* 描述 : 子函数,硬件复位
* 输入 : 无
* 输出 : 无
* 返回值 : 无
* 说明 : 无
**************************************************************************/
void AD9854_Reset(void)
{
DDS_RST_H;
delay_us(10);
DDS_RST_L;
}
/**************************************************************************
* 函数名 :Single_Mode_init
* 描述 : 子函数,AD9854初始化
* 输入 : 无
* 输出 : 无
* 返回值 : 无
* 说明 : 1.复位芯片 2.选择数据输入方式 3.选择数据刷新方式为外部触发方式
*******************************************************************************/
void Single_Mode_init(void)
{
unsigned char mode1[4]={0x10,0x4a,0x00,0x60}; //特殊功能寄存器设置 power down所有模块, PLL大于200MHz 旁路PLL,7倍频,
DDS_WR_H ; //读写端口设置为无效
DDS_RD_H;
DDS_UPD_L ;
AD9854_Reset(); //复位信号
AD9854_SetSpecialWord(mode1);
DDS_UPD_H ;
DDS_UPD_L ;
}
//====================================================================================
//函数名称:void AD9854_SetSine(ulong Freq,uint Shape)
//函数功能:AD9854正弦波产生程序
//入口参数:Freq 频率设置,取值范围为0~(1/2)*SYSCLK
// Shape 幅度设置. 为12 Bit,取值范围为(0~4095) ,取值越大,幅度越大
//出口参数:无
//====================================================================================
void Single_Mode(ulong Freq,uint Shape)
{
uchar count;
uchar Adress;
Adress = 0x04; //选择频率控制字地址的初值
Freq_convert(Freq); //频率转换
for(count=6;count>0;) //写入6字节的频率控制字
{
WriteByte(Adress++,FreqWord[--count]);
}
WriteByte(0x21,Shape>>8); //设置I通道幅度
WriteByte(0x22,(uchar)(Shape&0xff));
WriteByte(0x23,Shape>>8); //设置Q通道幅度
WriteByte(0x24,(uchar)(Shape&0xff));
DDS_UPD_H ;
DDS_UPD_L ;
}
/**************************************************************************
* 函数名 :TRIANGLE_MODE_init
* 描述 : 子函数,AD9854初始化
* 输入 : 无
* 输出 : 无
* 返回值 : 无
* 说明 : 1.复位芯片 2.选择数据输入方式 3.选择数据刷新方式为外部触发方式
*******************************************************************************/
void TRIANGLE_MODE_init(void)
{
unsigned char mode1[4]={0x10,0x4a,0x24,0x60}; //特殊功能寄存器设置 power down所有模块, PLL大于200MHz 旁路PLL,7倍频,
DDS_WR_H ; //读写端口设置为无效
DDS_RD_H;
DDS_UPD_L ;
AD9854_Reset(); //复位信号
AD9854_SetSpecialWord(mode1);
DDS_UPD_H ;
DDS_UPD_L ;
}
//================================================================
// 扫频功能
//================================================================
void TRIANGLE_MODE(ulong Freq_Low,ulong Freq_High,ulong Freq_Up_Down,ulong FreRate)
{
uchar count=6;
uchar Adress1,Adress2,Adress3;
const uint Shape=4000; //幅度设置. 为12 Bit,取值范围为(0~4095)
Adress1=0x04; //选择频率控制字地址的初值
Adress2=0x0a;
Adress3=0x10;
Freq_convert(Freq_Low); //频率1转换
for(count=6;count>0;) //写入6字节的频率控制字
{
WriteByte(Adress1++,FreqWord[--count]);
}
Freq_convert(Freq_High); //频率2转换
for(count=6;count>0;) //写入6字节的频率控制字
{
WriteByte(Adress2++,FreqWord[--count]);
}
Freq_convert(Freq_Up_Down); //步进频率转换
for(count=6;count>0;) //写入6字节的频率控制字
{
WriteByte(Adress3++,FreqWord[--count]);
}
WriteByte(0x1a,(uchar)((FreRate>>16)&0x0f)); //设置斜升速率
WriteByte(0x1b,(uchar)(FreRate>>8));
WriteByte(0x1c,(uchar)FreRate);
WriteByte(0x21,Shape>>8); //设置I通道幅度
WriteByte(0x22,(uchar)(Shape&0xff));
WriteByte(0x23,Shape>>8); //设置Q通道幅度
WriteByte(0x24,(uchar)(Shape&0xff));
DDS_UPD_H ;
DDS_UPD_L ; //更新AD9854输出
}
//================================================================
// 主函数
//================================================================
void main(void)
{
unsigned char udclk[4]={0x00,0xff,0xff,0xff}; //32位更新时钟寄存器
WDT_Init(); //看门狗设置
Clock_Init(); //系统时钟设置
Port_Init();
//AD9854_SetUDClk(udclk); //延长内部刷新时间
/*Single_Mode_init();
Single_Mode(2000000,4000);*/
TRIANGLE_MODE_init();
TRIANGLE_MODE(9000000,15000000,100,30000);
while(1)
{
DDS_FSK_H;
delay_ms(90); //延时时间长,便于观察
DDS_FSK_L;
delay_ms(90);
}
}