Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- DHT11
- D Flip Flop
- gpio
- test bench
- atmega 128a
- Edge Detector
- Linked List
- uart 통신
- behavioral modeling
- Pspice
- Algorithm
- KEYPAD
- FND
- verilog
- Recursion
- BASYS3
- LED
- dataflow modeling
- soc 설계
- ring counter
- ATMEGA128A
- half adder
- hc-sr04
- pwm
- structural modeling
- i2c 통신
- vivado
- stop watch
- prescaling
- java
Archives
- Today
- Total
거북이처럼 천천히
LCD Display (HD44780U) - (1, 8bit mode) 본문
Embedded Programming (AVR)/Atmega 128A (실습)
LCD Display (HD44780U) - (1, 8bit mode)
유로 청년 2024. 9. 11. 08:041. 8bit mode를 통해 LCD 디스플레이 모듈인 HD44780U와 직접 연결하여 통신하기
- 이전 게시글에서는 I2C 통신을 이용하여 HD44780U, LCD 디스플레이 모듈과 통신하였다.
- 이번에는 HD44780U 모듈과 직접 연결하여 8bit mode로 통신해보도록 하겠다.
- HD44780U, LCD 디스플레이 모듈에 대해서 궁금하다면 아래 게시글을 참고하길 바란다.
Verilog RTL 설계(8월 22일 - 1, I2C 통신을 통한 LCD 컨트롤 - (1)) (tistory.com)
2. Header File of HD44780U, LCD Display Module
- Header File에 필요한 Parameter 선언 및 라이브러리, 함수 원형 선언하였다.
#ifndef LCD_H_
#define LCD_H_
// ATmega 128 System Clock 설정
#define F_CPU 16000000UL
// Define Header File
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>
// Define Parameter
#define LCD_DATA_PORT PORTF
#define LCD_DATA_DDR DDRF
#define LCD_DATA_PIN PINF
#define LCD_RS_PORT PORTE
#define LCD_RW_PORT PORTE
#define LCD_E_PORT PORTE
#define LCD_RS_DDR DDRE
#define LCD_RW_DDR DDRE
#define LCD_E_DDR DDRE
// Define PIN of Control
#define LCD_RS_PIN 5
#define LCD_RW_PIN 6
#define LCD_E_PIN 7
// Define Function Prototype
void LCD_INIT();
void LCD_SET_RW_READ();
void LCD_SET_RW_WRITE();
void LCD_SEND_DATA(uint8_t data);
void LCD_SEND_COMMAND (uint8_t command);
void LCD_ENABLE_PIN(); // Send data from MCU to LCD
void LCD_gotoXY(uint8_t row, uint8_t col); // Change to specific x, y
void LCD_INPUT_PORT(uint8_t data);
// Send data
void LCD_SEND_CHARACTER (uint8_t character);
void LCD_SEND_STRING(char* string);
// Declare 8bit mode
#define COMMAND_8BIT_MODE 0x38
#endif /* LCD_H_ */
- 이번 구현은 ATmega128A와 HD44780U LCD 디스플레이 모듈을 이용하여 구현하였다.
- 8bit 데이터를 송수신하기 위해 PORT F를 사용하였으며, RS, RW, Enable,과 같은 제어 신호는 PORT E에 5핀, 6핀, 7핀에 각각 연결하였다.
3. 8bit-mode 로 LCD 디스플레이 모듈과 통신
< Source, Parameter로 전달 받은 8bit 데이터를 Port로 전달하여 출력 >
// Data Port 에 8bit data 입력
void LCD_INPUT_PORT(uint8_t data) {
LCD_DATA_PORT = data;
}
< Source, Register Select의 DDR을 1으로 설정하여 Write로 변경 >
// LCD_RW_PIN 핀 Write 설정 (LCD_RW_PIN = 1)
void LCD_SET_RW_WRITE() {
// LCD_RW_PIN = 1
LCD_RW_DDR |= (1<<LCD_RW_PIN);
}
- 해당 함수는 LCD 디스플레이에 데이터를 Write하기 위해 RW 핀의 DDR 값을 1로 만들어 준다.
< Source, Enable 신호값을 Low → High → Low으로 변환 >
// 데이터를 MCU에서 LCD 디스플레이 모듈로 전송하기 위한 Enable 신호 변화
void LCD_ENABLE_PIN() {
// Enable : Low -> High -> Low
LCD_E_PORT &= ~(1<<LCD_E_PIN);
LCD_E_PORT |= (1<<LCD_E_PIN);
LCD_E_PORT &= ~(1<<LCD_E_PIN);
_delay_us(1600);
}
- Enable 신호는 MCU와 HD44780 LCD 모듈과의 통신 타이밍을 정확하게 제어할 수 있게 만들어 준다.
- Enable 신호가 Low → High 로 변화하게 되면 LCD 디스플레이 모듈에게 "LCD 디스플레이야! 너가 읽어야 할 데이터가 있으니, 데이터 읽을 준비 해!" 라는 신호를 보내게 되며, High → Low 로 변화하게 되면 LCD 디스플레이는 실제로 MCU로 부터 데이터를 가져오게 된다.
- 따라서 LCD 디스플레이 모듈은 Enable 신호 값이 Low → High로 변화할 때, 데이터를 가져오는 것이 아니라 High → Low로 변화할 때, 데이터를 가져오게 된다.
★★★★★★★★★★★★ - Q) Enable 신호값을 Low → High → Low로 변화시킨 뒤, 1600us delay time을 가지는가?
- Enable 신호값을 변화시킨 뒤, 1600us delay time을 갖는 이유는 Enable 신호의 안정화 시간을 갖기 위해서 대기 시간을 갖는 것이다. LCD HD44780U의 DataSheet에 따르면 Enable 신호값을 변화시킨 뒤, 1600us delay time을 가질 것을 권장하고 있다.
< Source, Parameter로 전달받은 8bit 데이터를 MCU에서 LCD 모듈로 전송하는 전체적인 과정 >
// Send data
void LCD_SEND_DATA(uint8_t data) {
// Data Port Write 설정
LCD_SET_RW_WRITE();
// Register Select : 1로 설정
LCD_RS_PORT |= (1<<LCD_RS_PIN);
// Data Port에 데이터 전송
LCD_INPUT_PORT(data);
// 데이터를 LCD로 전송하기 위해 Enable 신호값 변화
LCD_ENABLE_PIN();
}
- 위 코드에서 각각의 줄은 다음과 같은 의미를 갖습니다.
▶ LCD_SET_RW_WRITE() : LCD 디스플레이에 데이터를 Write하기 위해 RW핀의 DDR 값을 1로 설정한다.
▶ LCD_RS_PORT |= (1<<LCD_RS_PIN) : 8bit 데이터를 전송할 것이기 때문에 RS = 1로 설정한다.
▶ LCD_INPUT_PORT(data) : Data Port에 parameter로 전달받은 데이터를 내보낸다>
▶ LCD_ENABLE_PIN() : Data Port에 데이터를 전달한 뒤, LCD 디스플레이에 데이터를 전송하기 위해 Enable 신호 값을 Low → High → Low 로 변화시킨다.
< Source, Parameter로 전달 받은 8bit 명령어를 MCU에서 LCD 모듈로 전송하는 전체적인 과정 >
// Send Command
void LCD_SEND_COMMAND (uint8_t command) {
// Register Select : 0
LCD_RS_PORT &= ~(1<<LCD_RS_PIN);
// Data Port Write로 설정
LCD_SET_RW_WRITE();
// 명령어 전송
LCD_INPUT_PORT(command);
// 데이터를 LCD로 전송하기 위해 Enable 신호값 변화
LCD_ENABLE_PIN();
}
- 위 코드에서 각각의 줄은 다음과 같은 의미를 갖습니다.
▶ LCD_SET_RW_WRITE() : LCD 디스플레이에 데이터를 Write하기 위해 RW핀의 DDR 값을 1로 설정한다.
▶ LCD_RS_PORT &= ~(1<<LCD_RS_PIN) : 8bit 명령어를 전송할 것이기 때문에 RS = 0로 설정한다.
▶ LCD_INPUT_PORT(command) : Data Port에 parameter로 전달받은 명령어를 내보낸다.
▶ LCD_ENABLE_PIN() : Data Port에 명령어를 전달한 뒤, LCD 디스플레이에 명령어를 전송하기 위해 Enable 신호 값을 Low → High → Low 로 변화시킨다.
< Source, LCD 디스플레이 모듈의 초기화 작업 >
// Initialization of LCD
void LCD_INIT() {
// PORT 초기화
LCD_DATA_DDR = 0xff;
LCD_RW_DDR |= (1<<LCD_RW_PIN);
LCD_E_DDR |= (1<<LCD_E_PIN);
LCD_RS_DDR |= (1<<LCD_RS_PIN);
// LCD 초기화
_delay_ms(30);
LCD_SEND_COMMAND(COMMAND_8BIT_MODE);
_delay_ms(5);
LCD_SEND_COMMAND(COMMAND_8BIT_MODE);
_delay_ms(100);
LCD_SEND_COMMAND(COMMAND_8BIT_MODE);
LCD_SEND_COMMAND(0x3c); // 2-line, 5x10 dots
LCD_SEND_COMMAND(0x0c); // Display: on, cursor : off
LCD_SEND_COMMAND(0x01); // Clear Display
LCD_SEND_COMMAND(0x06); // Increase, Display Shift : off
}
- 해당 함수는 HD 44780U LCD 디스플레이 모듈을 사용하기 위해 수행하는 초기화 작업이다.
- 먼저, 8bit Data, RW(Read/Write). Enable, RS(Register Select)의 DDR(Data Direction Register)을 초기화시켜 준다.
- HD 44780U LCD 디스플레이 모듈의 Data Sheet에 따라 8bit mode, initialization of LCD 작업 수행시켜 주었다.
< Source, LCD 디스플레이 화면에서 특정 X, Y 좌표로 이동하는 명령어 전송 >
void LCD_gotoXY(uint8_t row, uint8_t col) {
// row, col 값을 LCD 화면으로 제한
row %= 2;
col %= 16;
// 특정 좌표의 주소값을 계산
// 1행 : 0x00 ~ 0x0f
// 2행 : 0x40 ~ 0x4f;
uint8_t address = (0x40*row) + col;
// 특정 좌표로 전송하는 명령어와 계산한 주소값과 더한다.
uint8_t command_move_address = 0x80 + address;
// Send command
LCD_SEND_COMMAND(command_move_address);
}
- LCD_gotoXY 함수는 parameter로 전달 받은 row, col 값으로 커서를 이동시키는 명령어를 전송하는 함수이다.
- LCD_gotoXY 함수의 각 명령어 소스 코드들은 다음과 같은 의미를 갖는다.
▶ row %= 2; col %= 16; : row값과 col값을 2 x 16 LCD 화면안으로 제한하도록 설계
▶ uint8_t command_move_address = (0x40*row) + col; : 특정 x, y 좌표의 주소값을 계산
▶ uint8_t command_move_address = 0x80 + address; : 커서 이동 명령어와 계산된 주소를 연산
▶ LCD_SEND_COMMAND(command_move_address); : 연산된 명령어를 LCD 모듈에 전송
< Source, parameter로 전달 받은 character와 string 변수를 LCD 모듈로 전송한다. >
// Send character
void LCD_SEND_CHARACTER (uint8_t character) {
LCD_SEND_DATA(character);
}
// Send String
void LCD_SEND_STRING(char* string) {
int str_length = strlen(string);
for(uint8_t i=0; i<str_length; i++)
LCD_SEND_DATA(string[i]);
}
- Parameter로 전달 받은 character와 string을 LCD_SEND_DATA 함수를 통해 MCU에서 LCD 디스플레이 모듈로 데이터를 전송한다
< Source, Main 함수 >
#include "lcd.h"
int main(void)
{
// Init of LCD
LCD_INIT();
// SEND_DATA
LCD_gotoXY(0, 0);
LCD_SEND_STRING("Hello World!");
LCD_gotoXY(1,0);
LCD_SEND_STRING("I am 8bit mode!");
return 0;
}
- LCD 디스플레이를 데이터 시트에 따라 8bit mode로 LCD 초기화 작업을 수행한다.
- 초기화 작업이 끝나면 1행에는 "Hello World!", 2행에는 "I am 8bit mode!" 문자열을 출력하도록 하였다.
4. 구현
'Embedded Programming (AVR) > Atmega 128A (실습)' 카테고리의 다른 글
LCD Display (HD44780U) - (3, I2C 통신) (0) | 2024.09.12 |
---|---|
LCD Display (HD44780U) - (2, 4bit mode) (0) | 2024.09.11 |
8bit Timer / counter - Phase Correct Fast PWM Mode (0) | 2024.06.19 |
Structure (1) | 2024.06.11 |
다양한 파형 생성 실험 (8bit Timer/Counter) (0) | 2024.06.09 |