//Lcm.c
//
//Body: HT48C30-1
//Mask option
//BZ/BZB : All Disable
//the others use the default value
#include <ht48c30-1.h>
#pragma vector isr_4 @ 0x4
#pragma vector isr_8 @ 0x8
#pragma vector isr_c @ 0xc
//ISR for safequard
void isr_4(){} // external ISR
void isr_8(){} // timer/event 0
void isr_c(){} // timer/event 1
//initialize registers for safeguard
void safeguard_init(){
_intc = 0;
_tmrc = 0;
_tmr = 0;
_pac = 0xff; //input mode
_pbc = 0xff;
_pcc = 0xff;
}
//#define FOUR_BIT
//#define ONE_LINE
//for DV-16100NRB
// port B : LCM data port
// port C : LCM control port
#define LCM_CLS 0x1
#define CURSOR_HOME 0x2
#define CURSOR_SR 0x14
#define CURSOR_SL 0x10
#define INCDD_CG_SHF_C 0x6
#define TURN_ON_DISP 0xf
#define LCD_ON_CSR_OFF 0xc
#define LCM_DATA _pb
#define LCM_DATA_CTRL _pbc
#define LCM_CTRL _pc
#define LCM_CTRL_CTRL _pcc
#define LCM_CTRL_E _pc0
#define LCM_CTRL_RW _pc1
#define LCM_CTRL_RS _pc2
#define WRITE(a) { \
LCM_DATA = (a); \
LCM_CTRL_E = 1; \
LCM_CTRL_E = 0;}
const unsigned char msg[16] = "HOLTEK 8 bit MCU";
void mydelay(unsigned char ct);
void LCM_initialize();
void send_cmd(unsigned char);
void write_char(unsigned char);
void busy_check(void);
void lcm_delay(void);
void main(){
unsigned int i;
safeguard_init();
LCM_initialize();
while(1){
send_cmd(LCM_CLS);
mydelay(2);
send_cmd(CURSOR_HOME);
for(i = 0; i<sizeof(msg); i++){
if (i == 8)
send_cmd(0xc0); //move cursor to 2nd line
write_char(msg[i]); //(1st line:00h~, 2nd line:40h~)
}
send_cmd(LCD_ON_CSR_OFF);
mydelay(5);
}
}
void mydelay(unsigned char ct){
while(ct--) _delay(65535);
}
void LCM_initialize(){
LCM_DATA_CTRL = 0; //setup LCM data port as output port
LCM_CTRL_CTRL = 0; //setup LCM control port as output port
LCM_DATA = 0; //clear LCM data port
LCM_CTRL = 0; //clear LCM control port
#ifdef FOUR_BIT
WRITE(0x20); //4 bit mode
#else
WRITE(0x30); //8 bit mode
#endif
//According to the data for the HD44780, there needs to be at
//least 4.5 ms delay between each program.
mydelay(1);
#ifdef FOUR_BIT
#ifdef ONE_LINE
WRITE(0x20); //4-bit 1-line
#else
WRITE(0x28); //4-bit 2-line
#endif
#else
#ifdef ONE_LINE
WRITE(0x30); //8-bit 1-line
#else
WRITE(0x38); //8-bit 2-line
#endif
#endif
#ifdef FOUR_BIT
WRITE(0x80); //4-bit high nibble (2nd pass)
#endif
send_cmd(LCM_CLS); //clean display
send_cmd(TURN_ON_DISP); //turn on display
send_cmd(INCDD_CG_SHF_C); //auto increment mode
//cursor left and DD RAM address+1
}
// send command to LCM
void send_cmd(unsigned char c){
#ifdef FOUR_BIT
unsigned char tmp;
tmp = c << 4;
c &= (unsigned char)0xf0;
#endif
busy_check();
LCM_DATA = c;
LCM_CTRL_RW = 0;
LCM_CTRL_RS = 0;
LCM_CTRL_E = 1;
LCM_CTRL_E = 0;
#ifdef FOUR_BIT
WRITE(tmp);
#endif
}
// write character to LCM
void write_char(unsigned char c){
#ifdef FOUR_BIT
unsigned char tmp;
tmp = c<<4;
c &= (unsigned char)0xf0;
#endif
busy_check();
LCM_DATA = c;
LCM_CTRL_RW = 0;
LCM_CTRL_RS = 1;
LCM_CTRL_E = 1;
LCM_CTRL_E = 0;
#ifdef FOUR_BIT
WRITE(tmp);
#endif
}
// Wait until the busy flag is not busy
void busy_check(void){
unsigned char val, tmp;
do{
LCM_CTRL_E = 0;
LCM_DATA_CTRL = 0xff;
LCM_CTRL_RS = 0;
LCM_CTRL_RW = 1;
LCM_CTRL_E = 1;
val = LCM_DATA;
LCM_CTRL_E = 0;
#ifdef FOUR_BIT
tmp = val & (unsigned char)0xf0;//4-bit high nibble
LCM_CTRL_E = 1; //pulse high
val = LCM_DATA; //4-bit low nibble (2nd pass)
LCM_CTRL_E = 0; //pulse low
val = (val>>4) | tmp; //combine 2 pass
#endif
}while(val & (unsigned char)0x80);
LCM_CTRL_RW = 0;
LCM_DATA_CTRL = 0; //LCM not busy, then set LCM data
//bus to input port
}