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

📄 lcd.c

📁 LV24000的单片机DEMO程序
💻 C
字号:
/************************************************************************
*
*   Copyright(c) 2004 ItoM BV
*   All Rights Reserved.
*
*   LV2400x evaluation kit: Driving LCD in 4 bits mode
*   File name:	LCD.c
*
*************************************************************************/

#include <stdio.h>
#include "common.h"
#include "Lv24Ekit.h"
#include "LcdDef.h"

/*-------------------------------------------------------------------
        LCD routines
-------------------------------------------------------------------*/
#ifdef HITACHI_LCD
void InitLcd(void) 
{
   // Clear all LCD control lines
//  _putbit(0, LCD_CONTROL_PORT, LCD_RS);
//  _putbit(0, LCD_CONTROL_PORT, LCD_RW);
//  _putbit(0, LCD_CONTROL_PORT, LCD_E);
  LCD_CONTROL_PORT = 0;

  DelayUs(DLT_15ms);		// Wait 15 ms
  SendLcdInitCmd(0x30);		// Command for init interface (D[7:4]=0x3) 
  DelayUs(DLT_5ms);		// Wait 4.1 ms
  SendLcdInitCmd(0x30);		// Command for init interface (D[7:4]=0x3) 
  DelayUs(DLT_100us); 		// Wait 100 us
  SendLcdInitCmd(0x30);		// Command for init interface (D[7:4]=0x3) 
  DelayUs(DLT_5ms);		// Wait 4.1 ms
  SendLcdInitCmd(0x20);		// Command for set 4 bit operation (D[7:4]=0x2)
  DelayUs(DLT_40us);		// Wait 40 us

  SendLcdCmd(LCD_FONT); 	// Set LCD font
  DelayUs(DLT_40us);		// Wait 40 us
  SendLcdCmd(SET_DISP|DISP_EN); // Enable display
  DelayUs(DLT_40us);		// Wait 40 us
  SendLcdCmd(CLR_DISP); 	// Clear display 01 or 0000 0001
  DelayUs(DLT_2ms);		// Wait 1.53 ms
  SendLcdCmd(ENTRY_INC); 	// Set Entry Mode Inc, No shift, 06 or 0000 0110
  DelayUs(DLT_40us);		// Wait 40 us
  SendLcdCmd(DD_RAM_ADDR); 	// Set Display Ram address 80 or 1000 0000
  DelayUs(DLT_40us);		// Wait 40 us
}// End InitLcd
#endif //HITACHI_LCD

#ifdef HITACHI_LCD
void ClearDisplay(void)
{
	SendLcdCmd(CLR_DISP); 	// Clear display 01 or 0000 0001
  	//DelayUs(DLT_2ms);	// Wait 1.53 ms
} // End ClearDisplay
#endif //HITACHI_LCD

#ifdef HITACHI_LCD
void ClearLcdPos(BYTE byPos, BYTE byLen)
{
	// Fill the LCD with number of spaces (specified by byLen) from position byPos
	BYTE i;

	// Breng the cursor to specified position
	SendLcdCmd(byPos); 	// Set cursor position

   	for (i=0; i<byLen; i++)
		SendLcdData(' ');
	SendLcdCmd(byPos); 	// Set cursor position back
} // End ClearLcdPos
#endif //HITACHI_LCD

#ifdef HITACHI_LCD
void SendLcdInitCmd(BYTE byInitCmd) 
{
   	// Set d[7:4] of byInitCmd to  LCD_DATA_PORT
	LCD_DATA_PORT = GetWriteLcdPattern(byInitCmd);   // Send data to LCD
   	_putbit(1, LCD_CONTROL_PORT, LCD_E); // Set enable 
   	_putbit(0, LCD_CONTROL_PORT, LCD_E); // Clear enable 
} // End SendLcdInitCmd
#endif //HITACHI_LCD

/* Send command to LCD 4 bit mode (with WaitLcdReady) */
#ifdef HITACHI_LCD
void SendLcdCmd(BYTE byCmd)
{
   WaitLcdReady();
   _putbit(0, LCD_CONTROL_PORT, LCD_RW); // Set LCD in write mode
   _putbit(0, LCD_CONTROL_PORT, LCD_RS); // set LCD in command mode
   DataToLcd(byCmd);		  // Send data to LCD
}// End SendLcdCmd 
#endif //HITACHI_LCD

