📄 lc72130.c
字号:
//*****************************************************************************
//
// File Name : 'lc72130.c'
// Title : Radio PLL
// Author : Ipman Robin
// Created : 1/8/2007
// Revised : 1/13/2008
// Version : 2.0
// Target MCU : Atmel AVR Mega 32
// Editor Tabs : 4
//
// Description : Radio PLL Control Use LC72130/LC72131
//
//
//*****************************************************************************
#include "system.h"
#include "kb_include.h"
IN1 in1; //发送数据格式1 MCU->72130
IN2 in2; //发送数据格式2 MCU->72130
//发送命令,同时将总线上的数据保存到输入缓冲中
static void pll_send_cmd(char addr,char* data)
{
BYTE i;
Clr_SS(); //拉低CE,发送地址
_delay_us(20);
spi_send_byte(addr);
Set_SS(); //拉高CE,发送数据
for(i=3;i>0;i--)
{
spi_send_byte(*data++);
}
Clr_SS();
}
void radio_sel_st(void)
{
radioParam ^= RA_ST;
#ifdef LCD_316
memset(tmpDispBuff,0,sizeof(tmpDispBuff));
#endif
if (radioParam&RA_ST)
{
in2.B.SNC = LOW;
#ifdef LCD_316
disp_string(tmpDispBuff,"ST ON",1,5);
#endif
}else{
in2.B.SNC = OPEN;
#ifdef LCD_316
disp_string(tmpDispBuff,"ST OFF",1,6);
#endif
}
disp_st(radioParam&RA_ST);
pll_send_cmd(LC72130_IN2,(char*)&in2);
#ifdef LCD_316
display_buff(tmpDispBuff);
delay_ms(500);
#endif
}
//计算实际频率,此处仅假设步进频率为FM为50K,中波为9K,不完整函数
//返回单位是KHZ
UINT16 radio_freq_to_pll_val(char band,UINT16 freq,BYTE step)
{
if(band==FM)
{
if(step>10)
step=10;
//if(regionIndex==REGION_JAPAN)//日本高频头中频 -10.7M
if(tunnerType==CET_JAPAN)
return (UINT16)((freq-FM_IF_FREQ)/step);
else
return (UINT16)((freq+FM_IF_FREQ)/step);
}else{//AM
if(tunnerType==CET6000)
return (UINT16)(freq+AM_IF_FREQ);
else
//return (UINT16)((freq+FM_IF_FREQ2)/step);
return (UINT16)((freq+FM_IF_FREQ2));
}
//return 0;
}
void radio_set_loc(BYTE mode)
{
if(mode)
{
in2.B.LOC = OPEN;
}else{
in2.B.LOC = LOW;
}
}
//初始化波段,仅开机调用
void radio_set_band(char band)
{
//先初始化公共部分
//初始化输出命令1
in1.B.XS = XS4_5M; //选择0为4.5MHZ晶体
in1.B.CTE = CTE_RESET; //锁相环内部使能位设置0复位设置为1开始计数.
//初始化输出命令2,不同的方案连线可能不一致,需要分别设置
#ifdef _MB653_ //不同机型IO接口连接不一致,需要单独设置
in2.B.IOC1 = IO_IN; //设置为输入模式 0
in2.B.IOC2 = IO_IN; //设置为输入模式 0
in2.B.IO1 = OPEN; // IO1未用,置空 0
in2.B.IO2 = OPEN; // IO2未用,置空 0
#elif defined(_MB633_) || defined(_MB655_)
in2.B.IOC1 = IO_OUT; //设置为输入模式 LOC
in2.B.IOC2 = IO_IN; //设置为输入模式 0
in2.B.B05 = OPEN;
#endif
//in2.B.SNC = LOW; //BO1 噪音控制打开 1
in2.B.FMB = OPEN; //BO2 上电初始化不提供FM电源 0
in2.B.STRQ = LOW; //BO3 设置为接收状态 0
in2.B.LOC = LOW; //LOW BO4 FMAGC 关闭 1
in2.B.AMB = OPEN; //BO5 上电初始化不提供AM电源 0
in2.B.DOC = DOC_END_UC; //_QUICK_SEARCH_
// in2.B.DOC = DOC_UNLOCK_LOW; //DOUT脚如未锁定输出低 0
#ifdef CE6000
in2.B.UL = UL_55US; //UL_55US; // E is extended by 1 to 2 ms UL_111US
#else
in2.B.UL = UL_55US; //UL_55US; // E is extended by 1 to 2 ms UL_111US
#endif
in2.B.DZ = DZA; //DZA此设置效果不是很明显可以设置捕捉范围
in2.B.TBC = OFF; //设置为1时B01将输出8HZ的基准信号
//但是BO1本收音电路设置为FM/AM转换,应设置为零
in2.B.DLC = DLC_NORMAL; //设置电荷泵正常输出
//in2.B.IFS = ON; //ON//////ON灵敏度控制,中频输入信号强度控制设置此状态,最大限度的减少误台
in2.B.TEST = 0; //必须设置为0
//再根据不同的波段设置不同的部分
if(band==FM)
{
radio_init_FM();
if(rdsEnable)
RDS_ON();
}else{
radio_init_AM();
RDS_OFF();
}
//发送到LC72130
pll_send_cmd(LC72130_IN2,(char *)&in2);
pll_send_cmd(LC72130_IN1,(char *)&in1);
}
//初始化AM,开机或切换波段时调用
void radio_init_AM(void)
{
//#ifdef CE6000
in1.B.XSREF = STEP1000; //1K
//#else
// if(freqParam[regionIndex][AM_FREQ_STEP]==9)
// in1.B.XSREF = STEP9000; //AM步进9K
// if(freqParam[regionIndex][AM_FREQ_STEP]==10)
// in1.B.XSREF = STEP5000;//STEP10000; //10K
//#endif
in1.B.SNS = ON; //输入频率范围0.5-10MHZ AMIN2: 2-40M
in1.B.DVS = OFF;
in2.B.SNC = LOW; //OPEN
in2.B.GT = GT_32MS; //GT_32MS ,提高精度
in2.B.FMB = OFF; //关闭FM电源
in2.B.AMB = ON; //AM提供8V
in2.B.IFS = OFF;
#ifdef LCD_BIT_ST
disp_set_bit(dispBuff,LCD_BIT_ST,OFF);
#endif
#ifdef LCD_BIT_STEREO
disp_set_bit(dispBuff,LCD_BIT_STEREO,OFF);
#endif
#ifdef LCD_BIT_TA
disp_set_bit(dispBuff,LCD_BIT_TA,OFF);
#endif
#ifdef _SUPPORT_RDS
rds_clear();
#endif
}
void radio_close(void)
{
delay_ms(100);
in2.B.FMB = OFF;
in2.B.AMB = OFF;
pll_send_cmd(LC72130_IN2,(char *)&in2);
}
//初始化FM,开机或切换波段时调用
void radio_init_FM(void)
{
//in1.B.XSREF = STEP50000; //FM步进50K*2
in1.B.SNS = OFF; //输入频率范围10-160MHZ
in1.B.DVS = ON;
in2.B.AMB =OFF; //关闭AM
in2.B.FMB = ON; //FM提供8V
in2.B.IFS = ON;
if(radioParam&RA_ST)
{
in2.B.SNC= LOW; //Stereo
}else{
in2.B.SNC= OPEN; //Mono
}
disp_st(radioParam&RA_ST);
#if FM_GT_MEASURE==4
in2.B.GT = GT_4MS; //GT_4MS将中频测量时间设置为4MS设置太高自动搜索整个频段将会很长
#endif
#if FM_GT_MEASURE==8
in2.B.GT = GT_8MS;
#endif
#if FM_GT_MEASURE==32
in2.B.GT = GT_32MS;
#endif
#if FM_GT_MEASURE==64
in2.B.GT = GT_64MS;
#endif
}
void radio_save_last_station(BYTE subBand,UINT16 freq)
{
if(subBand<6)
bandLastFreq[regionIndex][subBand-1] = freq;
}
//配置分频比参数
void pll_set_freq_ref(BYTE fref)
{
switch(fref)
{
case 1:
in1.B.XSREF = STEP5000; //5K, for ORIENT ONLY
break;
case 5:
in1.B.XSREF = STEP25000;//25K, for 50K STEP
break;
case 10:
in1.B.XSREF = STEP50000;//50K, for 100K STEP
break;
default:
in1.B.XSREF = STEP50000;//50K, for 200K STEP
break;
}
}
//直接跳转到固定频率,搭配pll_is_station(),resetCTE()函数可以实现自动搜索
//参数 freq: Khz
void pll_set_station(char band,UINT16 freq)
{
UINT16 freqVal;
in2.B.STRQ = 1;//接收状态
pll_send_cmd(LC72130_IN2,(void*)&in2);
if(band==FM)
{
if(freq<=ORIT_JUMP_FREQ1)
{
pll_set_freq_ref(ORIT_LOW_STEP); //10K STEP
freqVal = radio_freq_to_pll_val(band,freq,ORIT_LOW_STEP);
}else{
pll_set_freq_ref(freqParam[regionIndex][FM_FREQ_FINE]);
freqVal = radio_freq_to_pll_val(band,freq,freqParam[regionIndex][FM_FREQ_FINE]);
}
}else{
freqVal = radio_freq_to_pll_val(band,freq,freqParam[regionIndex][AM_FREQ_STEP]);
}
in1.B.FRQ = freqVal;
pll_send_cmd(LC72130_IN1,(void*)&in1);
}
void pll_reset_CTE(char band,UINT16 freq)
{
UINT16 freqVal;
if(band==FM)
{
if(freq<=ORIT_JUMP_FREQ1)
{
pll_set_freq_ref(ORIT_LOW_STEP); //10K STEP
freqVal = radio_freq_to_pll_val(band,freq,ORIT_LOW_STEP);
}else{
pll_set_freq_ref(freqParam[regionIndex][FM_FREQ_STEP]);
freqVal = radio_freq_to_pll_val(band,freq,freqParam[regionIndex][FM_FREQ_STEP]);
}
}else{
freqVal = radio_freq_to_pll_val(band,freq,freqParam[regionIndex][AM_FREQ_STEP]);
}
in2.B.STRQ = 0;//搜索状态
pll_send_cmd(LC72130_IN2,(char*)&in2);
in1.B.FRQ = freqVal;
in1.B.CTE = 0; //clear IF Count
pll_send_cmd(LC72130_IN1,(char*)&in1);
if(band==AM)
{
sys_seek_delay(AM_CTE_RESET_LOOPS);
}else{
if((tunnerType==CET6000))
{
sys_seek_delay(CTE_RESET_LOOPS_NORDS);
}
if(!rdsEnable)
sys_seek_delay(CTE_RESET_LOOPS_NORDS);
else
sys_seek_delay(CTE_RESET_LOOPS);
}
pll_send_cmd(LC72130_IN2,(char*)&in2);
in1.B.CTE = 1; //reset CTE
pll_send_cmd(LC72130_IN1,(char*)&in1);
//delay_ms(10);
}
BYTE isStereo(void)
{
#ifdef SD
if(bit_is_clear(PIN_SD,SD))
return TRUE;
#else
BYTE cmdBuff[3];//保存返回的值
if(!bRadioSeeking)
{
pll_shift_data(LC72130_OUT,cmdBuff);//发送地址
if((cmdBuff[0]&IO_ST)==0)
{
return TRUE;
}
}
#endif
return FALSE;
}
//判断是否为锁定的台,返回0:未锁定,返回 1:锁定
//参数:band 波段
// gtms 延时ms
signed char pll_is_station(char band,UINT16 freq)
{
BYTE i;
BYTE cmdBuff[3];//保存返回的值
UINT32 if_count=0;
BYTE timeoutIFS=0;
while(IFC_GETTING)//等待DO置低 100ms超时
{
timeoutIFS++;
if(!timeoutIFS)
break;
sys_seek_delay(1);
_delay_ms(1);
}
//delay_ms(150);
//发送3个0,用于获得IF数据
for(i=0;i<3;i++)
cmdBuff[i] = 0;
pll_shift_data(LC72130_OUT,cmdBuff); //发送地址
/*
//获取返回的中频 调试用
disp_char(dispBuff,1,'0'+(cmdBuff[0]&0x0F));
disp_char(dispBuff,2,'0'+(cmdBuff[1]>>4));
disp_char(dispBuff,3,'0'+(cmdBuff[1]&0x0F));
disp_char(dispBuff,4,'0'+(cmdBuff[2]>>4));
disp_char(dispBuff,5,'0'+(cmdBuff[2]&0x0F));
delay_ms(500);
*/
if_count = (((UINT32)(cmdBuff[0]&0x0F)<<16) | ((UINT16)cmdBuff[1]<<8) | (BYTE)cmdBuff[2]) & 0xFFFFF;
//if( bit_is_set(cmdBuff[0],BIT_UL) ) //UL是否锁定
if(band == FM)
{
if(freq>ORIT_JUMP_FREQ1)
{
if(radioParam&RA_LOC)
{
if((if_count<=FM_IF_CNT_MAX1844) && (if_count>=FM_IF_CNT_MIN1844))//判断是否10700(10.7M)
{
#ifdef LA1844
if(adcValue[AD_SMETER]>ADC_SMETER_SEEK)
return TRUE;
else
return FALSE;
#endif
return TRUE;
}
}else if((if_count<=FM_IF_CNT_MAX) && (if_count>=FM_IF_CNT_MIN))//判断是否10700(10.7M)
{
#ifdef LA1844
if(adcValue[AD_SMETER]>ADC_SMETER_SEEK)
return TRUE;
else
return FALSE;
#endif
return TRUE; //已锁定
}
}else{
if((if_count<=FM_IF_CNT_MAX_ORIT) && (if_count>=FM_IF_CNT_MIN_ORIT))//判断是否10700(10.7M)
{
return TRUE; //已锁定
}
}
}else{ //AM
if((if_count<AM_IF_CNT_MAX) && (if_count>AM_IF_CNT_MIN))//判断是否450K
{
return TRUE; //已锁定
}
}
#ifndef LA1844
if(tunnerType==CET_FM)
{
if(adcValue[AD_SMETER]>ADC_SMETER_SEEK)
return TRUE;
}
#endif
return FALSE; //未锁定
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -