前两个集BLOG分别给出了ADF5355接口的VERILOG设计实现以及设置频率的C语言算法,我今天试验了以,试验成功了。
首先很重要的是ADF5355寄存器配置的设置:
可以在这个基础上修改输入以及输入频率类型,其他不要动。驱动代码如下:
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#define R00 0X200960
#define R01 0X1
#define R02 0X42
#define R03 0x3
#define R04_1 0X08008B94
#define R04_0 0X10008B94
#define R04_A_LCK 0x28008B94
#define R04_D_LCK 0x30008B84
#define R05 0X800025
#define R06 0X35C0C076
#define R07 0X120000E7
#define R08 0X102D0428
#define R09 0X1110FCC9
#define R10 0XC0193A
#define R11 0X61300B
#define R12 0X1041C
#define Fref_in 40000 //输入时钟
#define F_pfd Fref_in //鉴相频率
#define MODE1 16777216; //第一部分小数分频模数
#define MODE2 130; //第二部分小数分频模数
#define IO *(unsigned int volatile *) (0x43c00000)
#define RF_EN *(unsigned int volatile *) (0x43c00004)
void WriteToADF5355(unsigned int BUF) {while( (IO&1)!=0 ) ;IO=BUF;}
void Write_frequence_AMP(unsigned int Freq,unsigned int Amp) //写频率和幅度
//AMP ==> 0:-4dbm 1:-1dbm 2:2dbm 3:5dbm
{
float Freq_N,Freq_temp;
unsigned int Freq2VCO,INT,FRAC1,FRAC2; //整数分频, 小数分频1 小数分频2
unsigned int R0_temp=0; //控制INT
unsigned int R4_temp=0,MODE2_temp; //改变输出的分频控制字,一共分成7段
unsigned int Out_Divider,RF_Divider;//输出分频控制,3位 及对应的分频数
unsigned int I_CP=9000;
unsigned int I_BLEED_N;
if((53125<=Freq)&&(Freq<106250)) { Out_Divider=6; RF_Divider=64;} //分频段
if((106250<=Freq)&&(Freq<212500)) { Out_Divider=5; RF_Divider=32;} //
if((212500<=Freq)&&(Freq<425000)) { Out_Divider=4; RF_Divider=16;} //
if((425000<=Freq)&&(Freq<850000)) { Out_Divider=3; RF_Divider=8; } //
if((850000<=Freq)&&(Freq<1700000)) { Out_Divider=2; RF_Divider=4; } //
if((1700000<=Freq)&&(Freq<3400000)){ Out_Divider=1; RF_Divider=2; } //
if((3400000<=Freq)&&(Freq<6800000)){ Out_Divider=0; RF_Divider=1; }
Freq_temp=Freq;
Freq2VCO=(Freq_temp*RF_Divider)*2;//计算出2倍VCO,从B端口输出
//计算整数分频INT;小数分频1FRAC1;小数分频2FRAC2
Freq_temp=Freq;
Freq_N=(Freq_temp*RF_Divider)/F_pfd; //计算出N分频值,带有小数位
Freq_temp=Freq_N;
INT=(unsigned int )Freq_temp;//计算出整数分频INT
I_BLEED_N=I_CP*4/(INT*375); //计算bleed 电流对应的值
I_BLEED_N=(unsigned int )I_BLEED_N;
Freq_temp=(Freq_N-INT)*MODE1;
FRAC1=(unsigned int )Freq_temp; //计算出小数分频1-FRAC1
Freq_temp=(Freq_N-INT)*MODE1
Freq_temp=Freq_temp-FRAC1;
FRAC2=(unsigned int )Freq_temp*MODE2;
MODE2_temp=MODE2;
WriteToADF5355((Out_Divider<<21)|(I_BLEED_N<<13)|(Amp<<4)|0X35000046);//R6
WriteToADF5355(R04_D_LCK | 1<<4 ); //R4-计数器复位
WriteToADF5355(2|(MODE2_temp<<4)|(FRAC2<<18));//R2
WriteToADF5355(1|(FRAC1<<4)); //R1
WriteToADF5355(INT<<4); //R0
WriteToADF5355(R04_D_LCK); //R4-计数器启动
usleep(161);
WriteToADF5355(0X200000|(INT<<4));
}
void Init_ADF5355(int mux ){
WriteToADF5355(R12);
WriteToADF5355(R11);
WriteToADF5355(R10);
WriteToADF5355(R09);
WriteToADF5355(R08);
WriteToADF5355(R07);
WriteToADF5355(R06);
WriteToADF5355(R05);
if (mux==1) WriteToADF5355(R04_1); // muxout = 1
else if (mux==2) WriteToADF5355(R04_A_LCK); // ANALOG LOCK
else if (mux==3) WriteToADF5355(R04_D_LCK); //DIGITAL LOCK
else WriteToADF5355(R04_0);// muxout = 0
WriteToADF5355(R03);
WriteToADF5355(R02);
WriteToADF5355(R01);
usleep(200);
WriteToADF5355(R00);
}
int check_if_adf5355_online(){
int i =10;unsigned int r ;
while(i--){
Init_ADF5355(1);r= IO&2 ; if (r==0) return 0;
Init_ADF5355(0);r= IO&2 ; if (r!=0) return 0;
}
return 1 ;
}
int main()
{
int r ;
init_platform();
RF_EN =1;
print("Hello World\n\r");
sleep(1);
r = check_if_adf5355_online();
if (r==0)while(1);
Init_ADF5355(3);
Write_frequence_AMP(1000*60 , 3);
while(1) ;
cleanup_platform();
return 0;
}
已经测试过了,代码很好用。100M以内的频率输出我用示波器看了么有问题,另外用频谱仪看了几个2G的频点,也都OK。
ADF5355的接口VERILOG代码在上两个BLOG里面,没有任何修改。在VIVADO项目下包装成了AXI_LITE外设,之后用上述驱动代码控制。
{{aAxvOXMOIvVUoXMxvoxiowMwWV8xxWTxoxOIOVIUUOvwVOUiIoUvvTMMVMwovWHWX8vOUOvvviTHUToiVwiVxvvMTXIm8VmUTXmOiXmvMW88IivwmHMoiHIoVU8VvmvIWXTvvOvv8xvMovOWooTxUWMm8UmooOTvvwUIoTwvmWUoiTw8VmvoHWwMIUWOixiowiUoiXwiwwMMIiIXHwUmOWUVmXXwV8iHWOTUiwTU8xwOoV8HVmTWZz}}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)