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

📄 keypad.c

📁 LV24000的单片机DEMO程序
💻 C
📖 第 1 页 / 共 2 页
字号:
					g_byInpPos = 1;
				}
			}
			// Second digit can only be >=7 for Japanse base, >=8 for Erope band !!!
		}
	#endif //SUPPORT_AMFM

	#ifdef FM_ONLY
		// Some smart input (!)
		// The first digit can only be 0 or 1, so move to 2nd position is input >1
		if ( g_byInpPos == 0)
		{
			if (byTmp>1)
			{
				g_byaInp[0]=0;
				g_byInpPos = 1;
			}
		}
		// Second digit can only be >=7 for Japanse base, >=8 for Erope band !!!
	#endif //FM_ONLY
				
		// Store the input
		g_byaInp[g_byInpPos] = byTmp;

		// Update position for next input
		g_byInpPos++;
		if ( g_byInpPos >=5)
			g_byInpPos = 0;

		// Show the input frequency
		wDisplayFreq = 0;
		for (i=0; i<5; i++)
		{
			wDisplayFreq *= 10;
			wDisplayFreq += g_byaInp[i];
		}
	#ifdef USE_LCD
		ClearLcdPos(LCDPOS_INPFREQ, LCDLEN_STATUS);
		PrintFreq10k(LCDPOS_INPFREQ, wDisplayFreq);		

		// Set cursor at correct position for user
		SetInputCursorPos();
	#endif //USE_LCD
	}
	else // Control keys pressed
	{
		if ( byKey == KP_H)
		{
			// Key #: set the input frequency
			// Determine input frequency
			wDisplayFreq = 0;
			for (i=0; i<5; i++)
			{
				wDisplayFreq *= 10;
				wDisplayFreq += g_byaInp[i];
			}
			g_byInpPos = 0; // Reset input to 1st digit
		}
		else
		{
			// Key <--: Step back 50 kHz (FM)/ 9kHz or 10 kHz (AM)
			// Key -->: Step forward 50 kHz (FM)/ 9kHz or 10 kHz (AM)
			wDisplayFreq = GetDisplayFrequency(g_wFreqGrid);
			if (byKey==KP_LEFT)
				wDisplayFreq -= g_wFreqGrid;
			else
				wDisplayFreq += g_wFreqGrid;
		}
	#ifdef USE_LCD
		ShowSetFreqStart();
	#endif //USE_LCD
		byTmp = SetFrequency(wDisplayFreq);
	#ifdef USE_LCD
		ShowResult(byTmp);
		SendLcdCmd(LCDPOS_INPFREQ | g_byInpPos);
	#endif //USE_LCD
	}
	return(LVLS_NO_ERROR);
} // End KpMenu1

//-----------------------------------------------------------------------------
// Keypad menu 2: Radio settings 1
//-----------------------------------------------------------------------------
BYTE KpMenu2(BYTE byKey)
{
	BYTE byTmp;

	byKey &= (BYTE)(~KP_LONG);	// We don't know long key for this menu

	// Check if a numeric key is pressed
	byTmp = GetNumKeyValue(byKey);
	if (byTmp != KP_NO_KEY)
	{
		g_byNrPressed = byTmp;
		byTmp = AdjustHwFeature(g_NumToFeat_A[g_byNrPressed], 0x00);
	#ifdef USE_LCD
		if (byTmp != LVLS_NO_ERROR)	// Feature not supported
			PrintKeyNotSupport(g_byNrPressed); // treat as NA-key
	#endif //USE_LCD
	}
	else
	{	// Ignore key H
		if (byKey==KP_RIGHT)
		{
			// Increase value
			AdjustHwFeature(g_NumToFeat_A[g_byNrPressed], 0x01);
		}
		else if (byKey==KP_LEFT)
		{
			// Decrease value
			AdjustHwFeature(g_NumToFeat_A[g_byNrPressed], 0xFF);
		}
	}
	return(LVLS_NO_ERROR);
} // End KpMenu2

