收音头控制程序(LC72130)
无标题 收音头控制程序(LC72130) lc72130 pdf datasheet //------------------------------------------------------------------------ /************************************************************************** // Tuner, VER 1.0 // // COPYRIGHT (C) 2002, Enbia Technology Inc. // Target: 89C5X, PLL IC: LC72130/LC72130M // AUTHOR: STEVEN LUO // // Revision History: // 2000/12/16 - Original Version // 2001/4/3 - V2.0, ported to RTX51TNY // //------------------------------------------------------------------------ #include #include #include #include #include "tuner_int.h" #include "dspenm.h" //--------------------------------------------------------------------------- // Tuner_Initialize //--------------------------------------------------------------------------- void Tuner_Initialize(void){ b_amstep = Read_EEPROM(EE_AMSTEP) & 0x01; band = Read_EEPROM(EE_BAND) & 0x01; cur_count[band] = Read_EEPROM(EE_CURCNT_LOW) + Read_EEPROM(EE_CURCNT_HIGH) * 0x100; Tuner_Set_Frequency_Int(); dwPLL_Shadow_IN2 |= BO2_ON; // Unmute Write_LC72131(MODE_IN1, dwPLL_Shadow_IN1); Write_LC72131(MODE_IN2, dwPLL_Shadow_IN2); } //--------------------------------------------------------------------------- // Tuner_Shutdown //--------------------------------------------------------------------------- void Tuner_Shutdown(BOOL bonoff){ if (bonoff){ Write_LC72131(MODE_IN1, (dwPLL_Shadow_IN1 & 0x0fffff) | PLL_OFF_REF); } else{ Write_LC72131(MODE_IN1, dwPLL_Shadow_IN1); } } //--------------------------------------------------------------------------- // Tuner_Set_AMStep //--------------------------------------------------------------------------- BOOL Tuner_Set_AMStep(BYTE ctrl){ if (ctrl != INQUIRE){ b_amstep = ! b_amstep; Write_EEPROM(EE_AMSTEP, b_amstep); } return b_amstep; } //--------------------------------------------------------------------------- // Tuner_Set_FMStep //--------------------------------------------------------------------------- BOOL Tuner_Set_FMStep(BYTE ctrl){ if (ctrl != INQUIRE){ b_fmstep = ! b_fmstep; } 第 1 页 无标题 return b_fmstep; } //--------------------------------------------------------------------------- // Tuner_Set_Band //--------------------------------------------------------------------------- BYTE Tuner_Set_Band(BYTE ctrl, WORD *freq){ if (ctrl != INQUIRE){ Temp_Mute(1); if (band != BAND_AM) band = BAND_AM; else band = BAND_FM; // 0: am, 1: fm Write_EEPROM(EE_BAND, band); Tuner_Set_Frequency_Int(); dwPLL_Shadow_IN2 |= BO2_ON; // Unmute Write_LC72131(MODE_IN1, dwPLL_Shadow_IN1); Write_LC72131(MODE_IN2, dwPLL_Shadow_IN2); Temp_Mute(0); } *freq = (Count_To_Freq()); return band; } //--------------------------------------------------------------------------- // Tuner_Set_Mono //--------------------------------------------------------------------------- BOOL Tuner_Set_Mono(BYTE ctrl){ if (ctrl != INQUIRE){ Temp_Mute(1); bST_MONO = ! bST_MONO; dwPLL_Shadow_IN2 &= ~BO3_ON; if (bST_MONO) {dwPLL_Shadow_IN2 |= BO3_ON;} // Stereo // Write_LC72131(MODE_IN1, dwPLL_Shadow_IN1); Write_LC72131(MODE_IN2, dwPLL_Shadow_IN2); Temp_Mute(0); } return bST_MONO; } //--------------------------------------------------------------------------- // Tuner_Save_Station //--------------------------------------------------------------------------- void Tuner_Save_Station(BYTE station){ BYTE ee_addr; if (station > MAX_PRESET_NUMBER) station = MAX_PRESET_NUMBER; ee_addr = EE_PRESET_BASE + band * (MAX_PRESET_NUMBER + 1) * 2 + station *2; Write_EEPROM(ee_addr, cur_count[band]/0x100); Write_EEPROM(ee_addr +1, cur_count[band]&0xff); } //--------------------------------------------------------------------------- // Tuner_Restore_Station //--------------------------------------------------------------------------- WORD Tuner_Restore_Station(BYTE station){ BYTE ee_addr; Temp_Mute(1); if (station > MAX_PRESET_NUMBER) station = MAX_PRESET_NUMBER; 第 2 页 无标题 ee_addr = EE_PRESET_BASE + band * (MAX_PRESET_NUMBER + 1) * 2 + station *2; cur_count[band]= Read_EEPROM(ee_addr) * 0x100 + Read_EEPROM(ee_addr +1); Tuner_Set_Frequency_Int(); dwPLL_Shadow_IN2 |= BO2_ON; // Unmute Write_LC72131(MODE_IN1, dwPLL_Shadow_IN1); Write_LC72131(MODE_IN2, dwPLL_Shadow_IN2); // save the current count Write_EEPROM(EE_CURCNT_LOW, cur_count[band] & 0xff); Write_EEPROM(EE_CURCNT_HIGH, cur_count[band] >> 8); Temp_Mute(0); return (Count_To_Freq()); } //--------------------------------------------------------------------------- // Tuner_Set_Frequency //--------------------------------------------------------------------------- WORD Tuner_Set_Frequency(BYTE ctrl, WORD freq){ BAND_INFO code *pBInfo; switch(band){ case BAND_AM: if (b_amstep) pBInfo = &BandInfo_AM_10KHz; else pBInfo = &BandInfo_AM_9KHz; break; case BAND_FM: if (b_fmstep) pBInfo = &BandInfo_FM_100KHz; else pBInfo = &BandInfo_FM_50KHz; break; case BAND_SW: break; } switch (ctrl){ case INQUIRE: return (Count_To_Freq()); break; case UP: cur_count[band] += pBInfo -> CntStep; break; case DOWN: cur_count[band] -= pBInfo -> CntStep; break; case SET: if ((band == BAND_AM) || (band == BAND_SW)){ //return cur_count[band] * pBInfo -> FRef - 450; cur_count[band] = (freq + 450) / (pBInfo -> FRef); } else { //return cur_count[band] * ((FM_FREF *100)/1000) - 1070; cur_count[band] = ((freq + 1070) * 1000) / (FM_FREF *100); } break; } Tuner_Set_Frequency_Int(); dwPLL_Shadow_IN2 |= BO2_ON; // Unmute Write_LC72131(MODE_IN1, dwPLL_Shadow_IN1); Write_LC72131(MODE_IN2, dwPLL_Shadow_IN2); // save the current count Write_EEPROM(EE_CURCNT_LOW, cur_count[band] & 0xff); Write_EEPROM(EE_CURCNT_HIGH, cur_count[band] >> 8); return (Count_To_Freq()); } //--------------------------------------------------------------------------- // Tuner_Step //--------------------------------------------------------------------------- WORD Tuner_Step(BYTE ctrl){ 第 3 页 无标题 if (ctrl != SET)return Tuner_Set_Frequency(ctrl, 0); } //--------------------------------------------------------------------------- // Tuner_Scan //--------------------------------------------------------------------------- int Tuner_Scan(BYTE ctrl){ BAND_INFO code *pBInfo; WORD temp; register BYTE j; switch(band){ case BAND_AM: if (b_amstep) pBInfo = &BandInfo_AM_10KHz; else pBInfo = &BandInfo_AM_9KHz; break; case BAND_FM: if (b_fmstep) pBInfo = &BandInfo_FM_100KHz; else pBInfo = &BandInfo_FM_50KHz; break; case BAND_SW: break; } if (ctrl == INQUIRE){ return (Count_To_Freq()); } else if (ctrl == UP){ cur_count[band] += pBInfo -> CntStep; } else if (ctrl == DOWN){ cur_count[band] -= pBInfo -> CntStep; } // Temp_Mute(1); Tuner_Set_Frequency_Int(); Write_LC72131(MODE_IN1, dwPLL_Shadow_IN1); Write_LC72131(MODE_IN2, dwPLL_Shadow_IN2); // Wait PLL Lock ----------------------------------------------------------- Pause(1); // for (j=0; j<255; j++){ if (PIN_TUNER_DO)break; } dwPLL_Shadow_IN2 &= DO_MODE_MASK; // set DO mode, end uc dwPLL_Shadow_IN2 |= DO_MODE_END_UC; dwPLL_Shadow_IN1 |= CTE_ON; // IF count start Write_LC72131(MODE_IN1, dwPLL_Shadow_IN1); Write_LC72131(MODE_IN2, dwPLL_Shadow_IN2); // Wait Gate over ----------------------------------------------------- for (j=0; j<10; j++){ if (!PIN_TUNER_DO) break; // break when gate ends os_wait2(K_TMO, 1); } // Gate time over temp = Read_72131() & 0x0fffff; dwPLL_Shadow_IN2 |= BO2_ON; // Unmute Write_LC72131(MODE_IN2, dwPLL_Shadow_IN2); // save the current count Write_EEPROM(EE_CURCNT_LOW, cur_count[band] & 0xff); Write_EEPROM(EE_CURCNT_HIGH, cur_count[band] >> 8); if ((temp >= pBInfo -> IFCntMin) && (temp <= pBInfo -> IFCntMax)){ return -(Count_To_Freq()); } else { return (Count_To_Freq()); } 第 4 页 无标题 } //--------------------------------------------------------------------------- // Tuner_Get_Stereo //--------------------------------------------------------------------------- BOOL Tuner_Get_Stereo(void){ if (band == BAND_FM) { return (!(Read_72131() & 0x800000)); } else return 0; } //--------------------------------------------------------------------------- // Tuner_Set_Frequency_Int //--------------------------------------------------------------------------- static void Tuner_Set_Frequency_Int(void){ BAND_INFO code *pBInfo; switch(band){ case BAND_AM: if (b_amstep) pBInfo = &BandInfo_AM_10KHz; else pBInfo = &BandInfo_AM_9KHz; break; case BAND_FM: if (b_fmstep) pBInfo = &BandInfo_FM_100KHz; else pBInfo = &BandInfo_FM_50KHz; break; case BAND_SW: break; } dwPLL_Shadow_IN1 = 0; dwPLL_Shadow_IN2 = 0; // Check Boundary ----------------------------------------------------- if (cur_count[band] > pBInfo -> CntMax){ cur_count[band] = pBInfo -> CntMin; // Cycling } else if (cur_count[band] < pBInfo -> CntMin){ cur_count[band] = pBInfo -> CntMax; // Cycling } // IN2 Mode ----------------------------------------------------------- dwPLL_Shadow_IN2 |= GATE_TIME_32MS; // Gate Time = 4ms dwPLL_Shadow_IN2 |= 0x100000; // IFS if (band == BAND_AM){ // Set Band dwPLL_Shadow_IN2 |= BO1_ON; } else if (band == BAND_FM){ dwPLL_Shadow_IN2 |= BO4_ON; } if (!bST_MONO) {dwPLL_Shadow_IN2 |= BO3_ON;} // Stereo // dwPLL_Shadow_IN2 &= DO_MODE_MASK; dwPLL_Shadow_IN2 |= DO_MODE_UNLOCK; // // IN1 Mode ----------------------------------------------------------- if (band == BAND_AM){ // Set Frequency dwPLL_Shadow_IN1 |= (cur_count[band] << 4); } else { dwPLL_Shadow_IN1 |= cur_count[band]; } dwPLL_Shadow_IN1 |= pBInfo -> DivMode; // Set DIv Mode dwPLL_Shadow_IN1 |= pBInfo -> DivRefPara; // Set DIV Ref Para } //--------------------------------------------------------------------------- // Count_To_Freq //--------------------------------------------------------------------------- static WORD Count_To_Freq(void){ BAND_INFO code *pBInfo; 第 5 页 无标题 switch(band){ case BAND_AM: if (b_amstep) pBInfo = &BandInfo_AM_10KHz; else pBInfo = &BandInfo_AM_9KHz; break; case BAND_FM: if (b_fmstep) pBInfo = &BandInfo_FM_100KHz; else pBInfo = &BandInfo_FM_50KHz; break; case BAND_SW: break; } if ((band == BAND_AM) || (band == BAND_SW)){ return cur_count[band] * pBInfo -> FRef - 450; } else { return cur_count[band] * ((FM_FREF *100)/1000) - 1070; } } #define LC72131_DELAY() {_nop_(); _nop_(); _nop_();} //--------------------------------------------------------------------------- // Write_LC72131_Addr // addr: the addr of the control register // value: the valude to set to //--------------------------------------------------------------------------- static void Write_LC72131_Addr(BYTE addr){ register BYTE i; PIN_TUNER_CE = 0; PIN_TUNER_CL = 1; LC72131_DELAY(); for (i = 8; i>0; --i){ PIN_TUNER_CL = 0; LC72131_DELAY(); if (addr & 0x01) PIN_TUNER_DI=1; else PIN_TUNER_DI=0; addr >>= 1; LC72131_DELAY(); PIN_TUNER_CL = 1; LC72131_DELAY(); } } //--------------------------------------------------------------------------- // Write_LC72131 // addr: the addr of the control register // value: the valude to set to //--------------------------------------------------------------------------- static void Write_LC72131(BYTE addr, DWORD value){ register BYTE i; // Send the addr byte first ------------// Write_LC72131_Addr(addr); PIN_TUNER_CE = 1; LC72131_DELAY(); // Send the control value in following------------// for (i = 24; i>0; --i){ PIN_TUNER_CL = 0; LC72131_DELAY(); if (value & 0x01) PIN_TUNER_DI=1; else PIN_TUNER_DI=0; value >>= 1; LC72131_DELAY(); PIN_TUNER_CL = 1; 第 6 页 无标题 LC72131_DELAY(); } PIN_TUNER_CE = 0; } //--------------------------------------------------------------------------- // Read_LC72131 // addr: the addr of the control register // return value //--------------------------------------------------------------------------- static DWORD Read_72131(void){ register BYTE i; DWORD temp = 0; // Send the addr byte first ------------// Write_LC72131_Addr(MODE_OUT); PIN_TUNER_CE = 1; LC72131_DELAY(); // read the value dword ------------// for (i=24; i>0; --i){ PIN_TUNER_CL = 0; LC72131_DELAY(); temp <<= 1; if (PIN_TUNER_DO) temp |= 1; PIN_TUNER_CL = 1; LC72131_DELAY(); } PIN_TUNER_CE = 0; return temp; } 头文件如下: #ifndef __TUNER_INT_H__ #define __TUNER_INT_H__ #include // ---------------------------------------------------------------- // Control Pins // ---------------------------------------------------------------- extern BOOL PIN_TUNER_DO; extern BOOL PIN_TUNER_CL; extern BOOL PIN_TUNER_DI; extern BOOL PIN_TUNER_CE; // use 24c02, 0x80 - 0xff enum TUNER_EE { EE_AMSTEP = 0x80, EE_BAND, EE_CURCNT_LOW, EE_CURCNT_HIGH, EE_PRESET_BASE // To store the preset station }; #define MAX_PRESET_NUMBER 0x29 // can store 20 channels for each band // ------------------------------------------------------------- // Tuner Modle: T-989 of Guangzhou Youshen // ------------------------------------------------------------- // work mode type define: #define MODE_IN1 0x28 #define MODE_IN2 0x29 第 7 页 无标题 #define MODE_OUT 0x2a #define CTE_ON 0x040000 #define IOC1 0x000001 #define IOC2 0x000002 #define IO1 0x000004 #define IO2 0x000008 #define BO1_ON 0x000010 #define BO2_ON 0x000020 #define BO3_ON 0x000040 #define BO4_ON 0x000080 #define DO_MODE_UNLOCK 0x000200 #define DO_MODE_END_UC 0x000400 #define DO_MODE_MASK ~0x000e00 // ---------------------------------------- // DEVIDER mode type define // ---------------------------------------- #define AM_DV_MODE 0x000000 // 16 BIT #define SW_DV_MODE 0x020000 // 20 #define FM_DV_MODE 0x020000 // 20 BIT SWALLOW #define AM_DV_REF_9KHz 0x900000 // 9 KHZ #define AM_DV_REF_10KHz 0x800000 // 10 KHZ #define SW_DV_REF 0xa00000 // 5 KHZ #define FM_DV_REF 0x300000 // 25 KHZ #define PLL_OFF_REF 0xe00000 // PLL inhibit and OSC stop. // ---------------------------------------- // IF Count // ---------------------------------------- #define GATE_TIME 32 #define GATE_TIME_32MS 0x020000 // #define GATE_TIME_4MS 0x000000 #define GATE_TIME_8MS 0x010000 #define IFS 0x100000 #define AM_IF_CNT 450*GATE_TIME // 450KH; #define AM_IF_CNT_MIN AM_IF_CNT - AM_IF_CNT*0.01 #define AM_IF_CNT_MAX AM_IF_CNT + AM_IF_CNT*0.01 #define SW_IF_CNT 450*GATE_TIME // 450KH; #define SW_IF_CNT_MIN SW_IF_CNT - SW_IF_CNT*0.01 #define SW_IF_CNT_MAX SW_IF_CNT + SW_IF_CNT*0.01 #define FM_IF_CNT 10700*GATE_TIME // 10.7 MH; #define FM_IF_CNT_MIN FM_IF_CNT - FM_IF_CNT*0.01 #define FM_IF_CNT_MAX FM_IF_CNT + FM_IF_CNT*0.01 // ---------------------------------------- // Frequence Refrence // ---------------------------------------- #define AM_FREF_9KHz 9 // 9khz #define AM_FREF_10KHz 10 // 10khz #define SW_FREF 5 // 5khz #define FM_FREF (25*2) // Fref=25*2 khz // Frequence Range #define AM_MIN_9KHz 522 // KHZ #define AM_MAX_9KHz 1611 // KHZ #define AM_MIN_10KHz 530 // KHZ #define AM_MAX_10KHz 1610 // KHZ #define SW_MIN 1700 // KHZ #define SW_MAX 25000 // KHZ 第 8 页 无标题 #define FM_MIN 8700 // 10KHZ #define FM_MAX 10800 // 10KHZ // Frequence Counter Range #define AM_CNT_MIN_9KHz ((AM_MIN_9KHz + 450)/9) #define AM_CNT_MAX_9KHz ((AM_MAX_9KHz + 450)/9) #define AM_CNT_MIN_10KHz ((AM_MIN_10KHz + 450)/10) #define AM_CNT_MAX_10KHz ((AM_MAX_10KHz + 450)/10) #define SW_CNT_MIN ((SW_MIN + 450)/SW_FREF) #define SW_CNT_MAX ((SW_MAX + 450)/SW_FREF) #define FM_CNT_MIN ((FM_MIN + 1070)/((FM_FREF *100)/1000)) #define FM_CNT_MAX ((FM_MAX + 1070)/((FM_FREF *100)/1000)) // ---------------------------------------- // Search Step // ---------------------------------------- #define AM_CNT_STEP 1 // F_step=1*5khz #define SW_CNT_STEP 1 // F_step=1*5khz #define FM_CNT_STEP_100KHz 2 // F_step=2*50khz when Fref=25khz #define FM_CNT_STEP_50KHz 1 // F_step=50khz when Fref=25khz typedef struct { DWORD DivMode; DWORD DivRefPara; WORD IFCntMax; WORD IFCntMin; BYTE FRef; WORD CntMax; WORD CntMin; BYTE CntStep; }BAND_INFO; enum { BAND_AM, BAND_FM, BAND_SW }; static BAND_INFO code BandInfo_AM_9KHz = {AM_DV_MODE, AM_DV_REF_9KHz, AM_IF_CNT_MAX, AM_IF_CNT_MIN, AM_FREF_9KHz, AM_CNT_MAX_9KHz, AM_CNT_MIN_9KHz, AM_CNT_STEP}; static BAND_INFO code BandInfo_AM_10KHz = {AM_DV_MODE, AM_DV_REF_10KHz, AM_IF_CNT_MAX, AM_IF_CNT_MIN, AM_FREF_10KHz, AM_CNT_MAX_10KHz, AM_CNT_MIN_10KHz, AM_CNT_STEP}; static BAND_INFO code BandInfo_FM_100KHz = {FM_DV_MODE, FM_DV_REF, FM_IF_CNT_MAX, FM_IF_CNT_MIN, FM_FREF, FM_CNT_MAX, FM_CNT_MIN, FM_CNT_STEP_100KHz}; static BAND_INFO code BandInfo_FM_50KHz = {FM_DV_MODE, FM_DV_REF, FM_IF_CNT_MAX, FM_IF_CNT_MIN, FM_FREF, FM_CNT_MAX, FM_CNT_MIN, FM_CNT_STEP_50KHz}; static BAND_INFO code BandInfo_SW = {SW_DV_MODE, SW_DV_REF, SW_IF_CNT_MAX, SW_IF_CNT_MIN, SW_FREF, SW_CNT_MAX, SW_CNT_MIN, SW_CNT_STEP}; // ---------------------------------------------------------------- // Variables // ---------------------------------------------------------------- static DWORD idata dwPLL_Shadow_IN1; static DWORD idata dwPLL_Shadow_IN2; static WORD idata cur_count[3]; // Current count static BOOL bST_MONO; static BOOL b_amstep; static BOOL b_fmstep = 1; static BYTE idata band; // ---------------------------------------------------------------- // external functions // ---------------------------------------------------------------- 第 9 页 无标题 static void Tuner_Set_Frequency_Int(void); static void Write_LC72131_Addr(BYTE addr); static DWORD Read_72131(void); static void Write_LC72131(BYTE addr, DWORD value); static WORD Count_To_Freq(void); extern void Pause(BYTE); extern BOOL Write_EEPROM(BYTE, BYTE); extern BYTE Read_EEPROM(BYTE); extern void Temp_Mute(BOOL bOnOff); #endif 第 10 页
2
|
|
|
|