#ifdef HITACHI_LCD
void SendLcdData(BYTE byData)
{
   WaitLcdReady();
   _putbit(0, LCD_CONTROL_PORT, LCD_RW);// Set LCD in write mode
   _putbit(1, LCD_CONTROL_PORT, LCD_RS);// Set LCD in data mode
   DataToLcd(byData);		  	// Send data to LCD
}// End SendLcdData
#endif //HITACHI_LCD

#ifdef HITACHI_LCD
void DataToLcd(BYTE byData)
{
  // Send high nibble first
  LCD_DATA_PORT = GetWriteLcdPattern(byData & 0xF0);	//D[7:4] of byData

  // Generate strobe (Toggle E) for LCD
   _putbit(1, LCD_CONTROL_PORT, LCD_E);
   _putbit(0, LCD_CONTROL_PORT, LCD_E);

  // Send low nibble
  byData <<= 4;					// Shift low nibble to high nibble
  LCD_DATA_PORT = GetWriteLcdPattern(byData); 	// Send low nibble to LCD port

  // Generate strobe (Toggle E) for LCD
   _putbit(1, LCD_CONTROL_PORT, LCD_E);
   _putbit(0, LCD_CONTROL_PORT, LCD_E);

  // Data to LCD Execution time is 40 us
  DelayUs(DLT_40us);				// Wait 40 us
  LCD_DATA_PORT = GetWriteLcdPattern(0x00); 	// Drive data port low to allow keyboard interrupts @@@
} // End DataToLcd
#endif //HITACHI_LCD

#ifdef HITACHI_LCD
BYTE GetWriteLcdPattern(BYTE byLcdData)
{
	BYTE byTmp;

	byTmp = (byLcdData & LCD_DATAPIN_MASK); // Take over the LCD data bits
//	byTmp |= (BYTE)(~LCD_DATAPIN_MASK);	// Make sure non-LCD bits are set (for pull up of keypad)
	byTmp |= (LCD_DATA_PORT & (~LCD_DATAPIN_MASK)); // preserve the non-LCD data bit
	return(byTmp);
} // End GetWriteLcdPattern
#endif //HITACHI_LCD

#ifdef HITACHI_LCD
void WaitLcdReady()
{
   BYTE byDone, byStat;

   // Change the 4 data bits of LCD to input (for reading status) @@@
   LCD_DDIR_PORT &= (~LCD_DATAPIN_MASK); // clear direction bit to change data pin to input mode
//   LCD_DATA_PORT &= (~LCD_DATAPIN_MASK); // Disable the pull up resistors @@@

   // Set LCD in read mode
   _putbit(1, LCD_CONTROL_PORT, LCD_RW);

   // RS low to read busy flag
   _putbit(0, LCD_CONTROL_PORT, LCD_RS);

   byDone = 0;
   while (byDone == 0)
   {
       // Generate strobe (Toggle E) for LCD
       _putbit(1, LCD_CONTROL_PORT, LCD_E);
       _putbit(0, LCD_CONTROL_PORT, LCD_E);
       byStat = LCD_DATA_PORT;
       if ( ( byStat & 0x80) == 0 )	// Check bit 7
           byDone = 1; // Busy flag clear - LCD is ready

       // Generate strobe for the low nibble to avoid dangling data
       _putbit(1, LCD_CONTROL_PORT, LCD_E);
       _putbit(0, LCD_CONTROL_PORT, LCD_E);
   }
   // Set all 4 bits of LCD to output	@@@
  LCD_DDIR_PORT |= (LCD_DATAPIN_MASK); // Set direction bit to change data pin to output mode
} // End WaitLcdReady
#endif //HITACHI_LCD

#ifdef HITACHI_LCD
BYTE DetectLcd()
{
   BYTE byData, byTemp;

   // Set a value into RAM location 0
   SendLcdCmd(SET_CURSOR | LCD_LINE0 | 0x00);
   SendLcdData('1');

   // Set RAM pointer back to location 0 for reading it
   SendLcdCmd(SET_CURSOR | LCD_LINE0 | 0x00);

   // Set all 4 bits of LCD to input @@@
   LCD_DDIR_PORT &= (~LCD_DATAPIN_MASK); // clear direction bit to change data pin to input mode
   LCD_DATA_PORT &= (~LCD_DATAPIN_MASK); // Disable the pull up resistors

   // Set LCD in read mode
   _putbit(1, LCD_CONTROL_PORT, LCD_RW);

   // RS high to access RAM data
   _putbit(1, LCD_CONTROL_PORT, LCD_RS);

   // Generate strobe (Toggle E) for LCD
   _putbit(1, LCD_CONTROL_PORT, LCD_E);
   _putbit(0, LCD_CONTROL_PORT, LCD_E);

   // Read high nibble
   byData = LCD_DATA_PORT;
   byData &= 0xF0; // Discard bit [3:0]

   // Generate strobe (Toggle E) for LCD
   _putbit(1, LCD_CONTROL_PORT, LCD_E);
   _putbit(0, LCD_CONTROL_PORT, LCD_E);

   // Read Low nibble
   byTemp = LCD_DATA_PORT;
   byTemp >>=4;	// Shift high nible (LCD data) to correct position

   // Patch data
   byData |= byTemp;

   // Set all 4 bits of LCD to output @@@
   LCD_DDIR_PORT &= (~LCD_DATAPIN_MASK); // clear direction bit to change data pin to input mode

   // Verify if we read what we have written
   if (byData == (BYTE)'1')
       return(1);
   return(0);
} // End DetectLcd
#endif //HITACHI_LCD

#ifdef USE_LCD
void PrintString(BYTE byPos, char *pStr)
{
   if (byPos != CURS_CURPOS)
      SendLcdCmd(byPos); 	// Set cursor position

   while (*pStr)
   {
#ifdef BOLYMIN_LCD
	SendLcdChar(*pStr);
#endif //BOLYMIN_LCD

#ifdef HITACHI_LCD
	SendLcdData(*pStr);
#endif //HITACHI_LCD
	pStr++;
   }
} // End PrintString
#endif //USE_LCD

#ifdef USE_LCD
void PrintDword(BYTE byPos, DWORD dw)
{
	char buf[12];
	BYTE i, byLen;
	DWORD dwTmp;

	// Find out size of buffer for dw
	dwTmp=10;
	byLen=0;
	while (dw>=dwTmp)
	{
		byLen++;
		dwTmp *= 10;
	}

	if (byLen>10)
		byLen=10;
	for (i=0; i<=byLen; i++)
	{
		buf[byLen-i] = '0'+(dw%10);
		dw/=10;
	}
	buf[i]=0;
	PrintString(byPos, buf);
} // End PrintDword
#endif //USE_LCD

#ifdef USE_LCD
void PrintFreq10k(BYTE byPos, WORD wFreq)
{
	// FM: wFreq in 10 kHz unit - Notation 108.00MHz
	// AM: wFreq in kHz unit - Notation 1500kHz
	// Print frequency at line 0 - position 0
	// Screen lay out (x is space):
	// 	108.00MHz
	// 	x87.50MHz
	// 	x1500xkHz
	// 	xx575xkHz
	WORD w1, w2;

	if (byPos != CURS_CURPOS)
      		SendLcdCmd(byPos); 	// Set cursor position

#ifdef SUPPORT_AMFM
	if ( (g_byStnFlag & STN_AM_MODE) == STN_AM_MODE )
	{
		SendLcdData(LCDC_SPACE);	// 1 leading space for AM frequency
		if (wFreq<1000)
			SendLcdData(LCDC_SPACE);// Extra leading space for frequency < 1000 kHz
		PrintDword(CURS_CURPOS, (DWORD)wFreq);
		PrintString(CURS_CURPOS, " kHz");
		return; // Done if AM mode
	}
#endif //SUPPORT_AMFM

	w1 = wFreq/100;	// MHz
	w2 = wFreq%100;	// kHz
	if (w1<100)	// Frequency < 100 MHz
		SendLcdData(LCDC_SPACE);		// Leading space for frequency <100MHz
	PrintDword(CURS_CURPOS, (DWORD)w1);
	SendLcdData(LCDC_DOT);		// Dot (MHz/KHz separator)
	if (w2<10)
		SendLcdData(LCDC_ZERO);	// Leading zero for xx.05
	PrintDword(CURS_CURPOS, (DWORD)w2);
	PrintString(CURS_CURPOS, "MHz");
} // End PrintFreq10k
#endif //USE_LCD