//-----------------------------------------------------------------------------
// Keypad menu 3: Radio settings 2
//	key 0...7: features as defined in g_NumToFeat_B
//	key 8: clear settings in flash
//	key 9: save settings in flash
//-----------------------------------------------------------------------------
BYTE KpMenu3(BYTE byKey)
{
	BYTE byTmp;
	BYTE byAdjValue;

	// Check if a numeric key is pressed
	byKey &= (BYTE)(~KP_LONG);	// We don't know long key for this menu
	byTmp = GetNumKeyValue(byKey);
	byAdjValue = 0x80;		// Mark no adjust value is determined
	if (byTmp != KP_NO_KEY)
	{
		byAdjValue = 0x00;
		g_byNrPressed = byTmp;
	}
	else
	{
		if (byKey==KP_RIGHT)
		{
			byAdjValue = 0x01; // Increase value
		}
		else if (byKey==KP_LEFT)
		{
			byAdjValue = 0xFF;	// Decrease value
		}
	}

	// Handle value adjustment
	if (byAdjValue != 0x80)
	{
		if (g_byNrPressed < KP_FEATB_CNT)	// Is it a feature key?
		{
			AdjustHwFeature(g_NumToFeat_B[g_byNrPressed], byAdjValue);
		}
#ifdef USE_PRESET
		else if (g_byNrPressed >= 8) // key 9 is save data in flash, key 8 is clear flash data
		{
		#ifdef USE_LCD
			// Clear current status line
			ClearLcdPos(LCDPOS_STATUS, LCDLEN_STATUS);
			if (g_byNrPressed == 8) 	// Key 8: Clear settings
				PrintString(LCDPOS_ACTNAME, "Clear");
			else 				// Key 9: Save settings
				PrintString(LCDPOS_ACTNAME, "Save");
			PrintString(CURS_CURPOS, " data");
		#endif //USE_LCD

			if (byAdjValue != 0x00)
			{
				if (g_byNrPressed == 8) 	// Key 8: Clear settings
					byTmp = WriteSettingsToFlash(FLS_CLEAR);
				else
					byTmp = WriteSettingsToFlash(FLS_SAVE);
			#ifdef USE_LCD
				ShowResult(byTmp);
			#endif //USE_LCD
			}
		}
#endif //USE_PRESET
		else // Not supported keys
		{
		#ifdef USE_LCD
			PrintKeyNotSupport(g_byNrPressed);
		#endif //USE_LCD
		}
	}
	return(LVLS_NO_ERROR);
} // End KpMenu3

BYTE AdjustHwFeature(BYTE byFeatureId, BYTE byAdj)
{
	BYTE byLim, byVal, byNew;

	// Get limit of feature
	byLim = GetHwFeatureLimit(byFeatureId);

	if (byLim > 0) // Feature supported
	{
		// Get current value
		byVal = GetHwFeatureValue(byFeatureId);

		// Adjust value
		byNew = byVal+byAdj;

		// Wrapping if exceed limit
		if (GetFeatureValueType(byFeatureId) == FV_NUMBER_NOWRAP)
		{
			if (byNew == 0xFF)	// Wrap from 0 to FF
				byNew=0;	// Stay 0
			else if (byNew > byLim)
				byNew=byLim;	// Stay at limit
		}
		else
		{
			if (byNew == 0xFF)	// Wrap from 0 to FF
				byNew=byLim;
			else if (byNew > byLim)	// Exceed limit
				byNew=0;	// Wrap to 0
		}

		// Setting new value if changes
		if (byNew != byVal)
		{
			if ( SetHwFeatureValue(byFeatureId, byNew) != LVLS_NO_ERROR )
				byNew = byVal;	// Setting value failed - value is not changed
		}
	#ifdef USE_LCD
		// Show name
		ClearLcdPos(LCDPOS_FNAME, LCDLEN_FNAME);
		PrintString(CURS_CURPOS, GetFeatureName(byFeatureId));

		// Show value
		ShowFeatureValue(byFeatureId, byNew);
	#endif //USE_LCD
	}
	else
	{
		return(LVLS_NSU_FEATURE_ERR);
	}
	return(LVLS_NO_ERROR);
} // End AdjustHwFeature

#ifdef USE_LCD
char *GetFeatureName(BYTE byFeatureId)
{
	// Return the name of the feature specified by featureId, using name defined in g_Lv24FeatName-table
	BYTE i;

	for (i=0; i<LV_FEATNAME_LSIZE; i++)
	{
		if ( g_Lv24FeatName[i].byFeatureId == byFeatureId)
			return(g_Lv24FeatName[i].szName);
	}
	return("Unknown"); // Not supported
} // End GetFeatureName
#endif //USE_LCD

