📄 xlcd.c
字号:
#include <p18cxxx.h>
#include "xlcd.h"
#include <delays.h>
/********************************************************************
* For the XLCD, from the xlcd.h file, we must provide:
* - DelayFor18TCY() provides a 18 Tcy delay
* - DelayPORXLCD() provides at least 15ms delay
* - DelayXLCD() provides at least 5ms delay
********************************************************************/
// My clock running at 4mhz - then devided by 4? to be ~ 1us/cycle ?
void DelayFor18TCY(void)
{
Delay10TCYx(0x2); //delays 20 cycles
return;
}
void DelayPORXLCD(void) // minimum 15ms
{
Delay100TCYx(0xA0); // 100TCY * 160
return;
}
void DelayXLCD(void) // minimum 5ms
{
Delay100TCYx(0x36); // 100TCY * 54
return;
}
/********************************************************************
* Function Name: OpenXLCD *
* Return Value: void *
* Parameters: lcdtype: sets the type of LCD (lines) *
* Description: This routine configures the LCD. Based on *
* the Hitachi HD44780 LCD controller. The *
* routine will configure the I/O pins of the *
* microcontroller, setup the LCD for 4- or *
* 8-bit mode and clear the display. The user *
* must provide three delay routines: *
* DelayFor18TCY() provides a 18 Tcy delay *
* DelayPORXLCD() provides at least 15ms delay *
* DelayXLCD() provides at least 5ms delay *
* *
* NOTE: I think there may be some problems with the BIT8 mode *
********************************************************************/
void OpenXLCD(unsigned char lcdtype)
{
// For PICDEM 2 Plus, setup the A/D bits so they
// don't interfere with the XLCD control bits.
ADCON1 = 0b00001110;
DelayPORXLCD(); // delay 15ms
// The data bits must be either a 8-bit port or the upper or
// lower 4-bits of a port. These pins are made into inputs
#ifdef BIT8 // 8-bit mode, use whole port
DATA_PORT = 0;
TRIS_DATA_PORT = 0xff;
#else // 4-bit mode
#ifdef UPPER // Upper 4-bits of the port
DATA_PORT &= 0x0f;
TRIS_DATA_PORT |= 0xf0;
#else // Lower 4-bits of the port
DATA_PORT &= 0xf0;
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
TRIS_RW = 0; // All control signals made outputs
TRIS_RS = 0;
TRIS_E = 0;
RW_PIN = 0; // R/W pin made low
RS_PIN = 0; // Register select pin made low
E_PIN = 0; // Clock pin made low
// Delay for 15ms to allow for LCD Power on reset
DelayPORXLCD();
// Setup interface to LCD - First Init Nibble
#ifdef BIT8 // 8-bit mode interface
TRIS_DATA_PORT = 0; // Data port output
DATA_PORT = 0b00110000; // Function set cmd(8-bit interface)
#else // 4-bit mode interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= 0b00110000; // Function set cmd(4-bit interface)
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= 0b00000011; // Function set cmd(4-bit interface)
#endif
#endif
E_PIN = 1; // Clock the cmd in
DelayFor18TCY();
E_PIN = 0;
// Delay for at least 4.1ms
DelayXLCD();
// Second Init Nibble
#ifdef BIT8 // 8-bit mode interface
#else // 4-bit mode interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= 0b00110000; // Function set cmd(4-bit interface)
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= 0b00000011; // Function set cmd(4-bit interface)
#endif
#endif
E_PIN = 1; // Clock the cmd in
DelayFor18TCY();
E_PIN = 0;
// Delay for at least 100us
DelayXLCD();
// Third Init Nibble
#ifdef BIT8 // 8-bit interface
DATA_PORT = 0b00110000; // Function set cmd(8-bit interface)
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00110000;
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00000011;
#endif
#endif
E_PIN = 1; // Clock the cmd in
DelayFor18TCY();
E_PIN = 0;
// Delay for at least 4.1ms
DelayXLCD();
// Fourth Init Nibble (Word for 8 bit)
#ifdef BIT8 // 8-bit interface
DATA_PORT = 0b00111100; // Function set cmd(8-bit interface)
// Check lower Nibble for correct bits
// This Init sequence has some issues!
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00100000;
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00000010;
#endif
#endif
E_PIN = 1; // Clock cmd in
DelayFor18TCY();
E_PIN = 0;
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0xff; // Make data port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make data nibble input
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make data nibble input
#endif
#endif
// From now on, send bytes - (2) nibbles for 4bit
// Set data interface width, # lines, font
while(BusyXLCD()); // Wait if LCD busy
// WriteCmdXLCD(lcdtype); // Function set cmd
WriteCmdXLCD(0x28); // Function set cmd
// Turn the display on then off
while(BusyXLCD()); // Wait if LCD busy
// WriteCmdXLCD(DOFF&CURSOR_OFF&BLINK_OFF); // Display OFF/Blink OFF
WriteCmdXLCD(0x0D);
while(BusyXLCD()); // Wait if LCD busy
// WriteCmdXLCD(DON&CURSOR_ON&BLINK_ON); // Display ON/Blink ON
// Clear display
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(0x01); // Clear display
// Set entry mode inc, no shift
while(BusyXLCD()); // Wait if LCD busy
// WriteCmdXLCD(SHIFT_CUR_LEFT); // Entry Mode
WriteCmdXLCD(0x06);
// Set DD Ram address to 0
while(BusyXLCD()); // Wait if LCD busy
// SetDDRamAddr(0); // Set Display data ram address to 0
WriteCmdXLCD(0x80); // Set Display data ram address to 0
return;
}
/********************************************************************
* Function Name: BusyXLCD *
* Return Value: char: busy status of LCD controller *
* Parameters: void *
* Description: This routine reads the busy status of the *
* Hitachi HD44780 LCD controller. *
********************************************************************/
unsigned char BusyXLCD(void)
{
RW_PIN = 1; // Set the control bits for read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock in the command
DelayFor18TCY();
#ifdef BIT8 // 8-bit interface
if(DATA_PORT&0x80) // Read bit 7 (busy bit)
{ // If high
E_PIN = 0; // Reset clock line
RW_PIN = 0; // Reset control line
return 1; // Return TRUE
}
else // Bit 7 low
{
E_PIN = 0; // Reset clock line
RW_PIN = 0; // Reset control line
return 0; // Return FALSE
}
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
if(DATA_PORT&0x80)
#else // Lower nibble interface
if(DATA_PORT&0x08)
#endif
{
E_PIN = 0; // Reset clock line
DelayFor18TCY();
E_PIN = 1; // Clock out other nibble
DelayFor18TCY();
E_PIN = 0;
RW_PIN = 0; // Reset control line
return 1; // Return TRUE
}
else // Busy bit is low
{
E_PIN = 0; // Reset clock line
DelayFor18TCY();
E_PIN = 1; // Clock out other nibble
DelayFor18TCY();
E_PIN = 0;
RW_PIN = 0; // Reset control line
return 0; // Return FALSE
}
#endif
}
/********************************************************************
* Function Name: putrsXLCD
* Return Value: void
* Parameters: buffer: pointer to string
* Description: This routine writes a string of bytes to the
* Hitachi HD44780 LCD controller. The user
* must check to see if the LCD controller is
* busy before calling this routine. The data
* is written to the character generator RAM or
* the display data RAM depending on what the
* previous SetxxRamAddr routine was called.
********************************************************************/
/*
void putrsXLCD(const rom char *buffer)
{
while(*buffer) // Write data to LCD up to null
{
while(BusyXLCD()); // Wait while LCD is busy
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
}
return;
}
*/
/********************************************************************
* Function Name: putsXLCD
* Return Value: void
* Parameters: buffer: pointer to string
* Description: This routine writes a string of bytes to the
* Hitachi HD44780 LCD controller. The user
* must check to see if the LCD controller is
* busy before calling this routine. The data
* is written to the character generator RAM or
* the display data RAM depending on what the
* previous SetxxRamAddr routine was called.
********************************************************************/
void putsXLCD(char *buffer)
{
while(*buffer) // Write data to LCD up to null
{
while(BusyXLCD()); // Wait while LCD is busy
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
}
return;
}
/*********************************************************************
* Function Name: ReadAddrXLCD *
* Return Value: char: address from LCD controller *
* Parameters: void *
* Description: This routine reads an address byte from the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The address*
* is read from the character generator RAM or *
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
*********************************************************************/
unsigned char ReadAddrXLCD(void)
{
char data; // Holds the data retrieved from the LCD
#ifdef BIT8 // 8-bit interface
RW_PIN = 1; // Set control bits for the read
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -