📄 tuning.c
字号:
#include <math.h>
#include "struct.h"
#include <stdio.h>
#include <w77e58.h>
#define tuning_address 0xc0 //调谐器地址
#define lo1_1 0x00 //lo1n
#define sel_lo1a 0x01 //sel-lo1a
#define logc_cntl 0x02 //lo2gc -lo1gc
#define control1 0x06 //adon
#define control2 0x07 //adon
#define status 0x0e //状态检查
#define tun_a_d 0x0f
#define DEBUG 1
sbit power_sw=P1^4;//电源开关
extern unsigned char i2c_read_a(unsigned char slave,
unsigned char address);//单字节读
extern void write_b(unsigned char slave, unsigned char address, unsigned char fb);
extern void write_a(unsigned char slave,unsigned char address,
unsigned char fb[],unsigned char sun);
extern void delay1(unsigned int i);
extern void daya1(unsigned long i);
void tuning_start();//调谐器初始化
void tuning_freq(tv ch);//调到频道
void calculate_desired();
void avoid_spurs();//避开假信号
bit is_spurin_band();//假信号检查
void select_vco();//以flo1的频率初步选择vco1
void calculate_lon();//步骤3.4 计算lo1n lo1a lo2i lo2n lo2a NUM fnon
void write_registers();//写寄存器
bit check_lo_lock();//检查LO-PLL锁定
bit optimize_vco();//优化VCO
float rf_freq;//当前使用频道中心频率
float fif2;//第2中频
#define fif1 1090 //第一中频
#define fref 5.25 //时钟基准
float f_ifbw_width;//第2中频带宽
float fstep;//最小调谐步骤大小
/**********************/
//计算值中间
unsigned char lo1n;//第1本振数值
unsigned char lo1a;//第1本振预分频比例因子
unsigned int lo2i;
unsigned char lo2n;
unsigned char lo2a;
unsigned int num;
unsigned int step;
unsigned char fnon;
unsigned char sel;//最优VCO1选择
unsigned char lo1gc;
unsigned char lo2gc;
unsigned char xogc;//振荡器环路增益控制
/*****************/
//
float flo1_desired;// 计算想得到的第1本振频率
//flo1_desired=Frf+Fif 中心频率+第1中频 // Fif-第1中频 Frf -输入中心频率
unsigned int lo1i;//第1本振的PLL整数分频系数
//lo1i=floor(flo1_desired/fref+1/2) //ferf -5.25Mhz
float flo1;//实际的VCO1的值
//flo1=lo1i*fref
float flo2_desired;//计算想得到的第2本振频率
//flo2_desired=flo1-Frf-fif2
//float ftest;//假信号干涉计算
//ftest=(n1*flo1)+(n2*flo2_desired)
//(|(|ftest|)-fif2|)<fifbw/2
void tuning_start()//调谐器初始化
{
unsigned char xok;
unsigned char fop;
dl: write_b(tuning_address,lo1_1,0x1a);
write_b(tuning_address,logc_cntl,0xff);
write_b(tuning_address,control1,0xe4);
write_b(tuning_address,control2,0x0f);
delay1(50000);
do
{
xok=i2c_read_a(tuning_address,status);//步骤A
if(xok&0x01)
return;
else {
fop=i2c_read_a(tuning_address,control2);//步骤B
xogc=fop&0x07;
if(xogc==0x03)
goto dl;
else {
write_b(tuning_address,control2,((xogc-1)&0x07)|(fop&0xf8));//步骤C
delay1(40000); //步骤D
}
}
}
while(1);//步骤E
}
void tuning_freq(tv ch)//调到频道
{
lp:
rf_freq=ch.rf;
fif2=ch.f_if2;
f_ifbw_width=ch.fif_bw;
fstep=ch.f_step;
#if(DEBUG)
printf("中心频率=%f,第2中频=%f,带宽=%f,步骤=%f\n",rf_freq,fif2,f_ifbw_width,fstep);
#endif
calculate_desired();//步骤3.1- 计算flo1和flo2频率
avoid_spurs();//步骤3.2 -避开假信号
select_vco();//步骤3.3 -最优vco1选择
calculate_lon();//步骤3.4 -计算lo1n lo1a lo2i lo2n lo2a NUM fnon
write_registers();//步骤3.5 -写寄存器
if(check_lo_lock())//步骤3.6 -检查LO-PLL锁定
{
if(optimize_vco())//步骤3.7 -优化VCO
{
power_sw=1;
daya1(500000);
power_sw=0;
daya1(500000);
tuning_start();//重新初始化
daya1(300000);
goto lp;
}
if(check_lo_lock())//检查LO-PLL锁定
write_b(tuning_address,0x02,0x20);//步骤3.8 -写LO控制寄存器-02
else
{ power_sw=1;
daya1(500000);
power_sw=0;
daya1(500000);
tuning_start();//重新初始化
daya1(300000);
goto lp;
}
}
else
{ power_sw=1;
daya1(500000);
power_sw=0;
daya1(500000);
tuning_start();//重新初始化
daya1(300000);
goto lp;
}
}
void calculate_desired()//步骤3.1- 计算flo1和flo2频率
{
float as;
flo1_desired= rf_freq +fif1;
as=(flo1_desired/fref)+(1/2);
lo1i=(unsigned int)as;
flo1=lo1i*fref;
flo2_desired=flo1- rf_freq-fif2;
}
void avoid_spurs()//步骤3.2 -避开假信号
{
unsigned char n_lo1adjust;//n次 lo1调整
n_lo1adjust=1;
do
{
if(n_lo1adjust>=3)
return;
if(is_spurin_band())
{
if(flo1<flo1_desired)
lo1i=lo1i+n_lo1adjust;
else lo1i=lo1i-n_lo1adjust;
flo1=lo1i*fref;
flo2_desired=flo1- rf_freq-fif2;
n_lo1adjust=n_lo1adjust+1;
}
else return;
}
while(1);
}
bit is_spurin_band()//假信号检查
{
float f_test;
char n1;
char n2;
char n_max=5;
n1=1;
do{
n2=-n1;
f_test=n1*(flo1-flo2_desired);
do{
n2=n2-1;
f_test=f_test-flo2_desired;
if(fabs((fabs(f_test))-fif2)<(f_ifbw_width/2))
return(1);
else
{
if((f_test>(flo2_desired-fif2-f_ifbw_width))|(n2>-n_max))
continue;
else break;
}
}
while(1);
n1=n1+1;
if(n1<n_max)
continue;
else return (0);
}
while(1);
}
void select_vco()//以flo1的频率初步选择vco1 步骤3.3 -最优vco1选择
{
if(1128.75<=flo1<1291.50)
sel=4;
else if(1291.50<=flo1<1449.00)
sel=3;
else if(1449.00<=flo1<1617.00)
sel=2;
else if(1617.00<=flo1<1790.25)
sel=1;
else if(1790.25<=flo1<1958.25)
sel=0;
else if(flo1<1128.75 )
sel=4;
else sel=0;
}
void calculate_lon()//步骤3.4 计算lo1n lo1a lo2i lo2n lo2a NUM fnon
{
unsigned int as;
lo1n=(unsigned int)(lo1i/8);
lo1a=lo1i-(lo1n*8);
lo2i=(unsigned int)(flo2_desired/fref);
lo2n=(unsigned int)(lo2i/8);
lo2a=lo2i-(lo2n*8);
num=(unsigned int)((flo2_desired/fref-lo2i)*3780);
step=3780*fstep/fref;
as=(unsigned int)(num/step+1/2);
num=step*as+1;
fnon=7;
}
void write_registers()//步骤3.5 -写寄存器
{
unsigned char reg[14];
reg[0]=lo1n-1;
reg[1]=((sel<<4)&0xf0)|(lo1a&0x0f);
reg[2]=0x86;
reg[3]=0;
if(sel<2)
reg[4]=128+48+fnon;
else reg[4]=48+fnon;
reg[5]=((lo2a<<5)&0xe0)|(lo2n-1);
if( rf_freq<400)
reg[6]=0xe4;
else reg[6]=0xf4;
reg[7]=8+xogc;
reg[8]=0;
reg[9]=0;
reg[10]=0;
reg[11]=num;
reg[12]=128+((num>>8)&0x0f);
reg[13]=0;
write_a(tuning_address,0,reg,14);
}
bit check_lo_lock()//步骤3.6 -检查LO-PLL锁定
{
unsigned char n_lock;
unsigned char bdata lock;
bit locka;
bit lockb;
n_lock=0;
do
{
lock=i2c_read_a(tuning_address,status);
locka=lock^1;
lockb=lock^2;
if(locka&lockb)
return(1);
n_lock++;
delay1(2000);
if(n_lock>10)
return(0);
}
while(1);
}
bit optimize_vco()//步骤3.7 -优化VCO
{
unsigned char tad1;
unsigned char r;
unsigned char t;
unsigned char x;
r=0;
t=0;
x=sel;
do{
tad1=i2c_read_a(tuning_address,tun_a_d);
tad1=tad1&0x07;
if((tad1==0)|(tad1==1))
return(0);
else {
if(tad1==2)
{
if(sel==0)
{
sel=x+1;
t++;
if(t>4)
{
#if(DEBUG)
printf("VCO优化 T>4\n");
#endif
return(1);
}
}
else
sel--;
}
else
{
if(sel<4)
sel++;
else
{
sel=x-1;
r++;
if(r>4)
{
#if(DEBUG)
printf("VCO优化 R>4\n");
#endif
return(1);
}
}
}
}
write_b(tuning_address,sel_lo1a, ((sel<<4)&0xf0)|(lo1a&0x0f));
delay1(1000);
}
while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -