This is file "LCDfg-lite.h".
//==============================================================================
// Copyright (c) 2005-2010, Isaac Marino Bavaresco
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Neither the name of the author nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//==============================================================================
// isaacbavaresco@yahoo.com.br
//==============================================================================
// Set TAB width to 4 characters
//==============================================================================
#if !defined __LCD_CFG_H__
#define __LCD_CFG_H__
//==============================================================================
//##############################################################################
//# #
//# THIS FILE IS HEAVILY HARDWARE-DEPENDANT #
//# #
//# IT MUST BE CHANGED TO FIT YOUR BOARD'S CIRCUIT AND CLOCK #
//# #
//##############################################################################
// This version is taylored for my board at 4MHz and Hi-Tech PICC.
// Change this file for your own needs.
//==============================================================================
//
// PIC16F648A
//
// +-----------------U-----------------+
// | |
// LCD_DI <- ==| 1 RA2/AN2/Vref AN1/RA1 18 |== -> LCD_D4
// | |
// LCD_E <- ==| 2 RA3/AN3/CMP1 AN0/RA0 15 |== -> LCD_D5
// | |
// PWRON <- ==| 3 RA4/T0CKI/CMP2 OSC1/RA7 16 |== -> LCD_D6
// | |
// RIGHT -> ==| 4 RA5/!MCLR OSC2/RA6 15 |== -> LCD_D7
// | |
// ==| 5 GND VCC 14 |==
// | |
// <- ==| 6 RB0/INT T1OSI/RB7 13 |== <- UP
// | |
// RXD -> ==| 7 RB1/RX/DT T1CKI/T1OSO/RB6 12 |== <- DOWN
// | |
// TXD <- ==| 8 RB2/TX/CK RB5 11 |== ->
// | |
// LEFT -> ==| 9 RB3/CCP1 RB4 10 |== ->
// | |
// +-----------------------------------+
//
//
//==============================================================================
#include <pic.h>
//==============================================================================
// Define this macro if your board uses the LCD R/!W pin.
//#define USE_READ_PIN
// Define this macro if you want to detect when the LCD is not connected or is
// damaged. Works only if using the R/!W pin.
//#define DETECT_FAILURE
// Number of repetitions before signailng a defective display.
//#define NUMBER_OF_READS_TIMEOUT 2000
// Define this macro if your board uses four bit interface.
#define USE_FOUR_BIT_INTERFACE
//==============================================================================
//==============================================================================
//==============================================================================
//==============================================================================
// Helper macros. Depend on your board.
#define DATAPORT_OUT PORTA
#define DATAPORT_IN PORTA
#define DATAPORT_DIR TRISA
#define LCD_D4 RA1
#define LCD_D5 RA0
#define LCD_D6 RA7
#define LCD_D7 RA6
#define LCD_E RA3
#define LCD_E_DIR TRISA3
#if defined USE_READ_PIN
#define LCD_RW RB6
#define LCD_RW_DIR TRISB6
#endif // defined USE_READ_PIN
#define LCD_DI RA2
#define LCD_DI_DIR TRISA2
//==============================================================================
// These macros depend on the model of your LCD module.
// The size your screen will have at startup.
#define INITIAL_MAXX 16
#define INITIAL_MAXY 2
// The maximum size your screen may have.
#define MAXIMUM_MAXX 16
#define MAXIMUM_MAXY 2
// The usual is 8, but 4 is more useful for such a narrow display.
#define TAB_WIDTH 4
//==============================================================================
// Interrupt-related macros
// If you don't need to disable interrupts, just define them all as empty macros
// The macro 'DeclareIntSaveVar' must declare 's' with a type suitable to hold
// the CPU's current interrupts (enabled/disabled) state
#define DeclareIntSaveVar( s ) unsigned char s
// The macro 'SaveInterruptsState' must save the current interrupts state to 's'
#define SaveInterruptsState( s ) (( s ) = INTCON & 0xc0 )
// The macro 'RestoreInterruptsState' must restore the previous interrupts state
// from 's'
#define RestoreInterruptsState( s ) ( INTCON = INTCON | ( s ))
// The macro 'DisableInterrupts' must disable all interrupts that may interfere
// with the LCD interface (for instance, an interrupt that uses the LCD interface
// pins to scan a keyboard)
#define DisableInterrupts() ( INTCON = INTCON & 0x3f )
//==============================================================================
// Data port manipulation macros
// The macro 'SetDataPortAsInputs' must set the data port bits (4 or 8,
// depending on the used mode) as inputs
#if defined USE_READ_PIN
#define SetDataPortAsInputs() ( DATAPORT_DIR |= 0xc3 )
#else // defined USE_READ_PIN
#define SetDataPortAsInputs()
#endif // defined USE_READ_PIN
// The macro 'SetDataPortAsOutputs' must set the data port bits (4 or 8,
// depending on the used mode) as outputs
#define SetDataPortAsOutputs() ( DATAPORT_DIR &= 0x3c )
// In 8-bit mode, the macro 'ReadDataPortValue' must read all 8 bits of the
// data port to 's', in 4-bit mode it must read the 4 bits of the data
// port to the higher 4 bits of 's'
#define ReadDataPortValue( s ) do \
{ \
s = 0; \
if( LCD_D7 ) s |= 0x80; \
if( LCD_D6 ) s |= 0x40; \
if( LCD_D5 ) s |= 0x20; \
if( LCD_D4 ) s |= 0x10; \
} \
while( 0 )
// In 8-bit mode, the macro 'SetDataPortValue' must output all the 8 bits of 's'
// to the data port, in 4-bit mode it must output the higher 4 bits of 's' to the
// data port
#define SetDataPortValue( s ) do \
{ \
char t; \
t = DATAPORT_OUT & 0x3c; \
if( s & 0x80 ) t |= 0x40; \
if( s & 0x40 ) t |= 0x80; \
if( s & 0x20 ) t |= 0x01; \
if( s & 0x10 ) t |= 0x02; \
DATAPORT_OUT = t; \
} \
while( 0 )
//( DATAPORT_OUT = DATAPORT_OUT & 0xf0 | ((( s ) >> 4 ) & 0x0f ))
// The following macros are only needed if you are using 4-bit interface
#if defined USE_FOUR_BIT_INTERFACE
// The macro 'ReadDataPortValueLow' must read the 4 bits of the data
// port to the lower 4 bits of 's' without disturbing its 4 higher bits.
#define ReadDataPortValueLow( s ) do \
{ \
if( LCD_D7 ) s |= 0x08; \
if( LCD_D6 ) s |= 0x04; \
if( LCD_D5 ) s |= 0x02; \
if( LCD_D4 ) s |= 0x01; \
} \
while( 0 )
// The macro 'SetDataPortValueLow' must output the lower 4 bits of 's' to
// the data port.
#define SetDataPortValueLow( s ) do \
{ \
char t; \
t = DATAPORT_OUT & 0x3c; \
if( s & 0x08 ) t |= 0x40; \
if( s & 0x04 ) t |= 0x80; \
if( s & 0x02 ) t |= 0x01; \
if( s & 0x01 ) t |= 0x02; \
DATAPORT_OUT = t; \
} \
while( 0 )
#endif // defined USE_FOUR_BIT_INTERFACE
//==============================================================================
// Control pins manipulation macros
#if defined USE_READ_PIN
#define SetRWAsRead() ( LCD_RW = 1 )
#define SetRWAsWrite() ( LCD_RW = 0 )
#define SetRWAsOutput() ( LCD_RW_DIR = 0 )
#else // defined USE_READ_PIN
#define SetRWAsRead()
#define SetRWAsWrite()
#define SetRWAsOutput()
#endif // defined USE_READ_PIN
#define SetDIValue( s ) ( LCD_DI = ( s ))
#define SetDIAsData() ( LCD_DI = 1 )
#define SetDIAsInstruction() ( LCD_DI = 0 )
#define SetDIAsOutput() ( LCD_DI_DIR = 0 )
#define SetEAsEnabled() ( LCD_E = 1 )
#define SetEAsDisabled() ( LCD_E = 0 )
#define SetEAsOutput() ( LCD_E_DIR = 0 )
//==============================================================================
void Delay_10us( unsigned short t );
// Delay macros.
#define Delay500ns() asm( "nop" )
// This macro is defined this way (without calling a function) to save call-stack
// levels, because it is used in the deepest function of the package.
// NOTE: The last "nop" is important to prevent the optimizer to optimize the sequence.
#define Delay37us() do \
{ \
asm( "movlw 9" ); \
asm( "addlw -1" ); \
asm( "btfss 3,2" ); \
asm( "goto $-2" ); \
asm( "nop " ); \
} \
while( 0 )
#define Delay100us() Delay_10us( 10 )
// This macro is defined this way (without calling a function) to save call-stack
// levels, because it is used in the deepest function of the package.
// NOTE: The last "nop" is important to prevent the optimizer to optimize the sequence.
#define Delay1520us() do \
{ \
asm( "movlw 254" ); \
asm( "nop " ); \
asm( "nop " ); \
asm( "addlw -1" ); \
asm( "btfss 3,2" ); \
asm( "goto $-4" ); \
asm( "nop " ); \
} \
while( 0 )
#define Delay4100us() Delay_10us( 410 )
#define Delay15ms() Delay_10us( 1500 )
//==============================================================================
// Macro or prototype for the function 'Beep'. Define it as an empty macro if
// your board doesn't have a buzzer or the like.
#define Beep()
//==============================================================================
// This macro defines the name that your 'putc' function must have to be linked
// with the library functions ('printf', etc).
// For MPLAB-C18 it is '_user_putc', for Hi-Tech PICC it is 'putch'.
#define LCD_PUTC putch
//==============================================================================
#endif // !defined __LCD_CFG_H__
//==============================================================================