//#ifdef USE_LCD
BYTE GetFeatureValueType(BYTE byFeatureId)
{
	// Return the value-type of the feature specified by featureId, using type defined in g_Lv24FeatName-table
	BYTE i;

	for (i=0; i<LV_FEATNAME_LSIZE; i++)
	{
		if ( g_Lv24FeatName[i].byFeatureId == byFeatureId)
			return(g_Lv24FeatName[i].byValType);
	}
	return(FV_NUMBER_WRAP); // default type
} // End GetFeatureValueType
//#endif //USE_LCD

#ifdef USE_LCD
void ShowFeatureValue(BYTE byFeatureId, BYTE byVal)
{
	char *pStr;

	// Init local
	pStr = NULL;

	// Clear current value display
	ClearLcdPos(LCDPOS_FVAL, LCDLEN_FVAL);

	switch (GetFeatureValueType(byFeatureId))
	{
	case FV_ON_OFF:	// On/Off value
		pStr = g_szValOnOff[byVal];
		break;

	case FV_STEREO:	// Stereo
		pStr = g_szValStereo[byVal];
		break;

	case FV_RBAND:	// Radio source:Off, FM, AM
		pStr = g_szValRadioBand[byVal];
		break;

	case FV_BFREQ:  // Buzzer frequency: Off, Freq1, Freq2, Freq3...
		if (byVal == 0)
			pStr = g_szValOnOff[byVal];	// Off
		else
		{
			PrintString(CURS_CURPOS, "Freq ");
			PrintDword(CURS_CURPOS, (DWORD)byVal);
		}
		break;

	case FV_REGION:	// Region
		pStr = g_szRegion[byVal];
		break;

	case FV_FWRAP_OPTION: // Frequency wrap option
		pStr = g_szWrapOption[byVal];
		break;

#ifdef USE_EXTCLK
	case FV_EXTCLK:
		pStr = g_szExtClock[byVal];
		break;
#endif //USE_EXTCLK

	//case FV_NUMBER_WRAP:		// Numberic value (Wrapping low/high limit allowed)
	//case FV_NUMBER_NOWRAP:	// Numberic value (Wrapping low/high limit not allowed)
	default:			// Show number
		PrintDword(CURS_CURPOS, (DWORD)byVal);
		break;
	}
	if (pStr != NULL)
		PrintString(CURS_CURPOS, pStr);
	// Show audio mute as Icon for Bolymin LCD
#ifdef BOLYMIN_LCD
	if (byFeatureId == IHCAP_AMUTE)
	{
		if (byVal==0) // Not muted
			ShowIcon(ICON_MUTED, HIDE_ICON);
		else
			ShowIcon(ICON_MUTED, SHOW_ICON);
	}
#endif //BOLYMIN_LCD
} // End ShowFeatureValue
#endif //USE_LCD

#ifdef USE_LCD
void InitKeypadMenu()
{
	WORD wTmp;
	BYTE i;
	// Show menu name
	PrintString(CURS_1_0, g_MenuName[g_byMenu]);

	// Menu specific intialization
	if (g_byMenu == MNU_MANUAL)
	{
		ShowCursor(TRUE);
		SendLcdCmd(LCDPOS_INPFREQ);	// set cursor at correct pos.
		g_byInpPos = 0;
		// Convert current frequency to input buffer
		wTmp = GetDisplayFrequency(g_wFreqGrid);
		for (i=5; i>0; i--)
		{
			g_byaInp[i-1] = (BYTE)(wTmp % 10);
			wTmp /= 10;
		}
	}
	else
	{
		ShowCursor(FALSE);	// hide cursor for other menu
	}
} // End InitKeypadMenu
#endif //USE_LCD

#ifdef USE_PRESET
void KpPresetHandling(BOOL bStore)
{
	// bStore = TRUE: store current frequency to current preset location
	//	    FALSE: recall current preset
	WORD wFreq;
	BYTE byResult;

#ifdef USE_LCD
	ShowPreset(g_byCurPreset, bStore);
#endif //USE_LCD

	if (bStore)
	{
		// Store preset
		wFreq = GetDisplayFrequency(g_wFreqGrid);	// 100 kHz grid?
		byResult = SavePreset(g_byCurPreset, wFreq);
	}
	else
	{
		// Recall preset
		wFreq = RecallPreset(g_byCurPreset);
		if (wFreq != 0)
			byResult = SetFrequency(wFreq);
		else
			byResult = LVLS_EMPTY_PRESET;
	}

#ifdef USE_LCD
	ShowResult(byResult);
#endif //USE_LCD
} // End KpPresetHandling
#endif //USE_PRESET

