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
- dataflow modeling
- prescaling
- test bench
- pwm
- KEYPAD
- uart 통신
- i2c 통신
- LED
- Algorithm
- Recursion
- FND
- structural modeling
- D Flip Flop
- Edge Detector
- hc-sr04
- ring counter
- half adder
- verilog
- DHT11
- vivado
- behavioral modeling
- gpio
- soc 설계
- Pspice
- stop watch
- ATMEGA128A
- Linked List
- java
- atmega 128a
- BASYS3
Archives
- Today
- Total
거북이처럼 천천히
LCD Display (HD44780U) - (2, 4bit mode) 본문
Embedded Programming (AVR)/Atmega 128A (실습)
LCD Display (HD44780U) - (2, 4bit mode)
유로 청년 2024. 9. 11. 13:351. 4bit mode를 이용하여 HD44780U LCD 모듈과 통신하기
- 지난 게시글에서는 8bit mode를 이용하여 HD44780U LCD 모듈과 통신을 하였다.
- HD44780U LCD 디스플레이 모듈은 8bit mode 외에도 4bit mode를 지원한다.
- 4bit mode는 8bt mode와 달리 4개의 데이터 버스를 이용하여 MCU와 LCD 디스플레이 모듈간에 데이터를 주고 받는다. 따라서 8bit 모드과 비교하였을 때, 4개의 와이어를 통해 데이터를 주고 받을 수 있어 자원을 효율적으로 줄일 수 있지만, 데이터 송수신 시간이 8bit 모드 대비 상대적으로 많이 소요된다.
- 4bit 모드를 통해 LCD 디스플레이 모듈과 통신 이론은 아래 게시글을 참고하길 바란다.
Verilog RTL 설계(8월 22일 - 2, I2C 통신을 통한 LCD 컨트롤 - (2)) (tistory.com)
2. 4bit mode를 이용하여 HD44780U LCD 모듈과 통신하는 함수 구현
< Source, Header file >
- Header File에 필요한 Parameter 선언 및 라이브러리, 함수 원형 선언하였다.
#ifndef LCD_H_
#define LCD_H_
// Define System Clock
#define F_CPU 16000000UL
// Define Library
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>
// Define PORT, DDR, PIN
#define LCD_DATA_PORT PORTF
#define LCD_DATA_DDR DDRF
#define LCD_DATA_PIN PINF
#define LCD_RS_DDR DDRE
#define LCD_RW_DDR DDRE
#define LCD_E_DDR DDRE
#define LCD_RS_PORT PORTE
#define LCD_RW_PORT PORTE
#define LCD_E_PORT PORTE
// Define Pin
#define LCD_RS_PIN 5
#define LCD_RW_PIN 6
#define LCD_E_PIN 7
// Function prototype
void LCD_INPUT_DATA(uint8_t data);
void LCD_SET_RW_WRITE();
void LCD_SEND_DATA(uint8_t data);
void LCD_SEND_COMMAND(uint8_t commnad);
void LCD_ENABLE();
void LCD_INIT();
void LCD_gotoXY(uint8_t row, uint8_t col);
void LCD_SEND_STRING();
#endif /* LCD_H_ */
- 이번 구현은 ATmega128A와 HD44780U LCD 디스플레이 모듈을 이용하여 구현하였다.
- 4bit 데이터를 송수신하기 위해 PORT F (4핀 ~ 7핀)을 사용하였으며, RS, RW, Enable,과 같은 제어 신호는 PORT E에 5핀, 6핀, 7핀에 각각 연결하였다.
< Source, Parameter로 전달 받은 8bit 데이터를 4bit 데이터로 쪼개어 4bit씩 데이터를 PORT에 전달한다. >
// Parameter로 전달 받은 data값을 PORT로 전달
void LCD_INPUT_DATA(uint8_t data) {
LCD_DATA_PORT = (LCD_DATA_PORT & 0x0f) | (data & 0xf0);
LCD_ENABLE();
LCD_DATA_PORT = (LCD_DATA_PORT & 0x0f) | ((data & 0x0f)<<4);
LCD_ENABLE();
}
- Parameter로 전달 받은 8bit 데이터를 4bit씩 쪼개어 두 번에 걸쳐서 데이터를 보내게 된다.
- 4bit씩 쪼개진 데이터를 PORT에 전달 한 뒤, Enable 신호 값을 Low → High → Low으로 변화시키기 위해 LCD_ENALBE 함수를 4bit 데이터를 전송한 뒤, 작성하였다.
★★★★★★★★★★★★ - Q) 왜 데이터를 PORT에 바로 넣지 않고, (LCD_DATA_PORT & 0x0f)와 OR 연산을 한 뒤, PORT에 대입하는가?
- A) (LCD_DATA_PORT & 0x0f)의 의미는 "PORT의 상위 4bit를 0으로 초기화하는 과정을 의미한다. PORT의 상위 4bit에 데이터를 넣기 전, 0으로 초기화하는 이유는 PORT에 남아 있는 상태에서 데이터를 넣게 되면 잘못된 데이터가 PORT에 있을 수 있기 때문에 PORT에 데이터를 넣기 전에 초기화 작업을 수행하게 된다.
< Source, Read/Write Pin 값을 Write(1)로 설정하기 >
// RW Pin의 DDR 값을 1로 설정
void LCD_SET_RW_WRITE() {
LCD_RW_PORT &= ~(1<<LCD_RW_PIN);
}
< Source, Enable 신호 값을 Low → High → Low 으로 변화시켜 LCD 모듈에 데이터를 전송한다. >
void LCD_ENABLE() {
// 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);
}
< Source, 8bit 명령어 및 8bit 데이터를 전송하기 >
void LCD_SEND_DATA(uint8_t data) {
LCD_SET_RW_WRITE();
LCD_RS_PORT |= (1<<LCD_RS_PIN);
LCD_INPUT_DATA(data);
}
void LCD_SEND_COMMAND(uint8_t command) {
LCD_SET_RW_WRITE();
LCD_RS_PORT &= ~(1<<LCD_RS_PIN);
LCD_INPUT_DATA(command);
}
- Parameter로 전달 받은 8bit data와 command를 MCU에서 LCD 디스플레이 모듈로 전달한다.
< Source, 특정 x와 y값을 Parameter로 받은 뒤, 해당 좌표 지점으로 이동한다. >
void LCD_gotoXY(uint8_t row, uint8_t col) {
row %= 2;
col %= 16;
uint8_t address = 0x40*row + col;
uint8_t specific_address_command = 0x80 + address;
LCD_SEND_COMMAND(specific_address_command);
}
< Source, LCD 디스플레이 모듈 초기화 작업 >
void LCD_INIT() {
// Init of port
LCD_DATA_DDR = 0xff;
LCD_RS_DDR |= (1<<LCD_RS_PIN);
LCD_RW_DDR |= (1<<LCD_RW_PIN);
LCD_E_DDR |= (1<<LCD_E_PIN);
// Init of LCD
_delay_ms(30);
LCD_SEND_COMMAND(0x33);
LCD_SEND_COMMAND(0x32);
LCD_SEND_COMMAND(0x2a);
LCD_SEND_COMMAND(0x0c);
LCD_SEND_COMMAND(0x01);
LCD_SEND_COMMAND(0x06);
}
< Source, 문자열을 Parameter로 전달 받아 순차적으로 문자열을 출력한다. >
void LCD_SEND_STRING(char* string) {
int str_lenght = strlen(string);
for(uint8_t i=0; i<str_lenght; i++)
LCD_SEND_DATA(string[i]);
}
< Source, Main method >
#include "lcd.h"
int main(void)
{
LCD_INIT();
LCD_gotoXY(0, 0);
LCD_SEND_STRING("Hello! World?");
LCD_gotoXY(1, 0);
LCD_SEND_STRING("I AM 4BIT MODE!");
while (1)
{
}
}
3. 구현
'Embedded Programming (AVR) > Atmega 128A (실습)' 카테고리의 다른 글
LCD Display (HD44780U) - (3, I2C 통신) (0) | 2024.09.12 |
---|---|
LCD Display (HD44780U) - (1, 8bit 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 |