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

📄 tuner.c

📁 mstar716驱动源代码
💻 C
字号:
#include"tuner.h"
//************************************************************************************************************
code uword USA_air[]={
0X0451,0X04C9,0X0541,0X0609,0X0681,0X0DB1,0X0E29,0X0EA1,0X0F19,0X0F91,
0X1009,0X1081,0X24D1,0X2549,0X25C1,0X2639,0X26B1,0X2729,0X27A1,0X2819,
0X2891,0X2909,0X2981,0X29F9,0X2A71,0X2AE9,0X2B61,0X2BD9,0X2C51,0X2CC9,
0X2D41,0X2DB9,0X2E31,0X2EA9,0X2F21,0X2F99,0X3011,0X3089,0X3101,0X3179,
0X31F1,0X3269,0X32E1,0X3359,0X33D1,0X3449,0X34C1,0X3539,0X35B1,0X3629,
0X36A1,0X3719,0X3791,0X3809,0X3881,0X38F9,0X3971,0X39E9,0X3A61,0X3AD9,
0X3B51,0X3BC9,0X3C41,0X3CB9,0X3D31,0X3DA9,0X3E21,0X3E99
};
code uword USA_catv[]={
0X0451,0X04C9,0X0541,0X0609,0X0681,0X0DB1,0X0E29,0X0EA1,0X0F19,0X0F91,
0X1009,0X1081,0X0979,0X09F1,0X0A69,0X0AE1,0X0B59,0X0BD1,0X0C49,0X0CC1,
0X0D39,0X10F9,0X1171,0X11E9,0X1261,0X12D9,0X1351,0X13C9,0X1441,0X14B9,
0X1531,0X15A9,0X1621,0X1699,0X1711,0X1789,0X1801,0X1879,0X18F1,0X1969,
0X19E1,0X1A59,0X1AD1,0X1B49,0X1BC1,0X1C39,0X1CB1,0X1D29,0X1DA1,0X1E19,
0X1E91,0X1F09,0X1F81,0X1FF9,0X2071,0X20E9,0X2161,0X21D9,0X2251,0X22C9,
0X2341,0X23B9,0X2431,0X24A9,0X2521,0X2599,0X2611,0X2689,0X2701,0X2779,
0X27F1,0X2869,0X28E1,0X2959,0X29D1,0X2A49,0X2AC1,0X2B39,0X2BB1,0X2C29,
0X2CA1,0X2D19,0X2D91,0X2E09,0X2E81,0X2EF9,0X2F71,0X2FE9,0X3061,0X30D9,
0X3151,0X31C9,0X3241,0X0721,0X0799,0X0811,0X0889,0X0901,0X32B9,0X3331,
0X33A9,0X3421,0X3499,0X3511,0X3589,0X3601,0X3679,0X36F1,0X3769,0X37E1,
0X3859,0X38D1,0X3949,0X39C1,0X3A39,0X3AB1,0X3B29,0X3BA1,0X3C19,0X3C91,
0X3D09,0X3D81,0X3DF9,0X3E71
};
//***********************************************************************************************************
//************************************************************************************************************
void InitTuner(void)
{
uchar code IniTuner[]=
{
0x2f,            // reg[0x01] <- 0x2F
0x25,            // reg[0x02] <- 0x25
0xc1,            // reg[0x03] <- 0xC1
0x00,            // reg[0x04] <- 0x00
0x63,            // reg[0x05] <- 0x63
0x10,            // reg[0x06] <- 0x10
0x00,            // reg[0x07] <- 0x00
0x29,            // reg[0x08] <- 0x29
0x00,            // reg[0x09] <- 0x00
0x85,            // reg[0x0A] <- 0x85
0x99,            // reg[0x0B] <- 0x99
0xE3,            // reg[0x0C] <- 0xE3
0x28,            // reg[0x0D] <- 0x28
0xF0,            // reg[0x0E] <- 0xF0
0x0F,            // reg[0x0F] <- 0x0F
0x24             /// reg[0x10] <- 0x24
};
I2CWriteBytes(0xC6,0x01,16,IniTuner);
init9886();
}
//************************************************************************************************************
void init9886(void)
{
if(soundif==0)
  {
   I2CWriteByte(0x86, 0x00,0x36); //56  6B2   d6  6B1
   I2CWriteByte(0x86, 0x01,0x30); //70  6B2   63  6B1
   I2CWriteByte(0x86, 0x02,0x0c); //0b  6B2   0f  6B1
  }
else
  {
   I2CWriteByte(0x86, 0x00,0xf6); 
   I2CWriteByte(0x86, 0x01,0x63); 
   I2CWriteByte(0x86, 0x02,0x0c|soundif); 
  }
}
//***********************************************************************************************************
void AutoMemory(void)//收台时屏制式与对应的电视制式一样否则可能漏台。
{
uchar i,j=0,k=0;
bit bTVFound=0,FirstFound=0;
uword wTVFreq;
uchar ctemp;
CloseBlueScreen();
MUTE=1;
remote_data=0XFF;
InitTuner();//电视TDA9887TS与MT2050初始化
//ChannelInit();
i=0;j=0;
wTVFreq=0x0384;//45M
OSDTVShowChannel((idWinColStart+idWinWidth-4),(idWinRowStart+2),BLUE_WHITE,0);//显示TV频道(节目)
while(wTVFreq<=0x4371)//863.25MHZ==0x4371
  {
   i=((wTVFreq-0x0384)/(2*FREQ_1MHZ))%60+1;
   OsdDegreeProgress(idWinColStart,idWinRowStart+idWinTvSetupRowMax,i);//进度条处理
   OSDDrawTVFreq((idWinRowStart+3),(idWinColStart+idWinWidth-9),BLUE_WHITE,wTVFreq);//写频率
   OsdSkipOnOff(1);
   wTVFreq+=2.5*FREQ_1MHZ; //2.5
   bTVFound=ChannelSel(&wTVFreq);
   PressKeyProc(ReadKey());
   if(((remote_data==KEY_UP)||(remote_data==KEY_DOWN)||(remote_data==KEY_STANDBY))&&IR_SUCESS_FLAG)break;
   if(TvAvChange())break;   
   if(bTVFound)
    {
     twdDelay(300);
	 for(k=0;k<100;k++)//确保信号较弱不会漏掉
	   {
	   twdDelay(2);
        ctemp=I2CReadByte(0x54, 0x3A);
        if(ctemp&0x01)
          bTVFound=0;
        else
	      {
		   bTVFound=1;
		   break;
		  }
		}
    if(bTVFound)//去掉信号行场不同步为假台
	  {
       if(((ctemp&0x0f)==0x00))//||((ctemp&0x0f)==0x04)	防止漏台
         bTVFound=0;
       }
	 }
    if(bTVFound)
	 {
	  j++;
      EEPSaveTVChannel(j, wTVFreq);
      OsdSkipOnOff(0);
      OSDTVShowChannel((idWinColStart+idWinWidth-4),(idWinRowStart+2),BLUE_WHITE,j);//显示TV频道(节目)
      }
   }
twdDelay(NVRDELAY);
Write24LC16Byte(idTVMAX,j);
twdDelay(2);
for(i=j+1;i<101;i++)
  EEPSaveTVChannel(i, 0x8384);
MUTE=1;
Write24LC16Byte(idTVsavenum1,1);
OsdSkipOnOff(0);
wTVFreq=TVSetChannel(1);
OSDTVShowChannel((idWinColStart+idWinWidth-4),(idWinRowStart+2),BLUE_WHITE,1);//显示TV频道(节目)
SetTuner(wTVFreq);
OSDDrawTVFreq((idWinRowStart+3),(idWinColStart+idWinWidth-9),BLUE_WHITE,wTVFreq);//写频率
OpenBlueScreen();
//twdDelay(250);
if(~press_mute_flag)
MUTE=0;
if(remote_data==KEY_STANDBY&&IR_SUCESS_FLAG)
  {
   OsdDisable();
   standby_off();
  }
remote_data=0XFF;
}
//************************************************************************************************************
//************************************************************************************************************
//************************************************************************************************************
bool ChannelSel(uword *wTVFreq)
{
static bit bTvFound08=0,bTvFound07=0;
//static uchar cPreTemp1=0;
uchar cTemp,cTemp1;//temp1,
SetTuner(*wTVFreq);
twdDelay(70); //50
cTemp=TunerReadByte(0x86);
if(cTemp&0x80)//Lock
  {
   cTemp1=(cTemp&0x1E)>>1;
   if(cTemp1!=0x07&&cTemp1!=0x08)
   {bTvFound07=0;bTvFound08=0;}
   /*if(cTemp1<0x07){(*wTVFreq)+=(cTemp1+1)/2;return TRUE;}	//50K one step
   else if(cTemp1>0x08){(*wTVFreq)-=(0X10-cTemp1)/2;return TRUE;}
   else if(cTemp1==0x07)
       {
	   if(~bTvFound08)
		  {
		  (*wTVFreq)-=(2.5-0.6)*FREQ_1MHZ; //防止进入死循环0.6
		  bTvFound07=1;
		  }
		else if(~bTvFound07&&bTvFound08)
          {
		  (*wTVFreq)-=(2.5-0.3)*FREQ_1MHZ;//0.3
		  bTvFound07=1;
		  }
		  return FALSE;
		}
   else if(cTemp1==0x08)
       {
	   if(~bTvFound07)
		  {
		  (*wTVFreq)-=(2.5-0.6)*FREQ_1MHZ; //防止进入死循环0.6
		  bTvFound08=1;
		  }
		else if(~bTvFound08&&bTvFound07)
          {
		  (*wTVFreq)-=(2.5-0.3)*FREQ_1MHZ;//0.3
		  bTvFound08=1;
		  }
		  return FALSE;
		}*/
   switch(cTemp1)
	 {
	  case 0:case 0x0f:
		return TRUE;break;
      case 0x01:case 0x02: //(*wTVFreq)+=(cTemp1+1)/2;
		(*wTVFreq)++;return TRUE;break;
      case 0x03:case 0x04:
		(*wTVFreq)+=2;return TRUE;break;
      case 0x05:case 0x06:
		(*wTVFreq)+=3;return TRUE;break;
	  case 0x07://收台时间与此关系较大
		if(~bTvFound08)
		  {
		  (*wTVFreq)-=(2.5-0.6)*FREQ_1MHZ; //防止进入死循环0.6
		  bTvFound07=1;
		  }
		else if(~bTvFound07&&bTvFound08)
          {
		  (*wTVFreq)-=(2.5-0.3)*FREQ_1MHZ;//0.3
		  bTvFound07=1;
		  }
		  return FALSE;
		  break;
      case 0x08://收台时间与此关系较大
	    if(~bTvFound07)
		  {
		   bTvFound08=1;
		   (*wTVFreq)-=(2.5+0.6)*FREQ_1MHZ; //防止进入死循环 0.6  (0.8M会进入死循环)
		   }
		 else if(bTvFound07&&~bTvFound08)
		   {
		   	(*wTVFreq)-=(2.5+0.3)*FREQ_1MHZ;//0.3
			bTvFound08=1;
		   }return FALSE;break; 
      case 0x09:case 0x0A: //(*wTVFreq)-=(0X10-cTemp1)/2;
        (*wTVFreq)-=3;return TRUE;break;
      case 0x0B:case 0x0C:
        (*wTVFreq)-=2;return TRUE;break;
      case 0x0E:case 0x0D:
        (*wTVFreq)--;return TRUE;break;
      }			  
  }
/*if(bTvFound08&&~bTvFound07) {(*wTVFreq)-=(2-0.3)*FREQ_1MHZ;bTvFound07=1;}//防止弱信号
else if(bTvFound07&&~bTvFound08) {(*wTVFreq)-=(2+0.3)*FREQ_1MHZ;bTvFound08=1;}//防止弱信号
else{*/bTvFound07=0;bTvFound08=0;//}
return FALSE;
}
//************************************************************************************************************
void SetTuner(uword wChanneF)
{
//if(soundif==0)
//SetTuner1(wChanneF,0x02f8,0x87);  //45.75
//else
SetTuner1(wChanneF,0x02f8,0xaf);  //0x2f8 38MHz 0x30a 38.9MHz
}
void SetTuner1(uword wChanneF,uword wif2,uchar cfifbw)
{
uchar n,m,i,cNum1,cDiv1A,cDiv1B,cDiv2A,cDiv2B,cReg[5];
uword wFreqLO1,wFreqLO2,wFreq_Temp1,wLO1I,wLO2I,wNum2;
udword dwTemp;
init9886();
wChanneF&=0x7fff;
wChanneF+=wif2;
if((wChanneF-wif2)%FREQ_1MHZ<(FREQ_1MHZ>>1))
wFreqLO1=wChanneF+IF1_FERQ-wif2-(wChanneF+IF1_FERQ-wif2)%FREQ_1MHZ;
else
wFreqLO1=wChanneF+IF1_FERQ-wif2-(wChanneF+IF1_FERQ-wif2)%FREQ_1MHZ+FREQ_1MHZ;
wFreqLO2=wFreqLO1-wChanneF;
i=0;
n=1;
do{
   if(i>11)break;
   for(m=n+1;m<12;m++)
	 {
      dwTemp=(n*wFreqLO1<m*wFreqLO2)?(m*wFreqLO2-n*wFreqLO1):(n*wFreqLO1-m*wFreqLO2); 
      if(dwTemp<=(wFreqLO2-wif2-(cfifbw>>1)))
		{
		 if((dwTemp<wif2+(cfifbw>>1))&&(dwTemp>wif2-(cfifbw>>1)))
		   {
			n=0;
			i++;
			if(i%2)
			  {
			   wFreqLO2=wFreqLO2+i*FREQ_1MHZ;
			   wFreqLO1=wFreqLO1+i*FREQ_1MHZ;
			   }
			   else
			   {
			   wFreqLO2=wFreqLO2-i*FREQ_1MHZ;
			   wFreqLO1=wFreqLO1-i*FREQ_1MHZ;
			   }
			}
			 break;
		 }
	 }
n++;
}while(n<11);
//************************************************************************************************************
wLO1I=wFreqLO1/(4*FREQ_1MHZ);
wLO2I=wFreqLO2/(4*FREQ_1MHZ);
wFreq_Temp1=((wFreqLO1%(4*FREQ_1MHZ))*4+(2*FREQ_1MHZ))/(4*FREQ_1MHZ);
cNum1=(uchar)wFreq_Temp1;
dwTemp=((((udword)(wFreqLO2))%(4*FREQ_1MHZ))*4095+2*FREQ_1MHZ)/(4*FREQ_1MHZ);
wNum2=(uword)(dwTemp);
wFreq_Temp1=wLO1I/12-1;
cDiv1A=(uchar)wFreq_Temp1;
wFreq_Temp1=wLO1I%24;
cDiv1B=(uchar)wFreq_Temp1%12;
wFreq_Temp1=wLO2I/8-1;
cDiv2A=(uchar)wFreq_Temp1;
wFreq_Temp1=wLO2I%8;
cDiv2B=(uchar)wFreq_Temp1;
//4
if(wChanneF<(FREQ_275M+wif2))
  cReg[0]=128+4*cDiv1B+cNum1;
else
  cReg[0]=4*cDiv1B+cNum1;
cReg[1]=cDiv1A;
cReg[2]=cDiv2B*32+(uchar)((wNum2/256)&0x000f);
cReg[3]=(uchar)(wNum2);
if(wNum2==0)
  cReg[4]=cDiv2A;
else
  cReg[4]=cDiv2A+0x40;
n=0;
do {
  m =I2CReadByte(0xc6,0x07);//lock
  if ((m&0x88)==0x88)break;
  delay_ms_ir(40);
  n++;
  } while(n< 200);
if(soundif==0)
I2CWriteByte(0x86, 0x00,0x16);
else
I2CWriteByte(0x86, 0x00,0xd6);
I2CWriteBytes(0xc6,0x01,5,cReg);
}
//************************************************************************************************************
void AdjTVChannel(signed char  sStep, bit bShow)//调整频道
{
uchar cNum, cNum_b,cTotal;
uword wTemp;
cTotal=Read24LC16Byte(idTVMAX);
cNum =Read24LC16Byte(idTVsavenum1);
if(cNum>cTotal)
  cNum=cTotal;
if(cNum==0)
  cNum=1;
Write24LC16Byte(idTVsavenum2, cNum);
cNum_b=cNum;
twdDelay(10);
do{
   cNum+=sStep;
   if(sStep)
     {
	  if(cNum>cTotal)
		cNum=1;
      else if(cNum<1)
		cNum=cTotal;
	 }
   wTemp=TVSetChannel(cNum);
   if(wTemp&0x8000)m_bTV_Skip=1;
   else m_bTV_Skip=0;
}while(m_bTV_Skip&&(cNum_b!=cNum)&&sStep);
Write24LC16Byte(idTVsavenum1, cNum);
if(~bShow)
  {
   MUTE=1;
   twdDelay(500);
   SetTuner(wTemp);
   if(~press_mute_flag)
     MUTE=0;
  }
else
  {
   MUTE=1;
   twdDelay(500);
   osd_tv_ch(cNum);
   SetTuner(wTemp);
   if(~press_mute_flag)
     MUTE=0;
  }
remote_data=0xff;
}
//************************************************************************************************************
uword TVSetChannel(uchar cNum)//从24LC16读频
{
uword wTemp;
if(cNum>0&&cNum<101&&soundif<4)//CATV
{
twdDelay(2);
wTemp=Read24LC16Byte(idTV_CHANNEL_STAT+(uword)((cNum-1)*2));
wTemp<<=8;
twdDelay(2);
wTemp|=Read24LC16Byte(idTV_CHANNEL_STAT+(uword)((cNum-1)*2+1));
}
else 
wTemp=0x8384;//45MHz
return wTemp;
}
//************************************************************************************************************
uchar JudgeBand(uword wTVFreq)
{
uchar cBand;
if(wTVFreq<VLMAX)
  cBand=0;
else if(wTVFreq>VHMAX)
  cBand=2;
else
  cBand=1;
return(cBand);
}
//************************************************************************************************************
void tv_return_memory(void)//电视回看
{
uchar cNum,temp_num;
uword wTVFreq;
twdDelay(2);
cNum=Read24LC16Byte(idTVsavenum2);
MUTE=1;
twdDelay(500);
osd_tv_ch(cNum);
wTVFreq=TVSetChannel(cNum);
SetTuner(wTVFreq);
temp_num=Read24LC16Byte(idTVsavenum1);
twdDelay(2);
Write24LC16Byte(idTVsavenum2, temp_num);
twdDelay(2);
Write24LC16Byte(idTVsavenum1, cNum);
if(~press_mute_flag)
MUTE=0;
}
//************************************************************************************************************
void exchange_channel(uchar tvnum1,uchar tvnum2)
{
uword wTVFreq1,wTVFreq2;
uchar temp_num;
if(tvnum1>Read24LC16Byte(idTVMAX))
   {
    twdDelay(2);
    Write24LC16Byte(idTVMAX, tvnum1);
   }
if(tvnum2>Read24LC16Byte(idTVMAX))
  {
   twdDelay(2);
   Write24LC16Byte(idTVMAX, tvnum2);
  }
if(tvnum1<201&&tvnum2<201)
{
 twdDelay(2);
 wTVFreq1 =TVSetChannel(tvnum1);
 twdDelay(2);
 wTVFreq2 =TVSetChannel(tvnum2);
 twdDelay(2);
 EEPSaveTVChannel(tvnum2, wTVFreq1);
 twdDelay(2);
 EEPSaveTVChannel(tvnum1, wTVFreq2);
 twdDelay(2);
}
temp_num=Read24LC16Byte(idTVsavenum1);
if(temp_num==tvnum2||temp_num==tvnum1)
  {
   MUTE=1;
   twdDelay(500);
   wTVFreq2=TVSetChannel(temp_num);
   SetTuner(wTVFreq2);
   if(~press_mute_flag)
     MUTE=0;
  }
}
//************************************************************************************************************
void copy_channel(uchar tvnum1,uchar tvnum2)
{ 
uword wTVFreq2;
uchar temp_num;
if(tvnum2>Read24LC16Byte(idTVMAX))
    {
    twdDelay(2);
    Write24LC16Byte(idTVMAX, tvnum2);
    }
if(tvnum1<101&&tvnum2<101)
  {
  twdDelay(2);
  wTVFreq2=TVSetChannel(tvnum1);
  twdDelay(2);
  EEPSaveTVChannel(tvnum2, wTVFreq2);
  twdDelay(2);
  }
temp_num=Read24LC16Byte(idTVsavenum1);
if(temp_num==tvnum2)
  {
   MUTE=1;
   twdDelay(500);
   wTVFreq2=TVSetChannel(temp_num);
   SetTuner(wTVFreq2);
   if(~press_mute_flag)
     MUTE=0;
  }
}
//************************************************************************************************************
void allclearchannel(void)
{
 uchar i,cTvNum;
 uword temp;
 cTvNum=Read24LC16Byte(idTVMAX);
 twdDelay(2);
 for(i=1;i<cTvNum;i++)
 {
 twdDelay(2);
 temp=TVSetChannel(i);
 if(temp&0x8000)
   continue;
 EEPSaveTVChannel(i, temp|0x8000);
 osd_timer_start();
 }
temp=TVSetChannel(1);
MUTE=1;
twdDelay(500);
SetTuner(temp);
if(~press_mute_flag)
  MUTE=0;
}
//************************************************************************************************************
void ChannelInit(void)
{
uchar i;
for(i=0;i<100;i++)
EEPSaveTVChannel((i+1), 0x8384);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -