ควบคุมจอ Nokia GLCD 6100 (Chip Phillips) ด้วย MCU 8 bits

ควบคุมจอ Nokia GLCD 6100 (Chip Phillips) ด้วย MCU 8 bits

บทนำ
หลังจากที่ได้กล่าวถึงอุปกรณ์ มือถือ จอแสดงผล Nokia GLCD 3310 กันไปแล้ว คราวนี้เราจะมาแกะรอย Nokia GLCD color 6100 กันบ้างครับ ด้วยความที่เป็นจอแสดงผลภาพแบบกราฟิกสี ซึ่งมีราคาถูก สามารถหาซื้อได้ที่ เสือป่า หรือ ร้านขายอะไหล่อุปกรณ์มือถือทั่วไป  วันนี้คุณจะได้ทึ่งกับตัวเองแล้วครับ เพราะว่าคุณก็สามารถควบคุมการแสดงผลภาพจาก GLCD color 6100 ไมโครคอนโทรลเลอร์ ในงาน Embedded Electronics , โครงงาน , งานประดิษฐ์ ต่าง ๆ ได้ง่ายเพียงปลายนิ้วเท่านั้นเอง และคุณยังได้พื้นฐานที่แท้จริงถึงการควบคุมการแสดงผลของจอประเภทกราฟิกด้วย ครับ คุณลองทำดูวันนี้ คุณก็จะทำได้ในวันนี้ !!!

Nokia GLCD color 6100 โดยทั่วไปแล้วจะแบ่งเวอร์ชั่นของ chip ภายในออกเป็น 2 แบบคือ แบบ chip phillips และ chip Epson แต่ละแบบ มีการเขียน software ที่แตกต่างกัน เวลาเลือกซื้อ คุณสามารถสังเกตความแตกต่างได้จากภายนอกของจอแสดงผลได้เลย ดังรูป

สังเกตที่สีของสายแพ โดยพลิกดูจากด้านหน้าของจอ (แต่ไม่ใช่สีที่ แผ่น pcb) จะสังเกตเห็นว่า จะมีสีส้ม กับ สีเขียว ซึ่งสีเขียว คือ chip Epson และ สีส้ม คือ chip Phillips ครับ ดังนั้นเวลาคุณเลือกซื้อมาใช้งาน กรุณาสังเกตอย่างที่บอกไปครับ (หากว่าใครมีเทคนิคการเลือกซื้อเพิ่มเติม สามารถ share knowledge กันได้ครับ ThaiEasyElec ขอขอบคุณครับ) 

องค์ประกอบของ GLCD Nokia 6100

 ขาของ LCD6100 มี 10 ขา โดยมีรายละเอียดดังนี้

 ขา 1 VDIG คือ แรงดันไฟเลี้ยงสำหรับวงจร Digital เช่น ไฟเลี้ยง LCD Controller ที่ฝังอยู่
 ขา 2 RST คือ ขารีเซต โดยทำงานที่ลอจิก 0
 ขา 3 SDAT คือ ขาสำหรับรับส่งข้อมูลแบบอนุกรม
 ขา 4 SCLK คือ สำหรับสัญญาณนาฬิกาสำหรับกำหนดจังหวะการอ่านข้อมูล
 ขา 5 CS คือ Chip Select สำหรับ enable การรับส่งข้อมูลอนุกรม ทำงานที่ลอจิก 0
 ขา 6 VDISPLAY แรงดันที่ใช้ในการแสดงผล สามารถใช้ได้กับแรงดัน 3.3V
 ขา 7 NC ไม่มีการใช้งาน
 ขา 8 GND
 ขา 9 LED- เป็นขาลบ สำหรับไฟ Backlight ถ้าไม่ต้องการควบคุม การจ่ายไฟ สามารถต่อ GND ได้โดยตรง
 ขา 10 LED+ เป็นขาบวก สำหรับไฟ Backlight ใช้ได้กับแรงดันประมาณ 6-7 V

 ท่านสามารถ Download symbol และ footprint สำหรับจอ LCD 6100 ได้ที่เว็บไซต์ ThaiEasyElec ครับ

การติดต่อ GLCD Nokia 6100 ด้วยไมโครคอนโทรลเลอร์
     ภายในจอ LCD 6100 จะมี LCD Controller ที่ทำหน้าที่สแกนภาพออกที่จอ (เหมือนเวลาเราใช้ 7-segments) โดยจะมีหน่วยความจำ SRAM ในตัว และเวลาเราติดต่อกับจอ ก็คือการติดต่อกับตัว LCD Controller ซึ่งจริงๆแล้ว สามารถติดต่อได้ทั้งแบบ parallel และแบบอนุกรม แต่ผู้ผลิตจอ LCD 6100 ได้ต่อวงจรในส่วนนี้เรียบร้อยแล้ว และให้เราติดต่อได้ทางอนุกรมเท่านั้น
     สำหรับจอ LCD 6100 ที่ใช้ IC PCF8833 ของ Phillips เป็น LCD Controller ใช้การเชื่อมต่อแบบ SPI 9-bit มี timing diagram ดังรูป

จาก  Timing diagram (รูปนำมาจาก datasheet ของ PCF8833) การส่งข้อมูลจะส่ง MSB ก่อน LSB และก่อนจะเป็นข้อมูล 8 บิต จะต้องส่ง bit DC เพื่อบอก LCD Controller ว่าเป็นไบต์ที่จะส่งนั้น เป็นคำสั่ง หรือเป็นค่าพารามิเตอร์ สำหรับส่งคำสั่ง บิต DC จะต้องเป็นลอจิก 0 และสำหรับพารามิเตอร์ บิต DC จะต้องเป็น 1 เช่น ถ้าต้องการกำหนด ความเข้มของภาพ (contrast) จะต้องส่งคำสั่ง 0x25 ตามด้วย ค่าพารามิเตอร์ความสว่าง ในที่นี้กำหนดเป็น 0x3F

  สำหรับสัญญาณ CS (SCE ในรูป) ใช้กำหนดจังหวะการเริ่มต้นการส่งข้อมูล เพื่อให้ผู้ส่งและผู้รับ เข้าใจตรงกันว่าให้นับบิตไหนเป็นบิตแรก และแต่ละไบต์ สามารถส่งต่อเนื่องกันโดยที่ไม่ต้องหยุดการส่งข้อมูลแล้วเริ่มใหม่ โดยสามารถเริ่มต้นครั้งเดียวแล้วส่งคำสั่งตามด้วยค่าพารามิเตอร์ แล้วส่งคำสั่งถัดไปได้ทันที

ขั้นตอนการเขียนโปรแกรม ไมโครคอนโทรลเลอร์ติดต่อกับ GLCD Nokia 6100
     บทความนี้ ใช้ AVR Atmega16 เป็น MCU เชื่อมต่อกับจอ LCD และส่งข้อมูลแบบเป็น IO คือไม่ได้ใช้ SPI เนื่องจากส่งได้ 8 บิต (ไม่พอสำหรับ 9 บิต)

Download Source Code >> code_C.rar

สำหรับการเซ็ตค่าเริ่มต้น ให้กับจอ มีลำดับดังนี้

กำหนด #define ต่างๆ
#define CS0 Clrb(LCD_CS_PORT,LCD_CS_PIN)   //LCD_CS = 0
#define CS1 Setb(LCD_CS_PORT,LCD_CS_PIN)   //LCD_CS = 1
#define CSOUT Setb(LCD_CS_DPRT,LCD_CS_PIN)   //LCD_CS = output

#define SO0 Clrb(MOSI_PORT,MOSI_PIN)   //MOSI = 0
#define SO1 Setb(MOSI_PORT,MOSI_PIN)   //MOSI = 1
#define SOOUT Setb(MOSI_DPRT,MOSI_PIN)   //MOSI = output

#define CLK0 Clrb(SCK_PORT,SCK_PIN)   //SCK = 0
#define CLK1 Setb(SCK_PORT,SCK_PIN)   //SCK = 1
#define CLKOUT Setb(SCK_DPRT,SCK_PIN)   //SCK = output
#define CLKP CLK1; CLK0

 เริ่มการกำหนดค่าเริ่มต้น หลังจากทำการรีเซตจอ

 START();

 CMD(SLEEPOUT);      
 
CMD(NORON);

 CMD(COLMOD);
 DAT(0x02);    //กำหนดโหมดสีที่ใช้เป็น 256 สี    

 CMD(MADCTL);
 DAT(0x00);       

 CMD(SETCON);
 DAT(0x3F);   //Don’t set more than 0x3F

 STOP();

 Delay100ms(20);

 START();

 CMD(DISPON);

 STOP();

     จากนั้น เราก็จะสามารถแสดงภาพตามต้องการได้ จากที่เรากำหนด โหมดสีเป็นแบบ 8 บิตนั้น ใน 8 บิต ประกอบด้วยโทนสีแดง (R) 3 บิต สีเขียว (G) 3 บิต และสีน้ำเงิน (B) 2 บิต โดยเรียงลำดับจาก MSB ไปยัง LSB เป็น RGB ซึ่งจะเห็นว่าเราสามารถระบุโทนสีแดง และเขียวได้ 8 โทน กับอีก 4 โทนสำหรับสีน้ำเงิน นอกจากนี้ เราสามารถสลับโทนสีแดง กับน้ำเงินได้ เพื่อให้สามารถแสดงรายละเอียดสีน้ำเงินได้มากขึ้น การใส่สีให้กับพิกเซล คือ การกำหนด code สี ให้กับพิกเซล  เนื่องจากมี 8 บิต จึงสามารถแสดงได้ 256 สี การเขียน code สี ให้กับ pixel ก็คือการเขียน code สีลงไปในหน่วยความจำที่อยู่ใน LCD Controller จากนั้นในการแสดงผล LCD  Controller จะนำ code สี ที่แต่ละตำแหน่ง มาเปิดตารางดูว่า code หรือโทนของแต่ละสี เป็นระดับสีเท่าไร ใน 16 ระดับ (4 บิต สำหรับแต่ละสี) ซึ่งระดับ 0 ก็คือมืดที่สุด และระดับ 15 คือสูงที่สุด เช่น ถ้าเป็นองค์ประกอบสีแดง R = 15 ก็หมายถึงสีแดงสด ถ้า R = 0 คือสีดำ

     ดังนั้น สี 256 สี ที่เราสามารถแสดงได้ ก็คือ การเลือกสีมาจากสีทั้งหมด 16 x 16 x 16 = 4096 สี นั่นเอง โดยเราสามารถกำหนดตารางสี สำหรับแต่ละโทนได้โดยใช้คำสั่ง RGBSET แต่เนื่องจาก PCF8833 นั้นได้ทำการกำหนดค่าเริ่มต้นของตารางสีดังกล่าวไว้แล้ว จึงไม่จำเป็นต้องกำหนดใหม่

     สำหรับการเขียนค่าสีลงในหน่วยความจำของจอ PCF8833 ได้กำหนดวิธีการไว้คือ เราต้องกำหนดคอลัมน์เริ่มต้น คอลัมน์สุดท้าย แถวแรก และแถวสุดท้าย แล้วจึงเขียนลงในหน่วยความจำทีเดียวอย่างต่อเนื่อง โดยเมื่อเขียนจนจบแถวแรก ตำแหน่งแอดเดรส จะเลื่อนไปยังแถวถัดไปทางซ้ายสุดให้เอง ลองดูตัวอย่างการใส่สีให้กับจอทั้งจอ (132×132 pixel) ดังนี้ โดยในที่นี้เลือกใส่สีน้ำเงิน

 START();

 CMD(CASET);
 DAT(sx);     //กำหนดคอลัมน์แรกที่จะเขียนลงใน memory
 DAT(ex);    //กำหนดคอลัมน์สุดท้ายที่จะเขียนลงใน memory
 
 CMD(PASET);
 DAT(sy);     //กำหนดแถวแรกที่จะเขียนลงใน memory
 DAT(ey);    //กำหนดแถวสุดท้ายที่จะเขียนลงใน memory

 CMD(RAMWR);    //เขียนข้อมูลลงใน memory
 for (i = 0; i < ((ex-sx+1) * (ey-sy+1)); i++) 
 {
  DAT(color);   //เขียนข้อมูลที่เป็นสี 8 บิต ลงใน memory
 }

 STOP();

    

จากรูป คือการเขียนข้อมูลลงในหน่วยความจำ เมื่อกำหนดคอลัมน์เริ่มต้น คอลัมน์สุดท้าย แถวแรก และแถวสุดท้าย เป็น xs, xe, ys ,ye ตามลำดับ (รูปนำมาจาก datasheet ของ PCF8833)

แนะนำโปรแกรมช่วยให้คุณเข้าใจการแสดงผลภาพ
     คราวนี้เราถ้าเราต้องการนำภาพจากในคอมของเรามาแสดงบนจอ LCD 6100 ในที่นี้จะใช้การสร้าง .h ไฟล์ มาเพื่อเก็บภาพไว้ในหน่วยความจำโปรแกรมของ Atmega16 ก่อนอื่น เราก็ต้องสร้างไฟล์ .h ก่อน โดยทาง ThaiEasyElec.com ได้เขียนโปรแกรมด้วยภาษา C# สำหรับสร้างไฟ .h จาก .bmp ให้ใช้งานง่ายๆ ดังนี้

โปรแกรมมีชื่อว่า bmp2h_conv เมื่อเปิดโปรแกรมขึ้นมา ให้ท่านกด Load เพื่อโหลดภาพ .bmp .jpg หรือ .jpeg

Download bmp2h_conv >> bmp2h_conv v2.0.rar 
Download bmp2h_conv เพื่อการพัฒนาต่อด้วย C#.net  >> Cdotnet.rar

เมื่อ Load มาแล้ว ช่อง From จะแสดงรายละเอียดของภาพ ท่านสามารถกำหนดขนาดของภาพที่ท่านต้องการแสดงได้ที่ช่อง width และ height จากนั้นสามารถใช้ mouse เลื่อนกรอบภาพได้
     เมื่อเลือกขนาดและบริเวณที่ต้องการได้แล้ว ก็กด Generate เพื่อสร้างไฟล์ .h  ก็จะได้ไฟล์ที่มีรูปแบบดังนี้

//############################################
// bmp to header file convertor version 1.0
// Author : www.ThaiEasyElec.com
//############################################
// source bmp file : C:\Documents and Settings\Pe\Desktop\ThaiEaysElecLPic132x132.bmp
// source pixel dept : 32
// target name : C:\Documents and Settings\Pe\Desktop\bmp2h_conv_pic\lcd132x96.h
// target pixel dept : 8
// target width : 132
// target height : 96
// ############################################
uint8_t lcd132x96[] PROGMEM = 
{
 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, …

นำไฟล์ไป include ใน Project แล้ว compile ได้ทันที

จากนั้นการแสดงภาพจากหน่วยความจำโปรแกรม สามารถเขียนได้ดังนี้

 START();

 CMD(CASET);
 DAT(0);
 DAT(131);
 
 CMD(PASET);
 DAT(0);
 DAT(95);

 CMD(RAMWR);
 for (i = 0; i < 132*96; i++) 
 { 
  DAT(pgm_read_byte(&lcd132x96));
 }

 STOP();
 
เมื่อ Build Project และโปรแกรมใส่ MCU ก็จะได้ภาพดังนี้

ในตัวอย่างใช้ขนาดภาพ 132×96 เนื่องจาก Atmega16 มีหน่วยความจำโปรแกรม 16K จึงต้องเหลือที่ไว้สำหรับเก็บ code อื่นๆ ไว้ถ้าโอกาสหน้าสามารถอ่านภาพที่เก็บใน SD Card ได้แล้ว จะเขียนมาใหม่ครับ

Link น่าสนใจ
– โปรแกรมแปลงภาพ Bitmap เป็น HEX file – สร้างจาก C# code
– Download symbol และ footprint
– C Code for LCD Nokia 6100
– LCD Info วิธีการเลือกจอ LCD 6100 Nokia ของต่างประเทศ
– Tutorial for LCD 6100 Nokia with an ATMEL AVR (PCF8833 Phillips)
– บทความ ภาษาไทย LCD 6100 with mcu 8 bits (PCF8833 Phillips)
– Controlling a Nokia 6100 Display with an Atmel-AVR (Epson S1D15G10)
– Example Code จาก Sparkfun
– How to Nokia LCD 6100 <= โปรแกรมแปลงภาพ Bitmap เป็น HEX File
– Datasheet Phillips PCF8833 
– Datasheet Epson S1D15G10

Thanks a lot….
     ขอขอบคุณ ฝรั่ง นาย เจมส์ พี ลินช์ (Mr. James P. Lynch) จาก Ebook เรื่อง Nokia 6100 LCD Display Driver ซึ่ง เขียนเกี่ยวกับการควบคุมจอ Nokia 6100 ด้วย ARM 7 ของ atmel โดยใช้บอร์ดของ olimex และ Sparkfun.com

     บทความนี้ หากพบว่ามีข้อผิดพลาดอย่างไร สามารถแจ้ง ThaiEasyElec แก้ไขปรับปรุงได้ครับ ร่วมกันช่วยพัฒนาวงการอิเล็กทรอนิกส์ในบ้านเรา ให้สู้ต่างประเทศได้กันเถอะครับ 

     หากท่านใดมีข้อสงสัยเพิ่มเติม e-mail มาถามได้ครับ โดยกรอกแบบฟอร์มด้านล่าง หรือเข้าไปที่ Contact Us ในบทความต่อไป จะมีเรื่องราว Reviewed อุปกรณ์อิเล็กทรอนิกส์ อีกครับ วันนี้ www.ThaiEasyElec.com  ขอจบบทความ GLCD Nokia 6100 เพียงเท่านี้ครับ