#include <16F84.h>
#use delay(clock=4000000)
#fuses NOWDT,XT, PUT, NOPROTECT
#use rs232(baud=9600,parity=N,xmit=PIN_A1,rcv=PIN_A0,bits=9)
#include <LCD_inline.C>
#define bufLen 0x17 // (command, 20 chars, CR, 00) = 23 = 0x17
char buffer[buflen];
int bufidx;
int eData;
int eAddr;
int eLine;
int eCol;
char reset[7] = "150163";
//-- Routine prototypes --//
void atoi_b16(char);
void displayname();
void main()
{
setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
lcd_init();
// we re-use the buffer here to check if we have a valid System Name,
// If not, simply use the default message.
// A blank EEprom will have 0xFF as the first byte (and all others probably)
displayname();
while (1==1)
{
bufidx = 0;
do {
buffer[ bufidx++ ] = getc();
} while ( buffer[bufidx - 1 ] != 0x0D && (bufidx <= buflen ) );
if (bufidx == buflen) // add the terminating 0x00
buffer[buflen-1]=0;
else
buffer[bufidx-1] = 0;
switch(toupper(buffer[0]))
{
case 'C' :
break;
case 'M' : // Move MLLCC - Move Line ColumnColumn (dec)
eLine = make8(atoi_b16(&buffer[3]),0); // line only low bit
eCol = make8(atoi_b16(&buffer[1]),0);
lcd_gotoxy(eLine,eCol);
break;
case 'W' : // Write EEprom W0133 <-- addr 01 = 33
eAddr = make8(atoi_b16(&buffer[1]),0);
eData = make8(atoi_b16(&buffer[3]),0);
write_eeprom(eAddr,eData);
break;
case 'R' : // Read EEprom R01 <-- Read addr 01
eAddr = make8(atoi_b16(&buffer[1]),0);
eData = read_eeprom(eAddr);
printf("Read Data:\n\r");
printf("Address : %X \n\r",eAddr);
printf("Data : %X \n\r",eData);
printf(LCD_PUTC, eData);
break;
case 'D' : printf(LCD_PUTC, &buffer[1]);
break;
case 'I' :
eAddr = 0;
do
{
eData = buffer[eAddr + 1];
write_eeprom(eAddr,eData);
eAddr++;
} while (eData != 0x00);
write_eeprom(eAddr-1,0x00);
displayname();
break;
case 'X' : printf(LCD_PUTC,"\f");
break;
case 'Z' :
if ( buffer[1] == 0x31 && buffer[2] == 0x35 && buffer[3] == 0x30 && buffer[4] == 0x31)
if ( buffer[5]=0x36 && buffer[6] == 0x33)
{
write_eeprom(0,0xFF); // just write 0xff to byte 0 of the eeprom
displayname(); // re-write header
};
break;
}
}
}
//-- Clear LCD display and write System name to LCD --//
void displayname()
{
printf(LCD_PUTC,"\f"); // Clear LCD
eAddr=0;
eData=read_eeprom(eAddr);
if (eData == 0xFF )
printf(LCD_PUTC,"Initialised.\n");
else
{
for(eAddr=0; eAddr < 0x0F; eAddr++)
buffer[eAddr] = read_eeprom(eAddr);
eAddr++;
printf(LCD_PUTC,&buffer[0]);
}
}
unsigned int atoi_b16(char *s) { // Convert two hex characters to a int8
unsigned int result = 0;
int i;
for (i=0; i<2; i++,s++) {
if (*s >= 'A')
result = 16*result + (*s) - 'A' + 10;
else
result = 16*result + (*s) - '0';
}
return(result);
}
LCD source code
///////////////////////////////////////////////////////////////////////////
//// LCDD.C ////
//// Driver for common LCD modules ////
//// ////
//// lcd_init() Must be called before any other function. ////
//// ////
//// lcd_putc(c) Will display c on the next position of the LCD. ////
//// The following have special meaning: ////
//// \f Clear display ////
//// \n Go to start of second line ////
//// \b Move back one position ////
//// ////
//// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1) ////
//// ////
//// lcd_getc(x,y) Returns character at position x,y on LCD ////
//// ////
///////////////////////////////////////////////////////////////////////////
// As defined in the following structure the pin connection is as follows:
// D0 enable
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
//
// LCD pins D0-D3 are not used and PIC D3 is not used.
// Un-comment the following define to use port B
#define use_portb_lcd TRUE
struct lcd_pin_map { // This structure is overlayed
BOOLEAN rs; // The bits are allocated from
BOOLEAN rw; // on to an I/O port to gain
BOOLEAN enable; // access to the LCD pins.
BOOLEAN unused; // low order up. RS will
int data : 4; // be pin B0.
} lcd;
#byte lcd = 0xF81 // This puts the entire structure
#byte lcd = 6 // on to port B (at address 6)
#define set_tris_lcd(x) set_tris_b(x)
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
BYTE lcd_read_byte() {
BYTE low,high;
set_tris_lcd(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_lcd(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( BYTE address, BYTE n ) {
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
set_tris_lcd(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING[i]);
}
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
if(y!=1)
address=lcd_line_two;
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
char lcd_getc( BYTE x, BYTE y) {
char value;
lcd_gotoxy(x,y);
while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}