#ifdef USE_LCD
void SetInputCursorPos()
{
	// Set cursor at input position for user (only in manual menu)
	BYTE byTmp;

	// Done if we're not in manual input mode
	if (g_byMenu != MNU_MANUAL)
		return;

	// Fetch current input (digit) position
	byTmp = g_byInpPos;

#ifdef SUPPORT_AMFM
	if ( (g_byStnFlag & STN_AM_MODE) == STN_FM_MODE )
	{
		if ( g_byInpPos == 3) // avoid dot position
			byTmp=4;
	}
	else // AM mode - skip the 1st position
	{
		if ( g_byInpPos == 0) // avoid space position
			byTmp=1;
	}
	#endif //SUPPORT_AMFM

#ifdef FM_ONLY
	if ( g_byInpPos == 3) // avoid dot position
		byTmp=4;
#endif //FM_ONLY
	SendLcdCmd(LCDPOS_INPFREQ | byTmp);
} // End SetInputCursorPos
#endif //USE_LCD

//-----------------------------------------------------------------------------
// Callback-function: handle all callback from the LV2400x
//-----------------------------------------------------------------------------
BYTE CallBack(BYTE byCbReason)
{
	BYTE i;
	WORD wTmp;

	switch (byCbReason)
	{
	case CRSN_ASCAN_FOUND:	// Auto scan found a station
#ifdef USE_PRESET
		// Store it if we have place
		i = GetNextSavePresetLocation();
		if (i<PRESET_CNT)
		{
			SavePreset(i, GetDisplayFrequency(g_wFreqGrid));
			#ifdef USE_LCD
				PrintDword(LCDPOS_ACTSTAT, (DWORD)i+1); // show number of station found so far
			#endif //USE_LCD
		}
		if (i >= (PRESET_CNT-1) )	// check if we have used the last storage
			return(LVLS_NO_MORE_PRST_MEM); // Abort auto scan due to out of storage
#endif //USE_PRESET
		break;

	case CRSN_STN_CHNG:	// Station changed
	case CRSN_SCAN_UPD:	// Update during scanning
		// Show current fieldstrength value				
	#ifdef USE_LCD
			ShowFieldStrength( GetFmFieldStrength() );
			wTmp = g_wFreqGrid;
		#ifdef SUPPORT_AMFM
			if ( (g_byStnFlag & STN_AM_MODE) == STN_FM_MODE )
			{
				if ( byCbReason == CRSN_SCAN_UPD )
					wTmp = 10; // Display grid 100 kHz during scan
			}
		#endif //SUPPORT_AMFM
		#ifdef FM_ONLY
			if ( byCbReason == CRSN_SCAN_UPD )
				wTmp = 10; // Display grid 100 kHz during scan
		#endif //FM_ONLY
			PrintFreq10k( LCDPOS_FREQ, GetDisplayFrequency(wTmp) );		
			SetInputCursorPos();
	#endif //USE_LCD
		break;
	case CRSN_FS_CHNG:	// Field strength changed
		// Show new fieldstrength value
		#ifdef USE_LCD
			ShowFieldStrength( GetFmFieldStrength() );
			SetInputCursorPos();
		#endif //USE_LCD
		break;
			
	case CRSN_MS_CHNG:	// Mono stereo state changed
		#ifdef USE_LCD
			i = GetStereoState();		// Determine current stereo state
			if (i == GSS_STEREO_DET)	// Stereo is detected
				i = EVK_STEREO_DET;
			else if (i == GSS_STEREO)	// Stereo is enabled (but not detected)
				i = EVK_STEREO;
			else
				i = EVK_MONO;		// None of the aboves: mono
			// Show value
			ShowMonoStereo(i);
			SetInputCursorPos();
		#endif //USE_LCD
		break;

	case CRSN_AFC_FAILED:	// AFC failed, re-tune the current frequency
		SetFrequency(GetDisplayFrequency(g_wFreqGrid));
		break;

	default:
		break;
	}

	// Abort when new key pressed
	//if (g_bySwFlag1 & SF1_ABORT)
	if (g_byPressedKey != KP_NO_KEY)
	{
		//g_bySwFlag1 &= (~SF1_ABORT);
		//g_byPressedKey = KP_NO_KEY;	// Swallow key
		return(LVLS_USER_ABORT_ERR);
	}
	return(LVLS_NO_ERROR);
} // End CallBack

⌨️ 快捷键说明

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