📄 tuner.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 + -