They only provided me the sourcecode in a protected PDF document. Here's that sourcecode. It should be noted that there's a little fault in the software.
The PWM that should control the LCD contrast actually makes the buzzer make a constant noise (the wrong PWM is being controlled):
/******************************************************************************
* PICDEM 2 PLUS
* SAMPLE CODE
* DB-DP113_Ver2.0 © 2004 -2008 Sure Electronics Inc.
*******************************************************************************/
#include <p18f4520.h>
#include <sw_i2c.h>
#include <usart.h>
#include <delays.h>
#include <timers.h>
#pragma config OSC = HS
#pragma config PWRT = OFF
#pragma config BOREN = OFF
#pragma config WDT = OFF
#pragma config MCLRE = ON
#pragma config PBADEN = OFF
#pragma config LVP = OFF
#define Func_key PORTBbits.RB0 // Function key
#define change_key PORTAbits.RA4 // Change key
unsigned char reset_key_pressed,last_reset_key_pressed;
unsigned char Func_key_pressed,last_Func_key_pressed;
unsigned char change_key_pressed,last_change_key_pressed;
unsigned char cnt_fuckey;
unsigned char cnt_chgkey;
unsigned char PWM_data;
char PWMbuf[6];
unsigned char key_flag=0;
char pointer=0;
unsigned char i2c_var;
unsigned int cvalue,fvalue; // Memory Centigrade and Fahrenheit Value
char cent_buf[6],fahr_buf[6]; // Centigrade and Fahrenheit Value Array
char LCD_name[]="Sure Electronics";
char LCD_Ver[]="Ver 2.1";
void timer_isr (void); // Timer0 Interrupt Service Routine
void init(void); // Initialize Control Microchip
char Funckey(void); // Get State of Function Switch
char changekey(void); // Get State of Change Function Switch
void PWM(unsigned char i); // PWM Mode
void LCD_init(void); // Set LCD Initial Display
void LCD_display(char *i); // LCD display
void delayinit(void);
void sendUSART(char *sendbuf);
/**************************************************************************/
void init(void)
{
CMCON=0b00000111; // Close Comparator
TRISA=0b00010000;
TRISB=0b00000001;
TRISC=0b11000000;
TRISD=0b00000000;
TRISE=0b00001000;
ADCON1=0b00001111; // Digital Channel Allocation
SPBRG=38; // Baud Rate 4800bps
BAUDCONbits.BRG16=0; // Choose 8-bit Baud Rate Generator
TXSTAbits.BRGH=0; // High Baud Rate
TXSTAbits.SYNC=0; // Asynchronous Mode
RCSTAbits.SPEN=1; // Enable Serial
TXSTAbits.TX9=0; // 8-bit Transmission
TXSTAbits.TXEN=1; // Enable Transmission
CCP1CON=0b00001100; // Set PWM Mode
CCP2CON=0b00001100;
T2CONbits.TMR2ON = 0;
T2CONbits.T2OUTPS3 = 1;
T2CONbits.T2OUTPS2 = 1;
T2CONbits.T2OUTPS1 = 1;
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2CKPS1 = 1;
T2CONbits.T2CKPS1 = 1;
PR2 = 255;
TRISCbits.TRISC2=0;
TRISCbits.TRISC1=0;
T2CONbits.TMR2ON = 1;
CCPR1L = 100;
CCPR2L = 0;
}
/**************************************************************************/
void PWM(unsigned char i)
{
CCP1CON=0b00001100;
T2CONbits.TMR2ON = 0;
T2CONbits.T2OUTPS3 = 1;
T2CONbits.T2OUTPS2 = 1;
T2CONbits.T2OUTPS1 = 1;
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2CKPS1 = 1;
T2CONbits.T2CKPS1 = 1;
PR2 = 255;
TRISCbits.TRISC2=0;
T2CONbits.TMR2ON = 1;
CCPR1L = 25*i;
}
/**************************************************************************/
char Funckey(void)
{
unsigned char temp;
Func_key_pressed=Func_key;
if((Func_key_pressed==0)&(last_Func_key_pressed==1))
{
Delay100TCYx(1); //Delay to avoid buffeting
if(Func_key_pressed==0)cnt_fuckey++;
}
last_Func_key_pressed=Func_key_pressed;
temp=cnt_fuckey%3;
return temp;
}
char changekey(void)
{
unsigned char temp;
change_key_pressed=change_key;
if((change_key_pressed==0)&(last_change_key_pressed==1))
{
Delay100TCYx(1); //Delay to avoid buffeting
if(change_key_pressed==0)cnt_chgkey++;
}
last_change_key_pressed=change_key_pressed;
temp=cnt_chgkey%11;
return temp;
}
/**************************************************************************/
// Write data
void byte_write(unsigned char adr,unsigned char data)
{
SWStartI2C();
i2c_var = SWPutcI2C(0xA0); // Control byte
SWAckI2C();
i2c_var = SWPutcI2C(adr); // Word address
SWAckI2C();
i2c_var = SWPutcI2C(data); // Data
SWAckI2C();
SWStopI2C();
}
// Read data
void byte_read(unsigned char adr)
{
SWStartI2C();
i2c_var = SWPutcI2C( 0xA0 ); // Control byte
SWAckI2C();
i2c_var = SWPutcI2C(adr); // Word address
SWAckI2C();
SWRestartI2C();
i2c_var = SWPutcI2C( 0xA1 ); // Control byte
SWAckI2C();
i2c_var = SWGetcI2C();//data
SWStopI2C();
}
// Write string
void page_write(unsigned char adr,unsigned char wdata[])
{
SWStartI2C();
i2c_var = SWPutcI2C(0xA0); // Control byte
SWAckI2C();
i2c_var = SWPutcI2C(adr); // Word address
SWAckI2C();
i2c_var = SWPutsI2C(wdata); // Data
SWStopI2C();
}
// Read string
void sequential_read(unsigned char adr,unsigned char rdata[],unsigned char len)
{
SWStartI2C();
i2c_var = SWPutcI2C( 0xA0 ); // Control byte
SWAckI2C();
i2c_var = SWPutcI2C(adr); // Word address
SWAckI2C();
SWRestartI2C();
i2c_var = SWPutcI2C( 0xA1 ); // Control byte
SWAckI2C();
i2c_var = SWGetsI2C(rdata,len); // Data
SWStopI2C();
}
// Inquiries confirmed
void ack_poll( void )
{
SWStartI2C();
i2c_var = SWPutcI2C( 0xA0 ); // Control byte
while( SWAckI2C() )
{
SWRestartI2C();
i2c_var = SWPutcI2C(0xA0); // Data
}
SWStopI2C();
}
/**************************************************************************/
void LM75_init(void) // Temperature Sensor Initializtion
{
SWStartI2C();
i2c_var = SWPutcI2C(0x90); // Control byte
SWAckI2C();
i2c_var = SWPutcI2C(0x01); // Configure register
SWAckI2C();
i2c_var = SWPutcI2C(0x18); // Configure byte
SWAckI2C();
SWStopI2C();
}
void LM75_temperature(void)
{
unsigned char tptr[2];
unsigned int temp_H,temp_L;
SWStartI2C();
i2c_var = SWPutcI2C(0x90); // Control byte
SWAckI2C();
i2c_var = SWPutcI2C(0x00); // Data Address
SWAckI2C();
SWRestartI2C();
i2c_var = SWPutcI2C(0x91); // Control byte
SWAckI2C();
i2c_var = SWGetsI2C(tptr, 2); // Read Temperature
SWStopI2C();
temp_H=tptr[0]; // High bits
temp_L=tptr[1]; // Low bits
// Compute Centigrade
cvalue=(temp_H<<8)|temp_L;
cent_buf[0]=' ';
if(cvalue&0x80==1)
{
cvalue=~cvalue+1; // Calculate Base Complement
cent_buf[0]='-';
}
cvalue=cvalue>>5;
cvalue=cvalue * 1.25;
cent_buf[1]=cvalue/100+48;
cent_buf[2]=(cvalue/10)%10+48;
cent_buf[3]='.';
cent_buf[4]=cvalue%10+48;
cent_buf[5]='\0';
// Compute Fahrenheit
fvalue=((cvalue*9)/5)+32;
fahr_buf[0]=' ';
if(fvalue&0x80==1)
{
fvalue=~fvalue+1; // Calculate Base Complement
fahr_buf[0]='-';
}
fahr_buf[1]=fvalue/100+48;
fahr_buf[2]=(fvalue/10)%10+48;
fahr_buf[3]='.';
fahr_buf[4]=fvalue%10+48;
fahr_buf[5]='\0';
}
/**************************************************************************/
/* 8-bit or 4-bit interface type
* For 8-bit operation uncomment the #define BIT8
*/
#define BIT8
/* When in 4-bit interface define if the data is in the upper or lower nibble.
For lower nibble, comment the #define UPPER
*/
/* #define UPPER */
/* DATA_PORT defines the port which the LCD data lines are connected to */
#define DATA_PORT PORTD
#define TRIS_DATA_PORT TRISD
/* CTRL_PORT defines the port where the control lines are connected.
* These are just samples, change to match your application.
*/
#define RW_PIN PORTAbits.RA2 /* PORT for RW */
#define TRIS_RW DDRAbits.RA2 /* TRIS for RW */
#define RS_PIN PORTAbits.RA3 /* PORT for RS */
#define TRIS_RS DDRAbits.RA3 /* TRIS for RS */
#define E_PIN PORTAbits.RA1 /* PORT for E */
#define TRIS_E DDRAbits.RA1 /* TRIS for E */
/* Display ON/OFF Control defines */
#define DON 0b00001111 /* Display on */
#define DOFF 0b00001011 /* Display off */
#define CURSOR_ON 0b00001111 /* Cursor on */
#define CURSOR_OFF 0b00001101 /* Cursor off */
#define BLINK_ON 0b00001111 /* Cursor Blink */
#define BLINK_OFF 0b00001110 /* Cursor No Blink */
/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT 0b00010011 /* Cursor shifts to the left */
#define SHIFT_CUR_RIGHT 0b00010111 /* Cursor shifts to the right */
#define SHIFT_DISP_LEFT 0b00011011 /* Display shifts to the left */
#define SHIFT_DISP_RIGHT 0b00011111 /* Display shifts to the right */
/* Function Set defines */
#define FOUR_BIT 0b00101111 /* 4-bit Interface */
#define EIGHT_BIT 0b00111111 /* 8-bit Interface */
#define LINE_5X7 0b00110011 /* 5x7 characters, single line */
#define LINE_5X10 0b00110111 /* 5x10 characters */
#define LINES_5X7 0b00111011 /* 5x7 characters, multiple line */
#define PARAM_SCLASS auto
#define MEM_MODEL far /* Change this to near for small memory model */
/* OpenXLCD
* Configures I/O pins for external LCD
*/
void OpenXLCD(PARAM_SCLASS unsigned char);
/* SetCGRamAddr
* Sets the character generator address
*/
void SetCGRamAddr(PARAM_SCLASS unsigned char);
/* SetDDRamAddr
* Sets the display data address
*/
void SetDDRamAddr(PARAM_SCLASS unsigned char);
/* BusyXLCD
* Returns the busy status of the LCD
*/
unsigned char BusyXLCD(void);
/* ReadAddrXLCD
* Reads the current address
*/
unsigned char ReadAddrXLCD(void);
/* ReadDataXLCD
* Reads a byte of data
*/
char ReadDataXLCD(void);
/* WriteCmdXLCD
* Writes a command to the LCD
*/
void WriteCmdXLCD(PARAM_SCLASS unsigned char);
/* WriteDataXLCD
* Writes a data byte to the LCD
*/
void WriteDataXLCD(PARAM_SCLASS char);
/* putcXLCD
* A putc is a write
*/
#define putcXLCD WriteDataXLCD
/* putsXLCD
* Writes a string of characters to the LCD
*/
void putsXLCD(PARAM_SCLASS char *);
/* putrsXLCD
* Writes a string of characters in ROM to the LCD
*/
void putrsXLCD(PARAM_SCLASS const MEM_MODEL rom char *);
/* User defines these routines according to the oscillator frequency */
extern void DelayFor18TCY(void);
extern void DelayPORXLCD(void);
extern void DelayXLCD(void);
/********************************************************************
* 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: 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-bit or *
* 8-bit mode and clear screen. 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 *
********************************************************************/
void OpenXLCD(unsigned char lcdtype)
{
// 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
#ifdef BIT8 // 8-bit mode interface
TRIS_DATA_PORT &= 0; // Data port output
DATA_PORT &= 0;
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 |= 0b00100000; // Function set cmd(4-bit interface)
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= 0b00000010; // 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();
// Setup interface to LCD
#ifdef BIT8 // 8-bit interface
DATA_PORT &= 0;
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 |= 0b00100000;
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00000010;
#endif
#endif
E_PIN = 1; // Clock the cmd in
DelayFor18TCY();
E_PIN = 0;
// Delay for at least 100us
DelayXLCD();
// Setup interface to LCD
#ifdef BIT8 // 8-bit interface
DATA_PORT &= 0;
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 |= 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
// Set data interface width, # lines, font
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(lcdtype); // Function set cmd
// Turn the display on then off
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(DOFF); // Display OFF/Blink OFF
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(DON); // Display ON/Blink ON
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(BLINK_OFF&CURSOR_OFF); // Display ON/Blink OFF
// 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
// Set DD Ram address to 0
while(BusyXLCD()); // Wait if LCD busy
SetDDRamAddr(0); // Set Display data ram address to 0
return;
}
/********************************************************************
* 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
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data out of the LCD controller
DelayFor18TCY();
data = DATA_PORT; // Save the data in the register
E_PIN = 0;
RW_PIN = 0; // Reset the control bits
#else // 4-bit interface
RW_PIN = 1; // Set control bits for the read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data out of the LCD controller
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the nibble into the upper nibble
of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // Read the nibble into the upper nibble
of data
#endif
E_PIN = 0; // Reset the clock
DelayFor18TCY();
E_PIN = 1; // Clock out the lower nibble
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the nibble into the lower nibble
of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the nibble into the lower nibble
of data
#endif
E_PIN = 0;
RW_PIN = 0; // Reset the control lines
#endif
return (data&0x7f); // Return the address, Mask off the busy bit
}
/********************************************************************
* Function Name: ReadDataXLCD *
* Return Value: char: data byte from LCD controller *
* Parameters: void *
* Description: This routine reads a data byte from the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The data *
* is read from the character generator RAM or *
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
********************************************************************/
char ReadDataXLCD(void)
{
char data;
#ifdef BIT8 // 8-bit interface
RS_PIN = 1; // Set the control bits
RW_PIN = 1;
DelayFor18TCY();
E_PIN = 1; // Clock the data out of the LCD
DelayFor18TCY();
data = DATA_PORT; // Read the data
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#else // 4-bit interface
RW_PIN = 1;
RS_PIN = 1;
DelayFor18TCY();
E_PIN = 1; // Clock the data out of the LCD
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the upper nibble of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // read the upper nibble of data
#endif
E_PIN = 0; // Reset the clock line
DelayFor18TCY();
E_PIN = 1; // Clock the next nibble out of the LCD
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the lower nibble of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the lower nibble of data
#endif
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#endif
return(data); // Return the data byte
}
/********************************************************************
* Function Name: SetCGRamAddr *
* Return Value: void *
* Parameters: CGaddr: character generator ram address *
* Description: This routine sets the character generator *
* address of the Hitachi HD44780 LCD *
* controller. The user must check to see if *
* the LCD controller is busy before calling *
* this routine. *
********************************************************************/
void SetCGRamAddr(unsigned char CGaddr)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make data port ouput
DATA_PORT = CGaddr | 0b01000000; // Write cmd and address to
port
RW_PIN = 0; // Set control signals
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Make data port inputs
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make nibble input
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((CGaddr | 0b01000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make nibble input
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((CGaddr |0b01000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control signals
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((CGaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (CGaddr&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make inputs
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make inputs
#endif
#endif
return;
}
/********************************************************************
* Function Name: SetDDRamAddr *
* Return Value: void *
* Parameters: CGaddr: display data address *
* Description: This routine sets the display data address *
* of the Hitachi HD44780 LCD controller. The *
* user must check to see if the LCD controller*
* is busy before calling this routine. *
********************************************************************/
void SetDDRamAddr(unsigned char DDaddr)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = DDaddr | 0b10000000; // Write cmd and address to
port
RW_PIN = 0; // Set the control bits
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make port output
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((DDaddr | 0b10000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make port output
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((DDaddr | 0b10000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control bits
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((DDaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (DDaddr&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make port input
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make port input
#endif
#endif
return;
}
/********************************************************************
* Function Name: WriteCmdXLCD *
* Return Value: void *
* Parameters: cmd: command to send to LCD *
* Description: This routine writes a command to the Hitachi*
* HD44780 LCD controller. The user must check *
* to see if the LCD controller is busy before *
* calling this routine. *
********************************************************************/
void WriteCmdXLCD(unsigned char cmd)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT &= 0; // Data port output
DATA_PORT &= 0;
DATA_PORT |= cmd; // Write command to data port
RW_PIN = 0; // Set the control signals
RS_PIN = 0; // for sending a command
DelayFor18TCY();
E_PIN = 1; // Clock the command in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT |= 0xff; // Data port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= cmd&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= (cmd>>4)&0x0f;
#endif
RW_PIN = 0; // Set control signals for command
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock command in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= (cmd<<4)&0xf0;
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= cmd&0x0f;
#endif
DelayFor18TCY();
E_PIN = 1; // Clock command in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Make data nibble input
TRIS_DATA_PORT |= 0xf0;
#else
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}
/********************************************************************
* Function Name: WriteDataXLCD *
* Return Value: void *
* Parameters: data: data byte to be written to LCD *
* Description: This routine writes a data byte 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 WriteDataXLCD(char data)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = data; // Write data to port
RS_PIN = 1; // Set control bits
RW_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data into LCD
DelayFor18TCY();
E_PIN = 0;
RS_PIN = 0; // Reset control bits
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= data&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= ((data>>4)&0x0f);
#endif
RS_PIN = 1; // Set control bits
RW_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock nibble into LCD
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= ((data<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= (data&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock nibble into LCD
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}
void DelayFor18TCY( void )
{
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
}
void DelayPORXLCD (void)
{
Delay1KTCYx(75); // Delay of 15ms
// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (15ms * 20MHz) / 4
// Cycles = 75,000
return;
}
void DelayXLCD (void)
{
Delay1KTCYx(25); // Delay of 5ms
// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (5ms * 20MHz) / 4
// Cycles = 25,000
return;
}
void delayinit(void)
{
//Delay of 4s
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
}
void LCD_init(void)
{
OpenXLCD( EIGHT_BIT&LINES_5X7 );// Configure External LCD
while(BusyXLCD()); // Wait if LCD is busy
putsXLCD(LCD_name); // write to LCD
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x40); // Set Display data RAM address to 0x40
putsXLCD(LCD_Ver); // write to LCD
delayinit();
}
void LCD_display(char *i)
{
// Set DD Ram address to 0
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x40); // Set Display data RAM address
// write to LCD
while(BusyXLCD()); // Wait if LCD is busy
putsXLCD(i);
}
/**************************************************************************/
#pragma code low_vector=0x18
void low_interrupt (void)
{
_asm GOTO timer_isr _endasm
}
#pragma code
#pragma interruptlow timer_isr
void timer_isr (void)
{
unsigned int i,m,n;
unsigned char send;
char Cent[]="Centigrade";
char Fahr[]="Fahrenheit";
char Cont[]="Contrast ";
char Current[]="Current Temperature";
TMR0H=0X80;
TMR0L=0X00;
i++;
LM75_temperature(); //Read Temperature
if(key_flag==0)
{
m=Funckey();
switch(m)
{
case(0): //Display "Centigrade"
{
LCD_display(Cent);
putsXLCD(cent_buf);
PWM_data=m;
}break;
case(1): //Display "Fahrenheit"
{
LCD_display(Fahr);
putsXLCD(fahr_buf);
PWM_data=m;
}break;
case(2): //Display Contrast information
{
LCD_display(Cont);
PWM_data=m;
}break;
}
if(change_key==0)key_flag=1;
}
if(key_flag==1)
{
n=changekey(); //Get state of change function key
if((PWM_data==2)|(PWM_data==3))
{
PWM(n);
switch(n)
{
case(0):
{
PWMbuf[0]='0';
PWMbuf[1]='%';
PWMbuf[2]=' ';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(1):
{
PWMbuf[0]='1';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(2):
{
PWMbuf[0]='2';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(3):
{
PWMbuf[0]='3';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(4):
{
PWMbuf[0]='4';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(5):
{
PWMbuf[0]='5';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(6):
{
PWMbuf[0]='6';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data ram address
putsXLCD(PWMbuf);
}break;
case(7):
{
PWMbuf[0]='7';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(8):
{
PWMbuf[0]='8';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
PWM(8);
}break;
case(9):
{
PWMbuf[0]='9';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(10):
{
PWMbuf[0]='1';
PWMbuf[1]='0';
PWMbuf[2]='0';
PWMbuf[3]='%';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
}
}
if(Func_key==0)key_flag=0;
}
if(i%8==0)
{
send++;
if((send>0)&(send<24))
{
sendUSART(Current);
}
if(send==24)
{
pointer=0;
TXREG=13;
TXREG=10;
}
if((send>28)&(send<36))
{
sendUSART(cent_buf);
}
if(send==36)
{
pointer=0;
}
if((send>36)&(send<52))
{
sendUSART(Cent);
}
if(send==52)
{
pointer=0;
TXREG=13;
TXREG=10;
}
if((send>56)&(send<64))
{
sendUSART(Fahr);
}
if(send==64)
{
pointer=0;
}
if((send>64)&(send<80))
{
sendUSART(Fahr);
}
if(send==80)
{
pointer=0;
TXREG=13;
TXREG=10;
}
}
INTCONbits.TMR0IF = 0;
}
void sendUSART(char *sendbuf)
{
if(*(sendbuf+pointer)!=0)
{
if(BusyUSART()==0)
{
TXREG=*(sendbuf+pointer);
pointer++;
return;
}
else
{
return;
}
}
}
/**************************************************************************/
void main (void)
{
init(); // Initialize Control Microchip
LM75_init(); // Temperature Sensor Initializtion
LM75_temperature(); // Read Temperature
LCD_init(); // Open LCD and display "Sure Electronics" and "Ver 2.1"
OpenTimer0 (TIMER_INT_ON & T0_SOURCE_INT & T0_16BIT);
INTCONbits.GIE = 1;
while(1){};
}
* PICDEM 2 PLUS
* SAMPLE CODE
* DB-DP113_Ver2.0 © 2004 -2008 Sure Electronics Inc.
*******************************************************************************/
#include <p18f4520.h>
#include <sw_i2c.h>
#include <usart.h>
#include <delays.h>
#include <timers.h>
#pragma config OSC = HS
#pragma config PWRT = OFF
#pragma config BOREN = OFF
#pragma config WDT = OFF
#pragma config MCLRE = ON
#pragma config PBADEN = OFF
#pragma config LVP = OFF
#define Func_key PORTBbits.RB0 // Function key
#define change_key PORTAbits.RA4 // Change key
unsigned char reset_key_pressed,last_reset_key_pressed;
unsigned char Func_key_pressed,last_Func_key_pressed;
unsigned char change_key_pressed,last_change_key_pressed;
unsigned char cnt_fuckey;
unsigned char cnt_chgkey;
unsigned char PWM_data;
char PWMbuf[6];
unsigned char key_flag=0;
char pointer=0;
unsigned char i2c_var;
unsigned int cvalue,fvalue; // Memory Centigrade and Fahrenheit Value
char cent_buf[6],fahr_buf[6]; // Centigrade and Fahrenheit Value Array
char LCD_name[]="Sure Electronics";
char LCD_Ver[]="Ver 2.1";
void timer_isr (void); // Timer0 Interrupt Service Routine
void init(void); // Initialize Control Microchip
char Funckey(void); // Get State of Function Switch
char changekey(void); // Get State of Change Function Switch
void PWM(unsigned char i); // PWM Mode
void LCD_init(void); // Set LCD Initial Display
void LCD_display(char *i); // LCD display
void delayinit(void);
void sendUSART(char *sendbuf);
/**************************************************************************/
void init(void)
{
CMCON=0b00000111; // Close Comparator
TRISA=0b00010000;
TRISB=0b00000001;
TRISC=0b11000000;
TRISD=0b00000000;
TRISE=0b00001000;
ADCON1=0b00001111; // Digital Channel Allocation
SPBRG=38; // Baud Rate 4800bps
BAUDCONbits.BRG16=0; // Choose 8-bit Baud Rate Generator
TXSTAbits.BRGH=0; // High Baud Rate
TXSTAbits.SYNC=0; // Asynchronous Mode
RCSTAbits.SPEN=1; // Enable Serial
TXSTAbits.TX9=0; // 8-bit Transmission
TXSTAbits.TXEN=1; // Enable Transmission
CCP1CON=0b00001100; // Set PWM Mode
CCP2CON=0b00001100;
T2CONbits.TMR2ON = 0;
T2CONbits.T2OUTPS3 = 1;
T2CONbits.T2OUTPS2 = 1;
T2CONbits.T2OUTPS1 = 1;
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2CKPS1 = 1;
T2CONbits.T2CKPS1 = 1;
PR2 = 255;
TRISCbits.TRISC2=0;
TRISCbits.TRISC1=0;
T2CONbits.TMR2ON = 1;
CCPR1L = 100;
CCPR2L = 0;
}
/**************************************************************************/
void PWM(unsigned char i)
{
CCP1CON=0b00001100;
T2CONbits.TMR2ON = 0;
T2CONbits.T2OUTPS3 = 1;
T2CONbits.T2OUTPS2 = 1;
T2CONbits.T2OUTPS1 = 1;
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2CKPS1 = 1;
T2CONbits.T2CKPS1 = 1;
PR2 = 255;
TRISCbits.TRISC2=0;
T2CONbits.TMR2ON = 1;
CCPR1L = 25*i;
}
/**************************************************************************/
char Funckey(void)
{
unsigned char temp;
Func_key_pressed=Func_key;
if((Func_key_pressed==0)&(last_Func_key_pressed==1))
{
Delay100TCYx(1); //Delay to avoid buffeting
if(Func_key_pressed==0)cnt_fuckey++;
}
last_Func_key_pressed=Func_key_pressed;
temp=cnt_fuckey%3;
return temp;
}
char changekey(void)
{
unsigned char temp;
change_key_pressed=change_key;
if((change_key_pressed==0)&(last_change_key_pressed==1))
{
Delay100TCYx(1); //Delay to avoid buffeting
if(change_key_pressed==0)cnt_chgkey++;
}
last_change_key_pressed=change_key_pressed;
temp=cnt_chgkey%11;
return temp;
}
/**************************************************************************/
// Write data
void byte_write(unsigned char adr,unsigned char data)
{
SWStartI2C();
i2c_var = SWPutcI2C(0xA0); // Control byte
SWAckI2C();
i2c_var = SWPutcI2C(adr); // Word address
SWAckI2C();
i2c_var = SWPutcI2C(data); // Data
SWAckI2C();
SWStopI2C();
}
// Read data
void byte_read(unsigned char adr)
{
SWStartI2C();
i2c_var = SWPutcI2C( 0xA0 ); // Control byte
SWAckI2C();
i2c_var = SWPutcI2C(adr); // Word address
SWAckI2C();
SWRestartI2C();
i2c_var = SWPutcI2C( 0xA1 ); // Control byte
SWAckI2C();
i2c_var = SWGetcI2C();//data
SWStopI2C();
}
// Write string
void page_write(unsigned char adr,unsigned char wdata[])
{
SWStartI2C();
i2c_var = SWPutcI2C(0xA0); // Control byte
SWAckI2C();
i2c_var = SWPutcI2C(adr); // Word address
SWAckI2C();
i2c_var = SWPutsI2C(wdata); // Data
SWStopI2C();
}
// Read string
void sequential_read(unsigned char adr,unsigned char rdata[],unsigned char len)
{
SWStartI2C();
i2c_var = SWPutcI2C( 0xA0 ); // Control byte
SWAckI2C();
i2c_var = SWPutcI2C(adr); // Word address
SWAckI2C();
SWRestartI2C();
i2c_var = SWPutcI2C( 0xA1 ); // Control byte
SWAckI2C();
i2c_var = SWGetsI2C(rdata,len); // Data
SWStopI2C();
}
// Inquiries confirmed
void ack_poll( void )
{
SWStartI2C();
i2c_var = SWPutcI2C( 0xA0 ); // Control byte
while( SWAckI2C() )
{
SWRestartI2C();
i2c_var = SWPutcI2C(0xA0); // Data
}
SWStopI2C();
}
/**************************************************************************/
void LM75_init(void) // Temperature Sensor Initializtion
{
SWStartI2C();
i2c_var = SWPutcI2C(0x90); // Control byte
SWAckI2C();
i2c_var = SWPutcI2C(0x01); // Configure register
SWAckI2C();
i2c_var = SWPutcI2C(0x18); // Configure byte
SWAckI2C();
SWStopI2C();
}
void LM75_temperature(void)
{
unsigned char tptr[2];
unsigned int temp_H,temp_L;
SWStartI2C();
i2c_var = SWPutcI2C(0x90); // Control byte
SWAckI2C();
i2c_var = SWPutcI2C(0x00); // Data Address
SWAckI2C();
SWRestartI2C();
i2c_var = SWPutcI2C(0x91); // Control byte
SWAckI2C();
i2c_var = SWGetsI2C(tptr, 2); // Read Temperature
SWStopI2C();
temp_H=tptr[0]; // High bits
temp_L=tptr[1]; // Low bits
// Compute Centigrade
cvalue=(temp_H<<8)|temp_L;
cent_buf[0]=' ';
if(cvalue&0x80==1)
{
cvalue=~cvalue+1; // Calculate Base Complement
cent_buf[0]='-';
}
cvalue=cvalue>>5;
cvalue=cvalue * 1.25;
cent_buf[1]=cvalue/100+48;
cent_buf[2]=(cvalue/10)%10+48;
cent_buf[3]='.';
cent_buf[4]=cvalue%10+48;
cent_buf[5]='\0';
// Compute Fahrenheit
fvalue=((cvalue*9)/5)+32;
fahr_buf[0]=' ';
if(fvalue&0x80==1)
{
fvalue=~fvalue+1; // Calculate Base Complement
fahr_buf[0]='-';
}
fahr_buf[1]=fvalue/100+48;
fahr_buf[2]=(fvalue/10)%10+48;
fahr_buf[3]='.';
fahr_buf[4]=fvalue%10+48;
fahr_buf[5]='\0';
}
/**************************************************************************/
/* 8-bit or 4-bit interface type
* For 8-bit operation uncomment the #define BIT8
*/
#define BIT8
/* When in 4-bit interface define if the data is in the upper or lower nibble.
For lower nibble, comment the #define UPPER
*/
/* #define UPPER */
/* DATA_PORT defines the port which the LCD data lines are connected to */
#define DATA_PORT PORTD
#define TRIS_DATA_PORT TRISD
/* CTRL_PORT defines the port where the control lines are connected.
* These are just samples, change to match your application.
*/
#define RW_PIN PORTAbits.RA2 /* PORT for RW */
#define TRIS_RW DDRAbits.RA2 /* TRIS for RW */
#define RS_PIN PORTAbits.RA3 /* PORT for RS */
#define TRIS_RS DDRAbits.RA3 /* TRIS for RS */
#define E_PIN PORTAbits.RA1 /* PORT for E */
#define TRIS_E DDRAbits.RA1 /* TRIS for E */
/* Display ON/OFF Control defines */
#define DON 0b00001111 /* Display on */
#define DOFF 0b00001011 /* Display off */
#define CURSOR_ON 0b00001111 /* Cursor on */
#define CURSOR_OFF 0b00001101 /* Cursor off */
#define BLINK_ON 0b00001111 /* Cursor Blink */
#define BLINK_OFF 0b00001110 /* Cursor No Blink */
/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT 0b00010011 /* Cursor shifts to the left */
#define SHIFT_CUR_RIGHT 0b00010111 /* Cursor shifts to the right */
#define SHIFT_DISP_LEFT 0b00011011 /* Display shifts to the left */
#define SHIFT_DISP_RIGHT 0b00011111 /* Display shifts to the right */
/* Function Set defines */
#define FOUR_BIT 0b00101111 /* 4-bit Interface */
#define EIGHT_BIT 0b00111111 /* 8-bit Interface */
#define LINE_5X7 0b00110011 /* 5x7 characters, single line */
#define LINE_5X10 0b00110111 /* 5x10 characters */
#define LINES_5X7 0b00111011 /* 5x7 characters, multiple line */
#define PARAM_SCLASS auto
#define MEM_MODEL far /* Change this to near for small memory model */
/* OpenXLCD
* Configures I/O pins for external LCD
*/
void OpenXLCD(PARAM_SCLASS unsigned char);
/* SetCGRamAddr
* Sets the character generator address
*/
void SetCGRamAddr(PARAM_SCLASS unsigned char);
/* SetDDRamAddr
* Sets the display data address
*/
void SetDDRamAddr(PARAM_SCLASS unsigned char);
/* BusyXLCD
* Returns the busy status of the LCD
*/
unsigned char BusyXLCD(void);
/* ReadAddrXLCD
* Reads the current address
*/
unsigned char ReadAddrXLCD(void);
/* ReadDataXLCD
* Reads a byte of data
*/
char ReadDataXLCD(void);
/* WriteCmdXLCD
* Writes a command to the LCD
*/
void WriteCmdXLCD(PARAM_SCLASS unsigned char);
/* WriteDataXLCD
* Writes a data byte to the LCD
*/
void WriteDataXLCD(PARAM_SCLASS char);
/* putcXLCD
* A putc is a write
*/
#define putcXLCD WriteDataXLCD
/* putsXLCD
* Writes a string of characters to the LCD
*/
void putsXLCD(PARAM_SCLASS char *);
/* putrsXLCD
* Writes a string of characters in ROM to the LCD
*/
void putrsXLCD(PARAM_SCLASS const MEM_MODEL rom char *);
/* User defines these routines according to the oscillator frequency */
extern void DelayFor18TCY(void);
extern void DelayPORXLCD(void);
extern void DelayXLCD(void);
/********************************************************************
* 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: 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-bit or *
* 8-bit mode and clear screen. 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 *
********************************************************************/
void OpenXLCD(unsigned char lcdtype)
{
// 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
#ifdef BIT8 // 8-bit mode interface
TRIS_DATA_PORT &= 0; // Data port output
DATA_PORT &= 0;
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 |= 0b00100000; // Function set cmd(4-bit interface)
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= 0b00000010; // 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();
// Setup interface to LCD
#ifdef BIT8 // 8-bit interface
DATA_PORT &= 0;
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 |= 0b00100000;
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00000010;
#endif
#endif
E_PIN = 1; // Clock the cmd in
DelayFor18TCY();
E_PIN = 0;
// Delay for at least 100us
DelayXLCD();
// Setup interface to LCD
#ifdef BIT8 // 8-bit interface
DATA_PORT &= 0;
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 |= 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
// Set data interface width, # lines, font
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(lcdtype); // Function set cmd
// Turn the display on then off
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(DOFF); // Display OFF/Blink OFF
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(DON); // Display ON/Blink ON
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(BLINK_OFF&CURSOR_OFF); // Display ON/Blink OFF
// 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
// Set DD Ram address to 0
while(BusyXLCD()); // Wait if LCD busy
SetDDRamAddr(0); // Set Display data ram address to 0
return;
}
/********************************************************************
* 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
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data out of the LCD controller
DelayFor18TCY();
data = DATA_PORT; // Save the data in the register
E_PIN = 0;
RW_PIN = 0; // Reset the control bits
#else // 4-bit interface
RW_PIN = 1; // Set control bits for the read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data out of the LCD controller
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the nibble into the upper nibble
of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // Read the nibble into the upper nibble
of data
#endif
E_PIN = 0; // Reset the clock
DelayFor18TCY();
E_PIN = 1; // Clock out the lower nibble
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the nibble into the lower nibble
of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the nibble into the lower nibble
of data
#endif
E_PIN = 0;
RW_PIN = 0; // Reset the control lines
#endif
return (data&0x7f); // Return the address, Mask off the busy bit
}
/********************************************************************
* Function Name: ReadDataXLCD *
* Return Value: char: data byte from LCD controller *
* Parameters: void *
* Description: This routine reads a data byte from the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The data *
* is read from the character generator RAM or *
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
********************************************************************/
char ReadDataXLCD(void)
{
char data;
#ifdef BIT8 // 8-bit interface
RS_PIN = 1; // Set the control bits
RW_PIN = 1;
DelayFor18TCY();
E_PIN = 1; // Clock the data out of the LCD
DelayFor18TCY();
data = DATA_PORT; // Read the data
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#else // 4-bit interface
RW_PIN = 1;
RS_PIN = 1;
DelayFor18TCY();
E_PIN = 1; // Clock the data out of the LCD
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the upper nibble of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // read the upper nibble of data
#endif
E_PIN = 0; // Reset the clock line
DelayFor18TCY();
E_PIN = 1; // Clock the next nibble out of the LCD
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the lower nibble of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the lower nibble of data
#endif
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#endif
return(data); // Return the data byte
}
/********************************************************************
* Function Name: SetCGRamAddr *
* Return Value: void *
* Parameters: CGaddr: character generator ram address *
* Description: This routine sets the character generator *
* address of the Hitachi HD44780 LCD *
* controller. The user must check to see if *
* the LCD controller is busy before calling *
* this routine. *
********************************************************************/
void SetCGRamAddr(unsigned char CGaddr)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make data port ouput
DATA_PORT = CGaddr | 0b01000000; // Write cmd and address to
port
RW_PIN = 0; // Set control signals
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Make data port inputs
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make nibble input
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((CGaddr | 0b01000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make nibble input
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((CGaddr |0b01000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control signals
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((CGaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (CGaddr&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make inputs
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make inputs
#endif
#endif
return;
}
/********************************************************************
* Function Name: SetDDRamAddr *
* Return Value: void *
* Parameters: CGaddr: display data address *
* Description: This routine sets the display data address *
* of the Hitachi HD44780 LCD controller. The *
* user must check to see if the LCD controller*
* is busy before calling this routine. *
********************************************************************/
void SetDDRamAddr(unsigned char DDaddr)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = DDaddr | 0b10000000; // Write cmd and address to
port
RW_PIN = 0; // Set the control bits
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make port output
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((DDaddr | 0b10000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make port output
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((DDaddr | 0b10000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control bits
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((DDaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (DDaddr&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make port input
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make port input
#endif
#endif
return;
}
/********************************************************************
* Function Name: WriteCmdXLCD *
* Return Value: void *
* Parameters: cmd: command to send to LCD *
* Description: This routine writes a command to the Hitachi*
* HD44780 LCD controller. The user must check *
* to see if the LCD controller is busy before *
* calling this routine. *
********************************************************************/
void WriteCmdXLCD(unsigned char cmd)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT &= 0; // Data port output
DATA_PORT &= 0;
DATA_PORT |= cmd; // Write command to data port
RW_PIN = 0; // Set the control signals
RS_PIN = 0; // for sending a command
DelayFor18TCY();
E_PIN = 1; // Clock the command in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT |= 0xff; // Data port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= cmd&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= (cmd>>4)&0x0f;
#endif
RW_PIN = 0; // Set control signals for command
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock command in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= (cmd<<4)&0xf0;
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= cmd&0x0f;
#endif
DelayFor18TCY();
E_PIN = 1; // Clock command in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Make data nibble input
TRIS_DATA_PORT |= 0xf0;
#else
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}
/********************************************************************
* Function Name: WriteDataXLCD *
* Return Value: void *
* Parameters: data: data byte to be written to LCD *
* Description: This routine writes a data byte 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 WriteDataXLCD(char data)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = data; // Write data to port
RS_PIN = 1; // Set control bits
RW_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data into LCD
DelayFor18TCY();
E_PIN = 0;
RS_PIN = 0; // Reset control bits
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= data&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= ((data>>4)&0x0f);
#endif
RS_PIN = 1; // Set control bits
RW_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock nibble into LCD
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= ((data<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= (data&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock nibble into LCD
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}
void DelayFor18TCY( void )
{
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
}
void DelayPORXLCD (void)
{
Delay1KTCYx(75); // Delay of 15ms
// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (15ms * 20MHz) / 4
// Cycles = 75,000
return;
}
void DelayXLCD (void)
{
Delay1KTCYx(25); // Delay of 5ms
// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (5ms * 20MHz) / 4
// Cycles = 25,000
return;
}
void delayinit(void)
{
//Delay of 4s
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
Delay10KTCYx(200);
}
void LCD_init(void)
{
OpenXLCD( EIGHT_BIT&LINES_5X7 );// Configure External LCD
while(BusyXLCD()); // Wait if LCD is busy
putsXLCD(LCD_name); // write to LCD
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x40); // Set Display data RAM address to 0x40
putsXLCD(LCD_Ver); // write to LCD
delayinit();
}
void LCD_display(char *i)
{
// Set DD Ram address to 0
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x40); // Set Display data RAM address
// write to LCD
while(BusyXLCD()); // Wait if LCD is busy
putsXLCD(i);
}
/**************************************************************************/
#pragma code low_vector=0x18
void low_interrupt (void)
{
_asm GOTO timer_isr _endasm
}
#pragma code
#pragma interruptlow timer_isr
void timer_isr (void)
{
unsigned int i,m,n;
unsigned char send;
char Cent[]="Centigrade";
char Fahr[]="Fahrenheit";
char Cont[]="Contrast ";
char Current[]="Current Temperature";
TMR0H=0X80;
TMR0L=0X00;
i++;
LM75_temperature(); //Read Temperature
if(key_flag==0)
{
m=Funckey();
switch(m)
{
case(0): //Display "Centigrade"
{
LCD_display(Cent);
putsXLCD(cent_buf);
PWM_data=m;
}break;
case(1): //Display "Fahrenheit"
{
LCD_display(Fahr);
putsXLCD(fahr_buf);
PWM_data=m;
}break;
case(2): //Display Contrast information
{
LCD_display(Cont);
PWM_data=m;
}break;
}
if(change_key==0)key_flag=1;
}
if(key_flag==1)
{
n=changekey(); //Get state of change function key
if((PWM_data==2)|(PWM_data==3))
{
PWM(n);
switch(n)
{
case(0):
{
PWMbuf[0]='0';
PWMbuf[1]='%';
PWMbuf[2]=' ';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(1):
{
PWMbuf[0]='1';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(2):
{
PWMbuf[0]='2';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(3):
{
PWMbuf[0]='3';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(4):
{
PWMbuf[0]='4';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(5):
{
PWMbuf[0]='5';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(6):
{
PWMbuf[0]='6';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data ram address
putsXLCD(PWMbuf);
}break;
case(7):
{
PWMbuf[0]='7';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(8):
{
PWMbuf[0]='8';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
PWM(8);
}break;
case(9):
{
PWMbuf[0]='9';
PWMbuf[1]='0';
PWMbuf[2]='%';
PWMbuf[3]=' ';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
case(10):
{
PWMbuf[0]='1';
PWMbuf[1]='0';
PWMbuf[2]='0';
PWMbuf[3]='%';
PWMbuf[4]=' ';
PWMbuf[5]=' ';
while(BusyXLCD()); // Wait if LCD is busy
SetDDRamAddr(0x4b); // Set Display data RAM address
putsXLCD(PWMbuf);
}break;
}
}
if(Func_key==0)key_flag=0;
}
if(i%8==0)
{
send++;
if((send>0)&(send<24))
{
sendUSART(Current);
}
if(send==24)
{
pointer=0;
TXREG=13;
TXREG=10;
}
if((send>28)&(send<36))
{
sendUSART(cent_buf);
}
if(send==36)
{
pointer=0;
}
if((send>36)&(send<52))
{
sendUSART(Cent);
}
if(send==52)
{
pointer=0;
TXREG=13;
TXREG=10;
}
if((send>56)&(send<64))
{
sendUSART(Fahr);
}
if(send==64)
{
pointer=0;
}
if((send>64)&(send<80))
{
sendUSART(Fahr);
}
if(send==80)
{
pointer=0;
TXREG=13;
TXREG=10;
}
}
INTCONbits.TMR0IF = 0;
}
void sendUSART(char *sendbuf)
{
if(*(sendbuf+pointer)!=0)
{
if(BusyUSART()==0)
{
TXREG=*(sendbuf+pointer);
pointer++;
return;
}
else
{
return;
}
}
}
/**************************************************************************/
void main (void)
{
init(); // Initialize Control Microchip
LM75_init(); // Temperature Sensor Initializtion
LM75_temperature(); // Read Temperature
LCD_init(); // Open LCD and display "Sure Electronics" and "Ver 2.1"
OpenTimer0 (TIMER_INT_ON & T0_SOURCE_INT & T0_16BIT);
INTCONbits.GIE = 1;
while(1){};
}


