⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tuning.c

📁 全数字高清电视数字调谐器
💻 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 + -