include <pic.h> // pic specific identifiers
#define _XTAL_FREQ 20000000 // Xtal speed
__CONFIG(0x3F71); // Config bits
#define LCD_PORT PORTB // constants
#define LCD_TRIS TRISB //
#define LCD_RS RB4
#define LCD_RW RB6
#define LCD_E RB7
// Required prototypes.. each function needs to be declared
// if called BEFORE definition.
void LCD_init(void), LCD_cmd(unsigned char ch);
void LCD_goto(char line, char column), LCD_clr(void);
void LCD_cur(unsigned char ch), pulse_E(void), LCD_hex(int value);
void LCD_char(unsigned char ch), LCD_charD(unsigned char ch);
unsigned char HSerin(void);
void HSerout(unsigned char ch), HSerinit(void);
void main(void) // program entry
{
int index = 0;
unsigned char ch;
ADCON1 = 0x6; // Analogue off
LCD_TRIS = 0b00000000; // Led port as outputs
__delay_ms(150); // let LCD stabilise
LCD_init(); // Initalise screen
LCD_goto(1,0); // line 1.
HSerinit();
while(1) // endless Loop
{
ch = HSerin(); // wait for a character
if(index == 16) // new line
LCD_goto(2,0);
if(index == 32) // goto line 1
{
LCD_clr();
index = 0; // re-set
}
LCD_char(ch); // display the received byte
HSerout(ch); // Echo back
index++; // move on
}
}
void HSerinit()
{
TRISC = 0xC0; // should ideally be set
SPBRG = 129; // 20Mhz xtal 9600 BAUD
TXSTA = 0x24; // TXEN and BRGH
RCSTA = 0x90; // SPEN and CREN
}
void HSerout(unsigned char ch)
{
while(!TXIF); // Wait for module to finish
TXREG = ch; // ready to send
}
unsigned char HSerin()
{
while(!RCIF); // Wait for a character
return RCREG; // return character
}
void LCD_init()
{
LCD_cmd(0x20); // 4 bit
LCD_cmd(0x28); // display shift
LCD_cmd(0x6); // character mode
LCD_cmd(0xc); // display on / off and cursor
LCD_clr(); // clear display
}
void LCD_hex(int value)
{
char data; // dispay hex values.
data = value >> 4 & 0xf; // send upper nibble
data = HEX_Table[data]; // hex lookup
LCD_char(data);
data = value & 0xf; // send lower nibble
data = HEX_Table[data]; // hex lookup
LCD_char(data);
}
void LCD_goto(char line, char column) // combines line and lineW
{
unsigned char data = 0x80; // default to 1
if(line == 2)data = 0xc0; // change to 2
data += column; // add in column
LCD_cmd(data);
}
void LCD_clr()
{
LCD_cmd(1); // Clr screen
}
void LCD_cur(char on)
{
unsigned char cur = 0xc; // cursor off
if(on) cur = 0xd; // cursor on
LCD_cmd(cur);
}
void LCD_cmd(unsigned char ch)
{
LCD_PORT = ch >> 4 & 0xf; // write high nibble
LCD_RS = 0;
pulse_E();
LCD_PORT = ch & 0xf; // write low nibble
LCD_RS = 0;
pulse_E();
__delay_ms(5);
}
void LCD_charD(unsigned char ch)
{
ch+=0x30;
LCD_char(ch); // convert to ascii
}
void LCD_char(unsigned char ch)
{
LCD_PORT = ch >> 4 & 0xf; // High nibble
LCD_RS = 1;
pulse_E();
LCD_PORT = ch & 0xf; // low nibble
LCD_RS = 1;
pulse_E();
__delay_ms(5);
}
void pulse_E()
{
LCD_E = 1;
__delay_us(1);
LCD_E = 0;
}