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

📄 lv2400x.c

📁 LV24000的单片机DEMO程序
💻 C
📖 第 1 页 / 共 5 页
字号:

	// Reset counter
	DriveBit(IR01_CNT_CTRL_REG, IR1_CCTL_CNT1_CLR, TRUE);	// Drive Clear counter bit high
	DriveBit(IR01_CNT_CTRL_REG, IR1_CCTL_CNT1_CLR, FALSE);	// Drive Clear counter bit low

	// Create the StartPattern (enable LV2400x counter) and StopPattern (disable LV2400x counter)
	byTmp = GetSwRegValue(IR01_CNT_CTRL_REG);
	byTmp |= IR1_CCTL_CNT_EN;			// Enable counter pattern (start pattern)
	wStart = MAKEWORD(byTmp, LSB(IR01_CNT_CTRL_REG));
	byTmp &= (BYTE)(~IR1_CCTL_CNT_EN);		// Disable counter pattern
	wStop = MAKEWORD(byTmp, LSB(IR01_CNT_CTRL_REG));
			
	// Start LV2400x counter and Pulse the NRW line
	dwMeasureTimeUs = Pulse3wNRW(wStart, wStop, dwMeasureTimeUs);

	// Read counter1 of LV2400x
	wPulseCnt = ReadReg(IR01_CNT_H_REG);	// High byte
	wPulseCnt <<=8;
	wPulseCnt |= ReadReg(IR01_CNT_L_REG);	// Patch low byte

	// Calculate measure frequency
	*pwFreq = PulseToFrequency1(wPulseCnt, dwMeasureTimeUs);

	return(LVLS_NO_ERROR);
} // End CountPulseCnt1

/* ************************************************************************************************
 *
 *  Function:   PulseToFrequency1
 *
 *  Authors:    Hung van Le
 *  Purpose:    Convert 16 bit pulse count to frequency
 *  Input:      
 *		wPulseCnt: 16 bit pulse count value
 *		dwMeasureTimeUs: measured time in us
 *  Output:     The calculated frequency in Hz
 *  Comments:   Use formula f = n * d / t
 *		where:	f: frequency in Hz
 *			n: pulse count
 *			d: divider factor (fetched with GetDividerFactor-function)
 *			t: measured time in us
 *		This function is meant for measuring with counter 1 (software controlled timing)
 * ************************************************************************************************
 * Copyright (c) 2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
 * ************************************************************************************************ */
 /*
WORD PulseToFrequency1(WORD wPulseCnt, DWORD dwMeasureTimeUs)
{
	DWORD dwFreqHz;
	DWORD dwUnit;

	switch ( GetOutputSelect() )
	{
		case CO_RF_OSC:
			dwUnit=10000;	// 10 KHz unit for RF
			break;
		case CO_IF_OSC:
			dwUnit=10;	// 10 Hz unit for IF
			break;
		//case CO_SD_OSC:
		default:
			dwUnit=1;	// 1 Hz unit for SD and other freq.
			break;
	}

	dwFreqHz = (DWORD)wPulseCnt * GetDividerFactor();

	// Pure unsigned 32 bit variant
	{
		DWORD dwM, dwK, dwH;
		DWORD dwTmp1, dwTmp2;
	
		dwM = dwFreqHz/dwMeasureTimeUs;			// First dividing gives MHz because t is in us
		dwTmp1 = dwFreqHz%dwMeasureTimeUs;		// Remainder of MHz
		dwTmp2 = dwTmp1/1000;				// Extract KHz
		dwK = (dwTmp2 * 1000000)/dwMeasureTimeUs;	// KHz
		dwH = (dwTmp2 * 1000000)%dwMeasureTimeUs;	// Remainder of KHz
		dwH = (dwH *1000)/dwMeasureTimeUs;		// Hz from KHz
		dwTmp2 = dwTmp1%1000;				// Hz from MHz	
		dwH += ((dwTmp2 * 1000000)/dwMeasureTimeUs);	// Total Hz
		dwFreqHz = dwM*1000000 + dwK*1000 + dwH;	// Total frequency
	}

	// MulDiv variant
	//dwFreqHz = MulDiv(dwFreqHz, 1000000, dwMeasureTimeUs);
	
	// Apply unit
	dwFreqHz /= dwUnit;

	// Shadow the measured frequency to simulates (frequency) read-registers
	ShadowMeasuredFrequency(dwFreqHz);

	return((WORD)dwFreqHz);
} // End PulseToFrequency1
*/
WORD PulseToFrequency1(WORD wPulseCnt, DWORD dwMeasureTimeUs)
{
	DWORD dwFreq;

	switch ( GetOutputSelect() )
	{
	case CO_RF_OSC:
		dwFreq = (DWORD)wPulseCnt * IMR01_FM_DIVIDER;
		dwFreq *= 100; // 10 KHz unit for RF
		dwFreq/= dwMeasureTimeUs;
		/*
		// Round the measured frequency up to 10 kHz - this must also be done to all RF-usage (example. in FindFmStation)
		dwFreq = (DWORD)wPulseCnt * IMR01_FM_DIVIDER;
		dwFreq *= 1000; // RF: Calculate in kHz to round it up to 10 KHz unit later
		dwFreq/= dwMeasureTimeUs;	// RF freq is now in kHz
		dwFreq = (dwFreq+5)/10;	// 10 KHz unit for RF (with up rouding)
		*/
		break;
	case CO_IF_OSC:
		dwFreq = (DWORD)wPulseCnt * 100000; // 10 Hz unit for IF
		dwFreq/= dwMeasureTimeUs;
		break;
	//case CO_SD_OSC:
	default:
		// 1 Hz unit for SD and other freq.
		dwFreq = (DWORD)wPulseCnt;
		// Pure unsigned 32 bit variant
		{
			DWORD dwM, dwK, dwH;
			DWORD dwTmp1, dwTmp2;
	
			dwM = dwFreq/dwMeasureTimeUs;			// First dividing gives MHz because t is in us
			dwTmp1 = dwFreq%dwMeasureTimeUs;		// Remainder of MHz
			dwTmp2 = dwTmp1/1000;				// Extract KHz
			dwK = (dwTmp2 * 1000000)/dwMeasureTimeUs;	// KHz
			dwH = (dwTmp2 * 1000000)%dwMeasureTimeUs;	// Remainder of KHz
			dwH = (dwH *1000)/dwMeasureTimeUs;		// Hz from KHz
			dwTmp2 = dwTmp1%1000;				// Hz from MHz	
			dwH += ((dwTmp2 * 1000000)/dwMeasureTimeUs);	// Total Hz
			dwFreq = dwM*1000000 + dwK*1000 + dwH;	// Total frequency
		}
		// MulDiv variant
		//dwFreqHz = MulDiv(dwFreq, 1000000, dwMeasureTimeUs);
		break;
	}
	
	// Shadow the measured frequency to simulates (frequency) read-registers
	ShadowMeasuredFrequency(dwFreq);

	return((WORD)dwFreq);
} // End PulseToFrequency1

/* ************************************************************************************************
 *
 *  Function:   CountPulseCnt2
 *
 *  Authors:    Hung van Le
 *  Purpose:    Counting the pulse (Measure frequencies) of the currently 
 *		selected chip's output. Measuring interval is made with external clock
 *  Input:      
 *		PWORD pwFreq: buffer to receive the measured frequency (unit depends on chip output)
 *  Output:     Status as defined in LvErr.h
 *  Comments:   See also CountPulseCnt1
 *		The code is fixed for 12MHz external clock (counter swapping enabled)
 *		Counter 2 usage
 *			RF (100 MHz): IR1_CTAB_128, 128 (measuring time 0.66ms - 127ppm)
 *			RF (100 MHz): IR1_CTAB_512, 512 (measuring time 2.62ms - 32ppm)
 *
 *			IF (45  kHz): IR1_CTAB_128, 128 (overflow !)
 *			IF (100 kHz): IR1_CTAB_128, 128 (measuring time 2.56ms - 33ppm)
 *			
 *			IF (45  kHz): IR1_CTAB_32, 32 (measuring time 1.42ms - 59ppm)
 *			IF (100 kHz): IR1_CTAB_32, 32 (measuring time 0.64ms - 130ppm)
 *			
 *			SD (38  kHz): IR1_CTAB_32, 32 (measuring time 1.68ms - 49ppm)
 *			
 *			RDS(57  kHz): IR1_CTAB_32, 32 (measuring time 1.12ms - 74ppm)
 *			
 *		Because of short measuring time, this method is not suitable for measuring IF/SD/RDS PLL 
 *		in lock mode.
 *		In free running mode (calibration mode), this method can be used.
 *
 *		RF is not PLL, so this methode always works
 *		We use following:
 *			RF 128
 *			IF/SD in free running mode: 32
 *			IF in lock mode: software window
 *
 * ************************************************************************************************
 * Copyright (c) 2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
 * ************************************************************************************************ */
#ifdef USE_EXTCLK
BYTE CountPulseCnt2(PWORD pwFreq)
{
	BYTE byResult;
	WORD wPulseCnt1, wPulseCnt2;
	BYTE byTab;
	BOOL bSwapState, bCntSelState;
	
	// Return value 0 means no pulses counted (chip removed?)
	//*pwFreqHz = 0;
	byResult = LVLS_NO_ERROR;
	
	if (GetOutputSelect() == CO_RF_OSC)
	{
		byTab = IR1_CTAB_128;			// Register value
		wPulseCnt2 = 128 *IMR01_CNT2_PRESCALER;	// Pulses for counter 2
	}
	else 
	{
		byTab = IR1_CTAB_32;			// Register value
		wPulseCnt2 = 32 *IMR01_CNT2_PRESCALER;	// Pulses for counter 2
	}
	
	// Reset counter 1
	DriveBit(IR01_CNT_CTRL_REG, IR1_CCTL_CNT1_CLR, TRUE);	// Drive Clear counter bit of high
	DriveBit(IR01_CNT_CTRL_REG, IR1_CCTL_CNT1_CLR, FALSE);	// Drive Clear counter bit of low
		
	// Program swap counter bit, tab bit, select counter 2
	bSwapState = DriveBitNeg(IR01_CNT_CTRL_REG, IR1_CCTL_SWP_CNT_L, TRUE);	// Swap counter
	bCntSelState = DriveBit(IR01_CNT_CTRL_REG, IR1_CCTL_CNT_SEL, TRUE);	// Select counter 2
	SetRegBits(IR01_CNT_CTRL_REG, IR1_CCTL_CNT_TAB, byTab); // counter Tab setting
	
	// Enable counter to start counting
	DriveBit(IR01_CNT_CTRL_REG, IR1_CCTL_CNT_EN, TRUE);

	// Wait counting done -  Poll register for counting done
	wPulseCnt1 = 1500; // Temporary use wPulseCnt1 as loop counter
	do
	{
		if (ReadReg(IR01_IRQ_ID_REG) & IR1_IRQID_CNT2)	// Counting done bit set
			break;
		wPulseCnt1--;
		DelayUs(DLT_100us);
	} while (wPulseCnt1>0);

	// Counting done - Disable the counter (also clear IR1_IRQID_CNT2 bit)
	DriveBit(IR01_CNT_CTRL_REG, IR1_CCTL_CNT_EN, FALSE);

	// Check timeout
	if (wPulseCnt1 == 0)
  	{
		byResult = LVLS_POLLING_CNT_TIMEOUT;
	}
	else
	{
		// Read counter1 of LV2400x
		wPulseCnt1 = ReadReg(IR01_CNT_H_REG);	// High byte
		wPulseCnt1 <<= 8;
		wPulseCnt1 |= ReadReg(IR01_CNT_L_REG);	// Patch low byte
	}

	// restore swap bit, counter select bit
	DriveBitNeg(IR01_CNT_CTRL_REG, IR1_CCTL_SWP_CNT_L, bSwapState);
	DriveBit(IR01_CNT_CTRL_REG, IR1_CCTL_CNT_SEL, bCntSelState);
	
	// Formula to calculate frequency from pulse counts
	//	if NoSwapping
	//		f = (N1 * fext * DividerFactor)/N2
	//  if Swapping
	//		f = (N2 * fext * DividerFactor)/N1
	//	(N2 is value of counter 2 = TabValue * CNT2_div_factor)
	*pwFreq = PulseToFrequency2(wPulseCnt2, wPulseCnt1);
	return(byResult);
} // End CountPulseCnt2
#endif //USE_EXTCLK

