TFT LCD에 이미지 표시하는 방법
2024년 4월 2일
TFT LCD(박막 트랜지스터 액정 디스플레이)는 스마트폰, 태블릿, TV 등 다양한 기기에 널리 사용되는 LCD의 한 종류입니다. TFT LCD는 높은 화질, 빠른 응답 속도, 낮은 전력 소비로 알려져 있습니다.
TFT LCD의 가장 흔한 용도 중 하나는 이미지 표시입니다. 이로 인해 디지털 사진 프레임, 디지털 사이니지, DIY 프로젝트 등 다양한 프로젝트에 이상적입니다. 본 문서에서는 SD 카드와 Arduino Due를 사용하여 TFT LCD에 이미지를 표시하는 방법을 소개합니다.
필요한 것들
- 아두이노 듀 마이크로컨트롤러 보드
- 240x320 TFT 디스플레이, ST7789VI 또는 동급 IC 탑재 (NHD-2.4-240320AF-CSXP)
- 40핀 0.5mm 피치 FFC 브레이크아웃 보드 (NHD-FFC40)
- SD 카드
- SD 카드 브레이크아웃 보드
- 브레드보드
- 점퍼선
- 마이크로컨트롤러용 USB 케이블
- 아두이노 IDE 소프트웨어
- LCD 이미지 변환기 소프트웨어
핀 배열 표
TFT LCD, SD 카드 브레이크아웃 보드 및 Arduino Due 간의 연결에 대한 완전한 핀아웃 설명 및 연결 방식.
TFT LCD 및 Arduino Due 핀 배열
| LCD 핀 | 기호 | 연결 |
|---|---|---|
| 1 | GND | GND |
| 2 | NC | NC |
| 3 | NC | NC |
| 4 | NC | NC |
| 5 | NC | NC |
| 6 | SDO | NC |
| 7 | VDD | 3.3V |
| 8 | VDDI | 3.3V |
| 9 | SDA | NC |
| 10 | CSX | GND |
| 11 | DCX | 아두이노 핀 2 |
| 12 | WRX | 아두이노 핀 11 |
| 13 | RDX | 3.3V |
| 14 | DB0 | NC |
| 15 | DB1 | NC |
| 16 | DB2 | NC |
| 17 | DB3 | NC |
| 18 | DB4 | NC |
| 19 | DB5 | NC |
| 20 | DB6 | NC |
| 21 | DB7 | NC |
| 22 | DB8 | 아두이노 핀 33 |
| 23 | DB9 | 아두이노 핀 34 |
| 24 | DB10 | 아두이노 핀 35 |
| 25 | DB11 | 아두이노 핀 36 |
| 26 | DB12 | 아두이노 핀 37 |
| 27 | DB13 | 아두이노 핀 38 |
| 28 | DB14 | 아두이노 핀 39 |
| 29 | DB15 | 아두이노 핀 40 |
| 30 | RESX | 3.3V |
| 31 | IM0 | 3.3V |
| 32 | IM2 | GND |
| 33 | GND | GND |
| 34 | LED-K1 | GND |
| 35 | LED-K2 | GND |
| 36 | LED-K3 | GND |
| 37 | LED-K4 | GND |
| 38 | LED-A | 3.3V |
| 39 | GND | GND |
| 40 | TE | NC |
SD 카드 브레이크아웃 보드 핀 배열:
| SD 브레이크아웃 핀 | 연결 |
|---|---|
| GND | 아두이노 듀 SPI 핀 6 |
| 미소 | 아두이노 듀 SPI 핀 1 |
| SCK | 아두이노 듀 SPI 핀 3 |
| 모시 | 아두이노 듀 SPI 핀 4 |
| CS | 아두이노 듀 핀 49 |
| 5V | 아두이노 듀 SPI 핀 2 |
| 3.3V | NC |
배선도
아래 배선도는 그래픽 표시 및 SD 카드 접근을 위해 TFT LCD와 SD 카드를 Arduino Due에 연결하는 방법을 보여줍니다.
이미지를 텍스트 파일로 변환하고 SD 카드에 저장
대부분의 LCD는 JPEG나 PNG 같은 표준 이미지 형식을 직접 해석하지 않습니다. 대신 16진수 형식으로 표현되는 원시 픽셀 데이터를 사용합니다. 먼저 LCD 이미지 변환기 소프트웨어를 다운로드하고 다음 단계를 따라 이미지를 이미지 데이터 배열로 변환해야 합니다:
- LCD 이미지 변환기 소프트웨어를 실행하십시오.
- 이미지 -> 가져오기로 이동하여 LCD에 표시할 이미지를 엽니다. 이미지 파일 해상도는 LCD의 해상도와 일치해야 합니다.
- 옵션 -> 변환으로 이동하여 "Color R5G6B5" 사전 설정이 선택되었는지 확인하십시오.
- "이미지" 탭을 클릭하세요. "일반" 섹션에서 "행으로 분할"의 체크를 해제하고 블록 크기를 "8비트"로 설정하세요.
- 창의 왼쪽 하단에서 "미리 보기 표시"를 클릭하세요.
- 16진수 값을 텍스트 편집기에 복사하여 붙여넣고 파일을 "image1.txt"로 저장하십시오.
- 텍스트 파일을 SD 카드로 옮긴 후, SD 카드를 브레이크아웃 보드에 삽입하십시오.
예제 코드를 아두이노 IDE에 복사하세요
아두이노 IDE를 열고 새 스케치를 시작하세요. 기존 코드를 모두 지운 후, 아래에 제공된 코드를 복사하여 붙여넣으세요.
/* /뉴헤이븐 디스플레이는 이 오픈소스 코드를 제공하기 위해 시간과 자원을 투자합니다. /뉴헤이븐 디스플레이 제품을 구매하여 뉴헤이븐 디스플레이를 지원해 주십시오! * * 본 코드는 예시 목적으로만 제공되며, 뉴헤이븐 디스플레이는 어떠한 보증도 하지 않습니다. * 뉴헤이븐 디스플레이는 본 코드 사용으로 인한 문제에 대해 책임을 지지 않습니다. * 본 샘플 코드의 일부를 포함하는 최종 애플리케이션의 개발자는 * 코드의 안전하고 올바른 작동을 보장할 책임이 있으며 * 사용으로 인한 모든 결과에 대한 책임도 집니다. * 자세한 내용은 GNU 일반 공중 사용 허가서를 참조하십시오. */ #include#include #include /**************************************************** * PINOUT: Arduino Due -> 2.4" TFT * *****************************************************/ #define RS 2 #define WR 11 const char slave = 0x38; const int ChipSelect = 49; int image_value = 0; File myFile; /**************************************************** * Function Commands * ******************************************************/ void comm_out(unsigned char c) { PIOB -> PIO_CODR = 1 << 25; //RS LOW REG_PIOC_ODSR = c << 1; PIOD -> PIO_CODR = 1 << 7; //WR LOW PIOD -> PIO_SODR = 1 << 7; //WR HIGH } void data_out(unsigned char d) { PIOB -> PIO_SODR = 1 << 25; //RS HIGH REG_PIOC_ODSR = d << 1; PIOD -> PIO_CODR = 1 << 7; //WR LOW PIOD -> PIO_SODR = 1 << 7; //WR HIGH } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // Window Set Function //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= void window_set(unsigned s_x, unsigned e_x, unsigned s_y, unsigned e_y) { comm_out(0x2a); //SET column address data_out((s_x)>>8); //SET start column address data_out(s_x); data_out((e_x)>>8); //SET end column address data_out(e_x); comm_out(0x2b); //SET page address data_out((s_y)>>8); //SET start page address data_out(s_y); data_out((e_y)>>8); //SET end page address data_out(e_y); } /**************************************************** * Initialization and Setup Routine * *****************************************************/ void setup() { delay(100); pinMode(RS,OUTPUT); pinMode(WR,OUTPUT); PIOC->PIO_OER = 0xFFFFFFFF; digitalWrite(WR, LOW); comm_out(0x28); //display off comm_out(0x11); //exit SLEEP mode delay(100); comm_out(0x36); //MADCTL: memory data access control data_out(0x10); //changing from 0x88 comm_out(0x21); //display inversion comm_out(0x3A); //COLMOD: Interface Pixel format *** 65K-colors in 16bit/pixel (5-6-5) format when using 16-bit interface to allow 1-byte per pixel data_out(0x55); //0x55 = 65k //0x65 = 262k comm_out(0xB2); //PORCTRK: Porch setting data_out(0x0C); data_out(0x0C); data_out(0x00); data_out(0x33); data_out(0x33); comm_out(0xB7); //GCTRL: Gate Control data_out(0x35); comm_out(0xBB); //VCOMS: VCOM setting data_out(0x2B); comm_out(0xC0); //LCMCTRL: LCM Control data_out(0x2C); comm_out(0xC2); //VDVVRHEN: VDV and VRH Command Enable data_out(0x01); data_out(0xFF); comm_out(0xC3); //VRHS: VRH Set data_out(0x11); comm_out(0xC4); //VDVS: VDV Set data_out(0x20); comm_out(0xC6); //FRCTRL2: Frame Rate control in normal mode data_out(0x0F); comm_out(0xD0); //PWCTRL1: Power Control 1 data_out(0xA4); data_out(0xA1); comm_out(0xE0); //PVGAMCTRL: Positive Voltage Gamma control data_out(0xD0); data_out(0x00); data_out(0x05); data_out(0x0E); data_out(0x15); data_out(0x0D); data_out(0x37); data_out(0x43); data_out(0x47); data_out(0x09); data_out(0x15); data_out(0x12); data_out(0x16); data_out(0x19); comm_out(0xE1); //NVGAMCTRL: Negative Voltage Gamma control data_out(0xD0); data_out(0x00); data_out(0x05); data_out(0x0D); data_out(0x0C); data_out(0x06); data_out(0x2D); data_out(0x44); data_out(0x40); data_out(0x0E); data_out(0x1C); data_out(0x18); data_out(0x16); data_out(0x19); comm_out(0x2A); //X address set data_out(0x00); data_out(0x00); data_out(0x00); data_out(0xEF); comm_out(0x2B); //Y address set data_out(0x00); data_out(0x00); data_out(0x01); data_out(0x3F); delay(10); comm_out(0x29); //display ON delay(10); SD.begin(ChipSelect); } /***************************************************** * Loop Function, to run repeatedly * *****************************************************/ void loop() { SD_Card_Image(1); delay(5000); //SD_Card_Image(2); //delay(5000); //SD_Card_Image(3); //delay(5000); //SD_Card_Image(4); //delay(5000); //SD_Card_Image(5); //delay(5000); } void SD_Card_Image(unsigned char image){ /*The images used are in a textfile*/ unsigned char dummy; unsigned int incr =0; switch (image){ case 1: image_value=1; myFile = SD.open("image1.txt"); break; case 2: image_value=2; myFile =SD.open("image2.txt"); break; case 3: image_value=3; myFile = SD.open("image3.txt"); break; case 4: image_value=4; myFile = SD.open("image4.txt"); break; case 5: image_value=5; myFile = SD.open("image5.txt"); break; } comm_out(0x2A); /*X address set*/ data_out(0x00); data_out(0x00); data_out(0x00); data_out(0xEF); comm_out(0x2B); /*Y address set*/ data_out(0x00); data_out(0x00); data_out(0x01); data_out(0x3F); comm_out(0x2C); /*command to begin writing to frame memory */ byte data_in1,data_in2,data_in,data_out_value; uint8_t data_send; char data_conv[1]={0}; int i; int track ; while (myFile.available()){ /*convert the input char data to integers*/ dummy = myFile.read(); dummy = myFile.read(); data_in1 = myFile.read(); data_in2 = myFile.read(); data_in=data_in1; if(data_in >=48 && data_in<=57){ /*if values are in range of 0-9 values*/ data_in1 = data_in-48; track=1; } if(data_in <=102 && data_in>=97){ /*if values are in range of a-f*/ data_in1 = data_in - 87; track=1; } if( data_in ==32/*Space*/ || data_in==44 /*comma*/ || data_in == 120 /*x*/){ dummy =data_in; track=0; data_in1 =0; data_in2 =0; } data_in=data_in2; if(data_in >=48 && data_in<=57){ /*if values are in range of 0-9 values*/ data_in2 = data_in-48; track=1; } if(data_in <=102 && data_in>=97){/*if values are in range of a-f*/ data_in2 = data_in - 87; track=1; } if( data_in ==32/*Space*/ || data_in==44 /*comma*/ || data_in == 120 /*x*/){/*skip dummy data*/ dummy =data_in; track=0; data_in1 =0; data_in2 =0; } dummy = myFile.read(); dummy = myFile.read(); data_out_value = data_in1<<4 | data_in2; data_out(data_out_value); } myFile.close(); }
코드를 아두이노에 업로드하세요
마지막 단계는 코드를 아두이노 IDE에 업로드하는 것입니다.
- USB-B 케이블로 아두이노를 PC에 연결하세요.
- 아두이노 IDE에서 보드와 포트를 선택하세요.
- "업로드" 버튼을 클릭하여 아두이노에 코드를 프로그래밍하세요.
코드가 성공적으로 업로드되면, 이미지가 LCD 화면에 표시됩니다.
자세히 알아보기
더 많은 튜토리얼과 인사이트를 보려면 저희의 다른 게시글을 확인해 보세요:
결론
전자공학을 배우거나 프로토타입을 제작하거나, 단순히 재미로 전자기기를 다루고 싶다면, 이 튜토리얼은 SD 카드에서 16진수 이미지 데이터를 읽어 TFT LCD에 표시하는 기본 과정을 설명합니다. 이는 시작점일 뿐이며, 확장 가능성은 무궁무진합니다. 이 튜토리얼이 즐거웠기를 진심으로 바랍니다!
클릭하여 확장