명령어와 데이터 관련 GPIO 제어루틴
귀찮으니 대충 정리해서
명령어는
Step 1.
RS/RW가 동시에 Low로 이동 (40ns delay)
Step 2. E가 High로 이동 / Data 설정(
상위 4비트)
Step 3. E가 Low로 이동 (10ns delay)
Step 4.
RW 해제
Step 5.
RS/RW가 동시에 Low로 이동
Step 6. E가 High로 이동 / Data 설정 (
하위 4비트) - Step 2 반복
Step 7. E가 Low로 이동 (10ns delay) - Step 3 반복
Step 8.
RS/RW가 동시에 High로 이동
DDRAM/CGRAM 데이터는
Step 1.
RS는 High RW는 Low로 이동 (40ns delay)
Step 2. E가 High로 이동 / Data 설정(
상위 4비트)
Step 3. E가 Low로 이동 (10ns delay)
Step 4.
RW 해제
Step 5.
RS는 High RW는 Low로 이동
Step 6. E가 High로 이동 / Data 설정 (
하위 4비트) - Step 2 반복
Step 7. E가 Low로 이동 (10ns delay) - Step 3 반복
Step 8.
RS/RW가 동시에 High로 이동
#define CLCD_RS 0x01
#define CLCD_RW 0x02
#define CLCD_E 0x04
#define DEFAULT_DLY 20
void ls1628_write_cmd(char cmd)
{
/**************************************/
// set RS & R/W
PORTC = 0x00;
// set E clock to high
_delay_us(DEFAULT_DLY); // 40ns delay
PORTC |= CLCD_E;
// data set - high nibble
PORTC |= (cmd & 0xF0);
_delay_us(DEFAULT_DLY); // 80ns delay
// set E clock to low
PORTC &= (~CLCD_E);
_delay_us(DEFAULT_DLY); // 10ns delay
// release RW
PORTC &= (~CLCD_RW);
/**************************************/
// set RS & R/W
PORTC = 0x00;
// set E clock to high
_delay_us(DEFAULT_DLY); // 40ns delay
PORTC |= CLCD_E;
// data set - low nibble
PORTC |= ((cmd & 0x0F) << 4);
_delay_us(DEFAULT_DLY); // 80ns delay
// set E clock to low
PORTC &= (~CLCD_E);
_delay_us(DEFAULT_DLY); // 10ns delay
// release RW
PORTC &= (~CLCD_RW);
}
void ls1628_write_char(char data)
{
/**************************************/
// set RS & R/W
PORTC = CLCD_RS;
// set E clock to high
_delay_us(DEFAULT_DLY); // 40ns delay
PORTC |= CLCD_E;
// data set - high nibble
PORTC |= (data & 0xF0);
_delay_us(DEFAULT_DLY); // 80ns delay
// set E clock to low
PORTC &= (~CLCD_E);
_delay_us(DEFAULT_DLY); // 10ns delay
// release RW
PORTC &= (~CLCD_RW);
/**************************************/
// set RS & R/W
PORTC = CLCD_RS;
// set E clock to high
_delay_us(DEFAULT_DLY); // 40ns delay
PORTC |= CLCD_E;
// data set - low nibble
PORTC |= ((data & 0x0F) << 4);
_delay_us(DEFAULT_DLY); // 80ns delay
// set E clock to low
PORTC &= (~CLCD_E);
_delay_us(DEFAULT_DLY); // 10ns delay
// release RW
PORTC &= (~CLCD_RW);
}
CLCD 초기화는 아래와 같이 수행해 준다.
그런데.. Function set 이후에 왜 E를 High로 해주어야 하는건지... 이유를 모르겠다!!!
#define CMD_CLS 0x01 // Clear Display
#define CMD_RTH 0x02 // Return HOME
#define CMD_MOD 0x04 // Entry Mode Set
#define MOD_INC 0x02
#define MOD_DEC 0x00
#define MOD_SHL 0x01
#define MOD_SHR 0x00
#define CMD_DIS 0x08 // Display on/off
#define DIS_ON 0x04
#define DIS_CUR 0x02
#define DIS_BLK 0x01
#define CMD_CUR 0x10 // Cursor or Display Shift
#define CUR_CUR 0x08
#define CUR_ALL 0x00
#define CUR_LEF 0x04
#define CUR_RIG 0x00
#define CMD_FNC 0x20 // Function Set
#define FNC_DL8 0x10
#define FNC_DL4 0x00
#define FNC_DN2 0x08
#define FNC_DN1 0x00
#define FNC_H10 0x04
#define FNC_H07 0x00
#define CMD_CGA 0x40 // Set CGRAM Address
#define CRA_ADR 0x3F
#define CMD_DDA 0x80 // Set DDRAM Address
void init_clcd(void)
{
_delay_ms(50);
ls1628_write_cmd(CMD_FNC | FNC_DL4 | FNC_DN2 | FNC_H07); // fuction set
PORTC = CLCD_E; // unknown
_delay_us(80); // 39 us wait
ls1628_write_cmd(CMD_DIS | DIS_ON | DIS_CUR | DIS_BLK); // disp on/off control
_delay_us(80); // 39 us wait
ls1628_write_cmd(CMD_CLS); // disp clear
_delay_ms(2); // 1.53ms wait
ls1628_write_cmd(CMD_MOD | MOD_INC | MOD_SHR); // entry mode set CMD_MOD
_delay_us(80);
ls1628_write_cmd(CMD_DDA);
_delay_us(80);
}