📄 lc72131.c.txt
字号:
/*
* LC72131 PLL AM/FM/SWê?ò??????÷
* ′|àí?÷ààDí£oC51,AVR
* °?±?£o1
* è??ú£o2006-12-14
* ×÷??£o??μ?í?<yangdewang@gmail.com>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA. Or, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
#include <math.h>
#include "radio.h"
#include "LC72131.h"
#include "arith.h"
#include "spi2.h"
#include "Clock.h"
#include <global.h>
////?¨ò?êy?Y?ó?úòy??
#ifdef __AVR__
static void inline setCE()
{
PORT_Readio |= (1<<ReadioSTB);
}
static void inline clCE()
{
PORT_Readio &=~(1<<ReadioSTB);
}
#elif defined (__C51__)
#define setCE() (LC72131_STB=true)
#define clCE() (LC72131_STB=false)
#endif
//?¨ò?òy??
#define AM_FM_SW_PIN BO1
#define IF_REQ_PIN BO2
#define ST_MO_SW_PIN BO3
#define ST_OUT_BIN IO2
#define InMod1 0x28 //add
#define InMod2 0x29 //add
#define OutMod 0x2a //add
#define con1 LC72131IM1.LC72131IM1
#define con2 LC72131IM2.LC72131IM2
#define indat LC72131OM.LC72131OM
#define C1 1 //?üá?1
#define C2 0 //?üá?2
#define write(dat) VSPI2_MasterTransmitLSB(dat)
#ifndef SAVE_RADIO_SETTING
RadioMode LC72131RadioMode = DefaultRadioMode;//?a0=am
#endif//SAVE_RADIO_SETTING
static uint8 perchdata frequencyTmp[SeekPointCount];
uint8 CurrentSeekPoint_Radio;//μ±?°?o′??°?D?μ??2??±frequencyTmp μ???ò?á?
uint8 LC72131CurrentFrequency;//μ±?°LC72131μ?1¤×÷?μ?ê£?êμ?ê?μ?êòò2¨??2?í?óD2?í?μ?????·?·¨£¨è?é?£?
union LC72131IntputCom1 LC72131IM1;
union LC72131IntputCom2 LC72131IM2;
union LC72131OutputCom LC72131OM;
uint8 LC72131SeekSatrtTime;//???÷?aê?ê±??
bool RadioLocked;//μ÷ó?LC72131IsLock()oó£?ó?óú?D??ê?·?óDì¨
bool LC72131SeekWait;//?aò?±íê?LC72131.C′|óúμèμ??áè??D?μ??êyê±????
bool LC72131SeekFlag;//???ˉ×??ˉ??ì¨ê±±???ò?£????÷?áê?ê±±?×??ˉ??á?
static bool LC72131SeekWay; //×??ˉ??ì¨ê±μ??μ?ê?ü??·??ò
void WriteConLC72131(bool ConOneOrTow)//D′?üá?μ?lc72131 ConOneOrTow = 1,?üá?1;=0 ?üá?2//ret: CE=0,CL=1
{
#ifdef VSPI_SYNCHRO_U
InVSPI();
#endif //VSPI_SYNCHRO_U
uint8* tmp,com;
if(ConOneOrTow)
{
tmp = LC72131IM1.dat;
com = InMod1;
}
else
{
tmp = LC72131IM2.dat;
com = InMod2;
}
clCE();
write(com);
setCE();
write(*tmp);
tmp++;
write(*tmp);
tmp++;
write(*tmp);
clCE();
#ifdef VSPI_SYNCHRO_U
OutVSPI();
#endif //VSPI_SYNCHRO_U
}
void ReadConLC72131()//?áè?
{
#ifdef VSPI_SYNCHRO_U
InVSPI();
#endif //VSPI_SYNCHRO_U
clCE();
write(OutMod);
// VSPI_MSB_FIRST();
setCE();
// _delay_loop_1(1);//cano
LC72131OM.dat[2] = VSPI2_MasterTransmitMSB(0xff);
#if defined(__C51__)//C51????μí×??ú
LC72131OM.dat[0] = VSPI2_MasterTransmitMSB(0xff);
LC72131OM.dat[1] = VSPI2_MasterTransmitMSB(0xff);
#else
LC72131OM.dat[1] = VSPI2_MasterTransmitMSB(0xff);
LC72131OM.dat[0] = VSPI2_MasterTransmitMSB(0xff);
#endif
clCE();
#ifdef VSPI_SYNCHRO_U
OutVSPI();
#endif //VSPI_SYNCHRO_U
}
void LC72131Mute(bool of)//??ò? of=false->???ó?D?μê?3??ó??ò?
{
if(of)
con2.IF_REQ_PIN = 1;//1?±??D?μê?3?????ò?
else
con2.IF_REQ_PIN = 0;//???ó?D?μê?3??ó??ò?
WriteConLC72131(C2); //D′?üá?2
}
void LC72131SeekFrequency(bool seek) //éè???μ?ê//fm = f*50k ,am = f*9k,sw = f*5k μ÷ó?·?·¨?°???èéè???°LC72131CurrentFrequency?±;seek = true ????DD?D?μ??êy//μè′y40msoóμ÷ó??°LC72131IsLock?°?D??ê?·?óDì¨
{
uint16 f;
switch(LC72131RadioMode)
{
case RM_AM:
{
f = 800+((uint16)LC72131CurrentFrequency)*16;//450k/9k<<4 + f<<4
break;
}
#ifdef UseSW
case RM_SW:
{
f = 90+LC72131CurrentFrequency;//450k/5k
break;
}
#endif
case RM_FM:
{
f = (107+FMFrequencyExcursion*10+(uint16)LC72131CurrentFrequency)/2;//10.7m//100k//×?μí?μ?ê87.00M
break;
}
}
con1.P_CTR_L = f;
con1.P_CTR_H = (f>>8);
//reset IFcounter
con1.CET = 0;
WriteConLC72131(C1); //D′?üá?1
//ShowRadio(true);////////todo
if(!seek)
return;
//start IFcounter
LC72131Mute(false);
con1.CET = 1;
WriteConLC72131(C1); //D′?üá?1
LC72131SeekWait = true;
LC72131SeekSatrtTime = SysClick;
}
void SetRadioMode(RadioMode mode)//éè??ê?ò??ú2¨??
{
con1.AM_FM = LC72131RadioMode = mode;
if(mode==RM_FM)
{
con2.AM_FM_SW_PIN = 0;
//LC72131CurrentFrequency = FMFrequency;
//con1.R_CRT = 8;//2???10khz
//con1.R_CRT = 1;//2???50khz
con1.R_CRT = 0;//2???100khz
SetRadioStation(FMStation);
}
else
{
con2.AM_FM_SW_PIN = 1;
#ifndef UseSW
//LC72131CurrentFrequency = AMFrequency;
con1.R_CRT = 9;//2???9khz
SetRadioStation(AMStation);
#endif
#ifdef UseSW
if(mode==RM_AM)
{
//LC72131CurrentFrequency = AMFrequency;
con1.R_CRT = 9;//2???9khz
SetRadioStation(AMStation);
}
else
{
con1.R_CRT = 10;//2???5khz
SetRadioStation(SWStation);
}
#endif
}
WriteConLC72131(C2); //D′?üá?2
}
void IniLC72131()
{
#ifdef __AVR__
DDR_Readio |= (1<<ReadioSTB);
#endif
clCE();
/*
SetRadioMode(LC72131RadioMode);
con1.CET = 0;
con1.XS = 0; //4.5Mhz
con2.IO_C1 = 0; //inport
con2.IO_C2 = 0;
con2.ST_OUT_BIN = 0;//open
con2.IF_REQ_PIN = 1;
con2.DNC = 0;
con2.DO_C = 0; //open
con2.UNLOCK= 0;
con2.DZ_C = 3;
con2.IF_CAT= 2; //32ms
con2.TBC = 0;
con2.DLC = 0;
con2.IFS = 1;
con2.TEST = 0;
*/
LC72131IM1.dat[0] = 0xd1;
LC72131IM1.dat[1] = 0x03;
LC72131IM1.dat[2] = 0x12;
LC72131IM2.dat[0] = 0x20;
LC72131IM2.dat[1] = 0xc0;
LC72131IM2.dat[2] = 0x12;
WriteConLC72131(C1); //D′?üá?1
WriteConLC72131(C2); //D′?üá?2
SetRadioMode(LC72131RadioMode);
}
/*ulong GetCTR()
{
ulong tmp = indat.IF_CTRH;
tmp = tmp<<16;
return (tmp+indat.IF_CTRL);
}*/
uint8 LC72131IsLock() //μ÷ó?oó2aê? RadioLocked ?D??ê?·?óDì¨ return£o?D?μ??2??????죨??μ±μ÷ó?oó RadioLocked == true ê±óDòaò?£?
{
uint16 tmp;
uint8 Patient;
LC72131SeekWait = false;
RadioLocked = false;
ReadConLC72131();//?áè?
if(LC72131RadioMode==RM_FM)
{
if(0x05 == indat.IF_CTRH)//14720//342400
{
tmp = 14720;
Patient = FMLockFrequencyPatient;
}
else
{
return 255;
}
}
else//14400
{
tmp = 14400;
Patient = AMLockFrequencyPatient;
}
tmp = abs(tmp-((int)(indat.IF_CTRL)));
if(tmp<Patient)
{
//frequencyTmp[CurrentSeekPoint_Radio] = tmp;
//CurrentSeekPoint_Radio++;
RadioLocked = true;
return (uint8)tmp;
}
return 255;
}
static void optimization()//ì???×????μμ?//μ÷ó?ê±òa?ófrequencyTmp[CurrentSeekPoint_Radio]?aóDD§êy?Y//LC72131CurrentFrequency?afrequencyTmp[CurrentSeekPoint_Radio-1]′|?μ?ê
//?′CurrentSeekPoint_Radio ???òóDD§êy?Y LC72131CurrentFrequency ?a???¨ê±?μ?ê
{
uint8 i,mini=0;
if(CurrentSeekPoint_Radio)
{
for(i=1;i<=CurrentSeekPoint_Radio;i++)
{
if(frequencyTmp[i]<frequencyTmp[mini])
{
mini = i;
}
}
mini = CurrentSeekPoint_Radio - mini;
if(LC72131SeekWay)
{
LC72131CurrentFrequency -= mini;
}
else
{
LC72131CurrentFrequency += mini;
}
LC72131SeekFrequency(false);
}
LC72131SeekFlag = false;
LC72131Mute(true);
}
/*éè??μ±?°?μ?ê?a??ò?μ?
×¢òa£oè?1?μ±?°?μ?êμ±?°?μ?êò?μ????Tμ÷ó?·?·¨???TD§1?
*/
void LC72131NextFrequemcy()
{
//uint8 oldFrequencyORpiancha = LC72131CurrentFrequency;
//LC72131CurrentFrequency += SeekStep;
switch(LC72131RadioMode)
{
case RM_AM:
{
LC72131CurrentFrequency = MovePointer(MinAMFrequency,MaxAMFrequency,LC72131CurrentFrequency,LC72131SeekWay);//min???T,maxé??T,pointerμ±?°????,direction·??ò£¨true:?ò′ó£?false:?òD?£?,Eddy:è?1??atrue????DDDy×a3?×÷
break;
}
#ifdef UseSW
case RM_SW:
{
LC72131CurrentFrequency = MovePointer(MinSWFrequency,MaxSWFrequency,LC72131CurrentFrequency,LC72131SeekWay);//min???T,maxé??T,pointerμ±?°????,direction·??ò£¨true:?ò′ó£?false:?òD?£?,Eddy:è?1??atrue????DDDy×a3?×÷
break;
}
#endif
case RM_FM:
{
LC72131CurrentFrequency = MovePointer(MinFMFrequency,MaxFMFrequency,LC72131CurrentFrequency,LC72131SeekWay);//min???T,maxé??T,pointerμ±?°????,direction·??ò£¨true:?ò′ó£?false:?òD?£?,Eddy:è?1??atrue????DDDy×a3?×÷
break;
}
}
LC72131SeekFrequency(LC72131SeekFlag);
#if 0
if(oldFrequencyORpiancha == LC72131CurrentFrequency)
{
//RadioAutoSeekFlag = false;
/*if(CurrentSeekPoint_Radio)
{
CurrentSeekPoint_Radio--;
}
optimization();*/
SetRadioStation(0);
}
else
LC72131SeekFrequency(true);
// optimization();
#endif
}
/*
*???ú×??ˉ??ì¨ê±ê1ó?£?2¢?òó|?úLC72131SeekWait??trueoó40msμ÷ó?
*?úLC72131SeekWait??trueμ?ê±oò?ò??±£′?á??μí3ê±??LC72131SeekSatrtTime±?óú????ê±
*/
void LC72131Seek()
{
uint8 piancha = LC72131IsLock();
if(RadioLocked)
{
frequencyTmp[CurrentSeekPoint_Radio] = piancha;
if(CurrentSeekPoint_Radio < (SeekPointCount-1))
{
CurrentSeekPoint_Radio++;
LC72131NextFrequemcy();
}
else
{
optimization();
}
}
else
{
if(CurrentSeekPoint_Radio)
{
CurrentSeekPoint_Radio--;
//??μ±?°?μ?êí???é?′????¨μ??μ?ê
if(LC72131SeekWay)
{
LC72131CurrentFrequency--;
}
else
{
LC72131CurrentFrequency++;
}
optimization();
}
else
{
LC72131NextFrequemcy();
}
}
}
void SetST_MO(bool ST_MO) //′ò?aó?1?±?á¢ì?éùê?3? ST_MO=trueê±á¢ì?éù1?±?
{
con2.ST_MO_SW_PIN = ST_MO;
if(LC72131RadioMode == RM_FM)
WriteConLC72131(C2); //D′?üá?2
}
bool GetST_MO() // ??è?μ±?°éùò?ê?3?×′ì? return:false =á¢ì?éù
{
if(!LC72131SeekWait)
{
ReadConLC72131();//?áè?
//±ü?aReadConLC721313?′íμ????üì¨
//WriteConLC72131(C1); //D′?üá?1
//WriteConLC72131(C2); //D′?üá?1
}
return indat.ST_OUT_BIN;
}
void LC72131SeekStart(bool SeekWay)//?aê???ì¨ SeekWay == true ?a> ?ò???μ????
{
CurrentSeekPoint_Radio = 0;
LC72131SeekWay = SeekWay;
LC72131SeekFlag = true;
LC72131NextFrequemcy();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -