📄 lcd.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 + -