#ifdef USE_LCD
void ShowStandAloneScreen(void)
{
	// Clear display
	ClearDisplay();

	// Show current frequency
	CallBack(CRSN_STN_CHNG);	// Station changed

	// Show current menu

} // End ShowStandAloneScreen
#endif //USE_LCD

#ifdef USE_LCD
void ShowUsbModeScreen(void)
{
	// Clear display
	ClearDisplay();

#ifdef BOLYMIN_LCD
	TurnOffIcons();
#endif //BOLYMIN_LCD

	PrintString(CURS_HOME, STR_SIGNON1);
	PrintString(CURS_1_0, STR_USBMODE);
	PrintString(CURS_CURPOS, STR_VERSION);
} // End ShowUsbModeScreen
#endif //USE_LCD

#ifdef USE_LCD
void ShowScanStart(BYTE byFlag)
{
	// Clear current status line
	ClearLcdPos(LCDPOS_STATUS, LCDLEN_STATUS);
	
	// Show new one
	if (byFlag & SCANSTN_AUTO)
		PrintString(CURS_CURPOS, "Auto");
	PrintString(CURS_CURPOS, "Scan ");

	// Show direction
	if (byFlag & SCANSTN_DIR)
		SendLcdData(EVK_SCAN_UP);	// Scan up
	else
		SendLcdData(EVK_SCAN_DOWN);	// Scan down
} // End ShowScanStart
#endif //USE_LCD

#ifdef USE_LCD
void ShowSetFreqStart(void)
{
	// Clear current status line
	ClearLcdPos(LCDPOS_STATUS, LCDLEN_STATUS);

	// Show new one
	PrintString(CURS_CURPOS, "Set freq.");
} // End ShowScanStart
#endif //USE_LCD

#ifdef USE_LCD
void ShowPreset(BYTE byNr, BOOL bStore)
{
	// Clear current name field and status
	ClearLcdPos(LCDPOS_STATUS, LCDLEN_STATUS);

	// Show new one
	if (bStore)
		PrintString(CURS_CURPOS, "Store #");
	else
		PrintString(CURS_CURPOS, "Recall ");
	PrintDword(CURS_CURPOS, (DWORD)byNr);
} // End ShowPreset
#endif //USE_LCD

#ifdef USE_LCD
void ShowResult(BYTE byResult)
{
	if (byResult == LVLS_NO_ERROR)
	{
		PrintString(LCDPOS_ACTSTAT, "OK");
	}
	else
	{
		PrintString(LCDPOS_ACTSTAT, "Err");
		PrintDword(CURS_CURPOS, (DWORD)byResult);
	}
} // End ShowResult
#endif //USE_LCD

#ifdef USE_LCD
void PrintKeyNotSupport(BYTE byNrKey)
{
	ClearLcdPos(LCDPOS_STATUS, LCDLEN_STATUS);

	PrintString(CURS_CURPOS, "Key ");

	// Print key number
#ifdef BOLYMIN_LCD
	SendLcdChar(byNrKey+'0');
#endif //BOLYMIN_LCD

#ifdef HITACHI_LCD
	SendLcdData(byNrKey+'0');
#endif //HITACHI_LCD
	
	PrintString(LCDPOS_FVAL, "NA");
} // End PrintKeyNotSupport
#endif //USE_LCD

#ifdef USE_LCD
void ShowFieldStrength(BYTE byFs)
{
	PrintDword(LCDPOS_FS, (DWORD)byFs);
} // End ShowFieldStrength
#endif //USE_LCD

#ifdef USE_LCD
void ShowMonoStereo(BYTE cMsChar)
{
#ifdef BOLYMIN_LCD
	if (cMsChar == EVK_STEREO_DET)
		ShowIcon(EVK_STEREO_DET, SHOW_ICON);
	else
		ShowIcon(EVK_STEREO_DET, HIDE_ICON);

	if (cMsChar == EVK_MONO)
		ShowIcon(EVK_STEREO, HIDE_ICON);
	else
		ShowIcon(EVK_STEREO, SHOW_ICON);
#endif //BOLYMIN_LCD

#ifdef HITACHI_LCD
      	SendLcdCmd(LCDPOS_MS); 	// Set cursor position
	SendLcdData(cMsChar);	// Display stereo char.
#endif //HITACHI_LCD
} // End ShowMonoStereo
#endif //USE_LCD

⌨️ 快捷键说明

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