#ifdef USE_EXTCLK
WORD PulseToFrequency2(WORD wCntA, WORD wCntB)
{
	DWORD dwFreq;

	// Avoid dividing by zero
	if (wCntB == 0)
	{
		dwFreq = 0;
	}
	else
	{
		switch ( GetOutputSelect() )
		{
		case CO_RF_OSC:
			dwFreq = (DWORD)wCntA * IMR01_FM_DIVIDER;
			dwFreq *= (EXT_CLK_12MHZ/10000); // 10 KHz unit for RF
			break;
		case CO_IF_OSC:
			dwFreq = (DWORD)wCntA * (EXT_CLK_12MHZ/10); // 10 Hz unit for IF
			break;
		//case CO_SD_OSC:
		default:
			dwFreq = (DWORD)wCntA * (EXT_CLK_12MHZ); // 1 Hz unit for other frequency
			break;
		}
		dwFreq /= wCntB;
	}
	
	// Shadow the measured frequency to simulates (frequency) read-registers
	ShadowMeasuredFrequency(dwFreq);

	return((WORD)dwFreq);
} // End PulseToFrequency2
#endif //USE_EXTCLK

BYTE GetFmFieldStrength(void)
{
	BYTE byRegValue;
	BYTE byOrgMode;
	BYTE byFs;
		
	// Make sure the chip is in measuring mode for measure field strenggth
	byOrgMode = DriveBit(IR01_RADIO_CTRL1_REG, IR1_RCTL1_EN_MEAS, TRUE);

	// Read Radio status register to determine field strength
	byRegValue = ReadReg(IR01_RADIO_STAT_REG);

	// Extract FieldStrength
	byRegValue &= IR1_RSTAT_FS; // extract field strength bits
	byRegValue ^= IR1_RSTAT_FS; // Invert field strength level (0 becomes 1)
	
	byFs = 0; // field strength to be returned
	while (byRegValue != 0)
	{
		if ( byRegValue & 1 )
			byFs++;
		byRegValue>>=1;
	}
	
	// Restore measure mode
	DriveBit(IR01_RADIO_CTRL1_REG, IR1_RCTL1_EN_MEAS, byOrgMode);

	return(byFs);
} // End GetFmFieldStrength

BYTE GetStereoState(void)
{
	// Determine stereo state of LV2400x
	// Return: GSS_MONO: mono mode
	//	   GSS_STEREO: stereo is enabled but no stereo recieving
	//	   GSS_STEREO_DET: stereo is enabled and stereo detected

	// Determine stereo enable state
	if ( (GetSwRegValue(IR01_STEREO_CTRL_REG) & IR1_STCTL_STEREO_L) == 0 ) // Stereo bit = 0: stereo is enabled
	{
		if (ReadReg(IR01_RADIO_STAT_REG) & IR1_RSTAT_STEREO) 	// Stereo state bit = 1 (Stereo)
			return(GSS_STEREO_DET);		// Stereo is detected by the chip
		else
			return(GSS_STEREO);		// Stereo is enabled but not detected
	}
	else
		return(GSS_MONO);
} // End GetStereoState

/* ************************************************************************************************
 *
 *  Function:   ShadowMeasuredFrequency
 *
 *  Authors:    Hung van Le
 *  Purpose:    Simulates some (frequency) read-registers which are missing in the chip
 *  Input:      
 *		DWORD dwFreqHz: frequency (in Hz) to be shadowed
 *  Output:     None
 *  Comments:   Use GetOutputSelect to determine the frequency source
 *
 * ************************************************************************************************
 * Copyright (c) 2002-2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
 * ************************************************************************************************ */
void ShadowMeasuredFrequency(DWORD dwFreqHz)
{
	// Only save the RF frequency
	if ( GetOutputSelect() == CO_RF_OSC)
	{
		g_wLastMsrRF = dwFreqHz; 
	}
} // End ShadowMeasuredFrequency

BYTE SetRfFrequency(WORD wRfFreq)
{
	BYTE byResult;

⌨️ 快捷键说明

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