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

📄 radiosub.c

📁 LV24000的单片机DEMO程序
💻 C
📖 第 1 页 / 共 2 页
字号:
						(*pwCurFreq) = DisplayFreqToRf(g_JapanWideFmBandList[i+1].wBandLo);
					else
						(*pwCurFreq) = wRfBandHigh; // ie: DisplayFreqToRf(g_JapanWideFmBandList[i].wBandHi);
					byResult = LVLS_FREQ_JUMP_ERR;
				}
			}
		}
	}

	// Check against hardware limit
	if ( (*pwCurFreq<g_wHwRfLow) || (*pwCurFreq>g_wHwRfHigh) )
	{
		byResult = LVLS_UNREACHABLE_FREQ_ERR;
		(*pwCurFreq<g_wHwRfLow)?(*pwCurFreq=g_wHwRfLow):(*pwCurFreq=g_wHwRfHigh);
	}
	return(byResult);
} // End CheckRfLimit

/* ************************************************************************************************
 *
 *  Function:   ScanFmRoutine
 *
 *  Authors:    Hung van Le
 *  Purpose:    Scan FM band for station
 *  Input:      
 *			int iDir: Scan direction (iDir = 1: scan up, -1: scan down)
 *			WORD wFmBandLow, WORD wFmBandHigh: RF-frequency range for scanning (in 10 kHz-unit)
 *  Output:     Status as defined in LvErr.h
 *  Global:	g_byScanLevel: the field strength level to accept/reject a station (must be set before invoking this routine)
 *		g_byStnFlag: STN_VALID flag to determine the initial start frequency: when this flag is set (we're at a valid station)
 *			     extra offset will be added to avoid finding the same station.
 *		g_byHwFlag1: HF1_NEG_IF_PHASE flag for the IF phase (the scan search for IF edge, the phase indicates which edge (Positive/Negative) is valid)
 *		g_wLastSetRF: the RF frequency (change during scanning)
 *		g_wLastMsrRF: the measured RF frequency (change during scanning)
 *  Comments:	The chip should be correctly set up before invoking this routine (Measure mode, mute , stereo ...)
 *
 * ************************************************************************************************
 * Copyright (c) 2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
 * ************************************************************************************************ */
BYTE ScanFmRoutine(int iDir, WORD wFmBandLow, WORD wFmBandHigh)
{
#define SCFM_FROMSTATION_STEP	((WORD)20)	// 200 kHz - Step size to step away from a station
#define SCFM_NOSTATION_STEP	((WORD)10)	// 100 kHz - Step size when a station is not found
#define SCFM_DISPLAY_DISTANCE	((WORD)85)	// 850 kHz - Update display distance

#define SCFM_SCANSTEP		((int)8) 	// 80 kHz - scan step (10 kHz-unit)
#define SCFM_IFSWING		((int)3500)	// 35 kHz - IF swing (10 Hz-unit)
#define SCFM_PRECISION		QSSF_PRECISION_LOW // precision level use by ScanSetFreq

	BYTE  byResult;
	WORD  wIfFreq, wIfFreq2;
	BOOL  bCorrectEdge;
	int   iStepFreq, iIfDif;
	int   iIfSwing;
	BYTE  byMsrFs, bySwFsLevel, byDispCnt;

	// Init var.
	byResult = LVLS_NO_ERROR;
	wIfFreq =0;
	if (g_byStnFlag & STN_VALID)			// Valid station
		iStepFreq = SCFM_FROMSTATION_STEP;	// Step away from current stattion
	else
		iStepFreq = 0;
	g_byStnFlag &= (~STN_VALID);			// No valid station now
	
	// Scan routine uses bySwFsLevel, i32ScanStepHz, i32IfSwingHz, which are derived from g_byScanLevel
	// Adjust the scan level because the radio chip can not measure it quickly
	bySwFsLevel = g_byScanLevel;
	if (g_byScanLevel > 0)
		bySwFsLevel--;	// Leave 0 at 0, convert 1..7 to 0..6
	if (bySwFsLevel>3)
		bySwFsLevel--;	// Convert scan level 7/6/5 to 5/4/3 (hardware measuring!!!)
		
	// Determine sign of the IF swing (depend on the scan direction and the IF phase)
	iIfSwing = SCFM_IFSWING * iDir;
	if ( g_byHwFlag1 & HF1_NEG_IF_PHASE) // Negative IF phase
		iIfSwing = -iIfSwing;

	// Scan loop
	byDispCnt = 0;
	while ( (g_byStnFlag & STN_VALID)==0 )	// While not valid station
	{
		// Calculate the new frequency
		g_wLastSetRF += (iStepFreq*iDir);

		// Check frequency
		byResult = CheckRfLimit(&g_wLastSetRF, wFmBandLow, wFmBandHigh, iDir);
		if (byResult != LVLS_NO_ERROR)
		{
			wIfFreq = 0;
			if (byResult != LVLS_FREQ_JUMP_ERR)
			{
				// Set frequency to valid one
				ScanSetFreq(g_wLastSetRF, QSSF_PRECISION_HIGH);
				goto return_ScanFmRoutine;
			}
		}

		// Set the frequency
		byResult = ScanSetFreq(g_wLastSetRF, SCFM_PRECISION);
		if (byResult != LVLS_NO_ERROR)
			goto return_ScanFmRoutine;

		// Callback - report current frequency
		byDispCnt++;
		//if (byDispCnt>9)
		if (byDispCnt>1)
		{
			byResult = CallBack(CRSN_SCAN_UPD);
			if (byResult != LVLS_NO_ERROR)
				goto return_ScanFmRoutine;
			byDispCnt = 0;
		}
		
		// Check 1: field strength should be sufficient
		if ( bySwFsLevel>0 )
		{
			//DelayUs(DLT_5ms);	// The hardware fieldstrength measuring circuitry is not very fast, give it sometimes
			byMsrFs = GetFmFieldStrength();
			if ( byMsrFs < bySwFsLevel )
			{
				DelayUs(DLT_5ms);	// The hardware fieldstrength measuring circuitry is not very fast, give it sometimes
				byMsrFs = GetFmFieldStrength();
			}
			if ( byMsrFs < bySwFsLevel )
			{
				iStepFreq = SCFM_SCANSTEP;
				wIfFreq = 0;
				continue;
			}
		}
				
		// Measure the IF frequency at current point
		byResult = MeasureFrequency(CO_IF_OSC, LV_MSR_TIME_8ms, &wIfFreq2);
		if (byResult != LVLS_NO_ERROR)
			goto return_ScanFmRoutine;
		
		// Checking the IF edge when we have the 1st IF
		bCorrectEdge = FALSE;
		if (wIfFreq != 0)
		{
			iIfDif = (int)wIfFreq-(int)wIfFreq2;
			if (iIfSwing > 0)
			{
				if ( iIfDif >= iIfSwing ) // found edge
					bCorrectEdge = TRUE;
			}
			else
			{
				if ( iIfDif <= iIfSwing ) // found edge
					bCorrectEdge = TRUE;
			}
		}

		// Move current point to 1st point for next time
		wIfFreq = wIfFreq2;

		// Check if we have a correct IF-edge
		if ( !bCorrectEdge ) 
		{
			iStepFreq = SCFM_SCANSTEP;
			continue;
		}
		
		// Final step: pinpoint the station if field strength is sufficient
		if ( bySwFsLevel>0 )
		{
			byMsrFs = GetFmFieldStrength();
			if ( byMsrFs < bySwFsLevel )
			{
				iStepFreq = SCFM_SCANSTEP;
				continue;
			}
		}

		// Last update before FindFmStation
		byResult = CallBack(CRSN_SCAN_UPD);
		if (byResult != LVLS_NO_ERROR)
			goto return_ScanFmRoutine;

		// Pinpoint the station
		if ( FindFmStation() )
			g_byStnFlag |= STN_VALID;
		else
		{
			// Reset scan variable for next scan when not found
			iStepFreq = SCFM_NOSTATION_STEP;
			wIfFreq =0;
			continue;
		}

		// Verfy that we have the station with correct field strength
		if ( g_byScanLevel > 0 )
		{
			byMsrFs = GetFmFieldStrength();
			if ( byMsrFs < g_byScanLevel )
			{
				g_byStnFlag &= (~STN_VALID); // Wrong field strength
				iStepFreq = SCFM_SCANSTEP;
			}
		}
	} // End ScanLoop

return_ScanFmRoutine:
	if (byResult == LVLS_NO_ERROR)
	{
		// We found a station, extra verification when the found station is at 50 kHz grid
		MeasureFrequency(CO_RF_OSC, LV_MSR_TIME_32ms, &wIfFreq);	// Update g_wLastMsrRF
		wIfFreq = GetDisplayFrequency(5); // Temp. use wIfFreq to store current display frequency, aligned at 50 kHz
		if ( (wIfFreq % 10) == 5 )	// Display frequency end at 50 kHz?
		{
			// Determine the station frequency again
			MeasureFrequency(CO_IF_OSC, LV_MSR_TIME_32ms, &wIfFreq);	// IF

			// Compensate RF to get with the last measured IF
			// Calculate the delta IF 
			iIfDif = (int)wIfFreq - (int)DEFAULT_IF_FREQ;
			if ( g_byHwFlag1 & HF1_NEG_IF_PHASE) // Apply IF-sign
				iIfDif = -iIfDif;	     // Negative IF phase

			// Compensate RF to get the desired IF (IF in 10 Hz, RF in 10 kHz unit)
			// g_wLastMsrRF is updated above
			g_wLastMsrRF = (int)g_wLastMsrRF + (iIfDif/1000);	
		}
	}
	return(byResult);
} // End ScanFmRoutine

/* ************************************************************************************************
 *
 *  Function:   FindFmStation
 *
 *  Authors:    Hung van Le
 *  Purpose:    Try to find a FM station
 *  Input:      None
 *  Output:     TRUE : station found
 *		FALSE: no station found
 *  Global:	g_byHwFlag1: HF1_NEG_IF_PHASE flag for the IF phase
 *		g_wLastMsrRF: the measured RF frequency (compensated for display frequency calculation)
 *  Comments:	- A FM station is characterized by the IF-edge of +/- 45 degree (positive/negative IF). 
 *		  When we have the correct edge, the station can be pinpointed by using equation RF1 +/- IF1 = RF2 +/- IF2
 *		  (+ or - depends on the IF-phase)
 *
 *		- When a station is found, the RF will be compensated with dIF:
 *		  To avoid wrong display frequency, we have to correct the RF-frequency according to the measured IF-frequency.
 *		  When the IF-phase is negative, we have relation:
 *			DisplayFreq = RF - IF	(for positive phase the equation is DisplayFreq = RF + IF)
 *		  When we find a station, the display frequency should be
 *			DisplayFreq = RF' - MeasuredIF
 *			where MeasuredIF = CalibratedIF + dIF. 
 *			or dIF = MeasuredIF - CalibratedIF (dIF can be negative and is 0 when the RF is correctly tuned)
 *			so RF' = RF + dIF
 *		  For example when the CalibratedIF is 110 kHz, and we find a station with 100 kHz as last measured IF,
 *		  dIF = 100 - 110 = -10 kHz
 *		  When the IF phase is negative, The RF' is then  RF' = RF + 10 kHz
 *
 *		- This routine can also be used to validate the FM station
 *
 * ************************************************************************************************
 * Copyright (c) 2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
 * ************************************************************************************************ */
BOOL FindFmStation(void)
{
//	#define FFS_IF_MARGIN	1500	// in 10 Hz unit
	#define FFS_IF_MARGIN	2500	// in 10 Hz unit

	BYTE  byLoopCnt;
	WORD  wCurFM;
	WORD  wCurIF;
	int   iDifIF;

	// Determine current IF
	MeasureFrequency(CO_IF_OSC, LV_MSR_TIME_32ms, &wCurIF);

	if ( (wCurIF < (DEFAULT_IF_FREQ-FFS_IF_MARGIN)) || (wCurIF >(DEFAULT_IF_FREQ+FFS_IF_MARGIN)) )
	{
		// Determine the current FM frequency (always measure RF for correcting it here after)
		MeasureFrequency(CO_RF_OSC, LV_MSR_TIME_32ms, &wCurFM);

		// Enter find station point loop if IF-frequency is not in OK range
		byLoopCnt = 4;
		do
		{
			byLoopCnt--;
			if (byLoopCnt == 0)
				return(FALSE);

			// Calculate the delta IF 
			iDifIF = (int)wCurIF - (int)DEFAULT_IF_FREQ;
			if ( g_byHwFlag1 & HF1_NEG_IF_PHASE ) // Apply IF-sign
				iDifIF = -iDifIF;	     // Negative IF phase
			wCurFM = (int)wCurFM + (iDifIF/1000);	// Compensate RF to get the desired IF (IF in 10 Hz, RF in 10 kHz unit)
			if ( ScanSetFreq(wCurFM, QSSF_PRECISION_HIGH) != LVLS_NO_ERROR )
				return(FALSE);

			MeasureFrequency(CO_IF_OSC, LV_MSR_TIME_32ms, &wCurIF);
		} while ( (wCurIF<(DEFAULT_IF_FREQ-FFS_IF_MARGIN)) || (wCurIF>(DEFAULT_IF_FREQ+FFS_IF_MARGIN)) );
	}
	return(TRUE);
} // End FindFmStation

⌨️ 快捷键说明

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