aitendoのTFT液晶モジュール[ZY-FGD1442701V1]を購入しました。USB-シリアル変換チップFT245RLを使い、パソコンから液晶モジュールに絵を表示しましたので紹介します。
一方で、難易度はかなり上がりますが、CPLDとSDカードを使って動画を表示する方法は以下の記事を参考にしてください。
- aitendoのTFT液晶モジュールZY-FGD1442701V1, ST7735をMAX II CPLDで駆動
- aitendoのTFT液晶モジュールにCPLDを使って動画を表示する
- 液晶とSDカード、CPLD、水晶を基板にまとめました。
- CPLDで、SDカード(Ver.1)とSPIモードで通信(初期化まで)
購入先のリンク
http://www.aitendo.co.jp/product/1621 (900円)
http://www.aitendo.co.jp/product/1707(基盤実装済み:1200円)
(価格はどちらも2009/11/08現在)
データシート&サンプルプログラムが上記リンクからダウンロードできます!
仕様
128*128dots 1.44inch(~3x3cm)
色数 65k色 (RGB 5,6,5bits)
携帯電話用
まさに少し前のバー型携帯電話に使われていた画面みたいな、手頃なサイズの液晶です。単電源3Vで動きますので、乾電池2本とかUSBバスパワーをレギュレートしたものが使え、高電圧や負電圧は必要ありません。
LCDコントローラはST7735。
SPI制御も出来るコントローラだが、シリ/パラ切り替えのピンが外に出てないので、パラレル制御(8bit)をするしかない。高速書き換えの為にはこちらの方が有利ですし、シリアル転送したいなら74HC164を使えばいいでしょう。
このコントローラに表示用バッファRAMが入っており、液晶に絵を表示するにはRAMへデータを書き込むだけでよい。表示のリフレッシュなどはコントローラがやってくれる。そのため秋月300円液晶のように、”クロックを送り続けないと液晶が死ぬ”ということはない。
単電源3.0Vでよくて、制御しやすいコントローラ付きで、仕様が分かっていて(重要)、0.8mmという接続しやすいインタフェースで、900円(現在)というのはなかなかお買い得だと思います。128×128というサイズは小さいですが、趣味で使うにはお手頃でいいと思います(サイズが大きすぎるとメモリが足りなくなる関係で)。
ピン配置
pin | (W-)FGD1442701V1 | ST7735 | 備考 |
9 | RSTB | RESX | リセット |
5 | CS0 | CSX | チップ選択。low enable。(以下のピンの入力を受け付けるか否か) |
6 | CD | D/CX | データ表示/コマンド-選択 |
7 | RD | RDX | 読み込み有効。使わない場合はVDDIかDGNDに固定 |
8 | WR | WRX | ライト有効 |
24,22,20,18,16,14,12,10 | D[8:0] | D[8:0] | データ |
(P.12)←ページ数はデータシートのページに対応。
インタフェスピン電圧は3.3V max. 4.6Vが絶対定格。バックライト用LEDがあるのでmin電圧が3.0Vとして、実質3.0-3.3Vの間で選択することになる。
チップの消費電流は1mA以下。バックライトLEDと比べたら無視できる量か。
(P.18,20)
タイミング
基本は、DCX 1/0 -> CSX 0 -> WRX 0 -> D[7:0] -> WRX 1-> CSX 1。
すなわち、
- DCXでデータ1かコマンド0かを選ぶ。チップ選択CSXを有効0(low enable)にする。
- WRX 0にし、D[7:0]に書き込み準備をする。WRX 1で書き込みをかける(立ち上がりで読まれる)。
- CSXを1にして終了。
CSXはenable(0)にしっぱなしでもDCXの切り替えは有効であるので、継続してデータを送るときはenableのままでいい。
書き込みに限れば、各ピン切り替えには50ns以上かければ、タイミング特性を満たすか。5*10^-8sec = 20MHz。10MHz駆動のAVRだとwaitなしでいけそう。それでも書き換えレートはまともな値となりそう
(~10MHz/(128bits*128bits*100clock)=10Hz)。
FT245RLは内部クロックが12MHz = 1/(83nsec)ですから、これもウェイトがいりません。
(P.21)
色データの送り方
Rnをnピクセル目のR(赤)データとする。これは仕様書P37,38のチャートを見ていただいた方がわかりやすそうな。
- 12bit,RGB 4-4-4bit, 3AH=”03h”:
command”2C” -> data”R1[3:0]G1[3:0]” -> data”B1[3:0]R2[3:0]” -> data”G2[3:0]B2[3:0]” ->…
- 16bit,RGB 5-6-5bit, 3AH=”05h”:
command”2C” -> data”R1[4:0]G1[5:3]” -> data”G1[2:0]B1[4:0]” -> data”R2[4:0]G2[5:3]” ->…
(P37,38)
リセット
RESX を10us以上0(low enable)にし、1に戻す。120ms以上待つ。
(P.71)
コマンドリスト
P76-78, 118-121
SWRESET 01h: Software reset
SLPOUT 11h: Sleep out & booster on(起動時スリープinなので、outせねばならない。)
RAMWR 2Ch: Memory write(データ書き込み)
COLMOD 3Ah: Interface pixel format(データ転送を16bitにするか12bitにするか)
実際の制御方法の理解にはaitendoさんのところで公開されているサンプルコードが役に立ちます。
http://aitendo2.sakura.ne.jp/aitendo_data/product_img2/product_img/panel/ZY-FGD1442701V1/demo/144demo.C
以下、自分が理解しやすいようこのコードに勝手にコメントをつけたものです。
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit CS=P3^2;
sbit A0=P3^3;
sbit RDB=P3^4;
sbit WRB=P3^5;
sbit RES=P3^7;
sbit key=P3^0;
uchar code colorc[]=
{0xf8,0x00,0x07,0xe0,0x00,0x1f,0xff,0xe0,0x1f,0xff,0x00,0x00,0xff,0xff};
void delay20us()
{
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
}
void WriteCOM(unsigned char a)
{
CS=0;// CSX
A0=0;// D/CX
P1=a;// D[7:0]
WRB=0;// WRX
delay20us();
WRB=1;// WRX
CS=1;// CSX
}
void WriteDAT(unsigned char b)
{
CS=0;
A0=1;
P1=b;
WRB=0;
delay20us();
WRB=1;
CS=1;
}
void delayms(uint ms)
{
uint i;
for(;ms!=0;ms--)
{for(i=200;i!=0;i--);}
}
main()
{
uchar i,j,k=0;
//RESET
RES=1;// RESX
delayms(100);
RES=0;
delayms(100);
RES=1;
delayms(120);
WriteCOM(0x01);//SOFTWARE RESET
delayms(50);
WriteCOM(0x11);//SLEEP OUT
delayms(200);
WriteCOM(0xFF);//VCOM4 level
WriteDAT(0x40);//TC2=4, TC1=0 clock delay
WriteDAT(0x03);//TC3=3 clock delay
WriteDAT(0x1A);
WriteCOM(0xd9);//EEPROM control status?
WriteDAT(0x60);//30h?
WriteCOM(0xc7);//Set VCOM offset control?
WriteDAT(0x90);// vmf = vmh (same as 10h)
delayms(200);
WriteCOM(0xB1);//Frame Rate Control(In normal mode/ Full colors)
//Frame rate= f_osc/((RTNA + 20)*(LINE+FPA+BPA))
WriteDAT(0x04);//RTNA = 4h
WriteDAT(0x25);//FPA=25h = 37
WriteDAT(0x18);//BPA=18h = 24
WriteCOM(0xB2);//Frame Rate Control (In Idle mode/ 8-colors)
WriteDAT(0x04);
WriteDAT(0x25);
WriteDAT(0x18);
WriteCOM(0xB3);//Frame Rate Control (In Partial mode/ full colors)
//1st parameter to 3rd parameter are used in line inversion mode.
WriteDAT(0x04);
WriteDAT(0x25);
WriteDAT(0x18);
//4th parameter to 6th parameter are used in frame inversion mode.
WriteDAT(0x04);
WriteDAT(0x25);
WriteDAT(0x18);
WriteCOM(0xB4);//Display Inversion Control(0:line inversion, 1:frame
inversion)
//[3:0] in full colors normal mode, in idle mode, in full colors partial mode (Partial mode on / Idle mode off)
WriteDAT(0x03);// 011
WriteCOM(0xB6);//Display Function set 5
WriteDAT(0x15);//NO=1,SDT=1,EQ=1 (default)
WriteDAT(0x02);//PTG=0,PT=2
WriteCOM(0xC0);// POWER CONTROL 1 GVDD&AVDD
WriteDAT(0x02);//4.7V (default)
WriteDAT(0x70);//1.0uA (default)
WriteCOM(0xC1);// POWER CONTROL 2 VGHH&VCLL
WriteDAT(0x07);// 14.7V, -12.25V
WriteCOM(0xC2);// POWER CONTROL 3 (in Normal mode/ Full colors)
WriteDAT(0x01);// (default)
WriteDAT(0x01);// (default)
WriteCOM(0xC3);// POWER CONTROL 4 (in Idle mode/ 8-colors)
WriteDAT(0x02);// (default)
WriteDAT(0x07);// (default)
WriteCOM(0xC4);// POWER CONTROL 5 (in Partial mode/ full-colors)
WriteDAT(0x02);// (default)
WriteDAT(0x04);// (default)
WriteCOM(0xFC);// POWER CONTROL 6 (in Partial mode + Idle mode)
WriteDAT(0x11);// (default)
WriteDAT(0x17);// 15h (default) -> 17h dcd
WriteCOM(0xC5);// VCOMH&VCOML
WriteDAT(0x3c);// 4V (default)
WriteDAT(0x4f);// 3a:-1.050V(default) -> 4f:-0.525V
WriteCOM(0x36);//Memory data access control
WriteDAT(0xC8);//MY-MX-MV-ML-RGB-MH-0-0 = 11001000 , (mirror xy, BGR)
WriteCOM(0x3a);//Interface pixel format
WriteDAT(0x05);//16bit mode
//GAMMA SET BY REGISTER
//***********************GAMMA*************************
WriteCOM(0xE0);// + polarity
WriteDAT(0x06);
WriteDAT(0x0E);
WriteDAT(0x05);
WriteDAT(0x20);
WriteDAT(0x27);
WriteDAT(0x23);
WriteDAT(0x1C);
WriteDAT(0x21);
WriteDAT(0x20);
WriteDAT(0x1C);
WriteDAT(0x26);
WriteDAT(0x2F);
WriteDAT(0x00);
WriteDAT(0x03);
WriteDAT(0x00);
WriteDAT(0x24);
WriteCOM(0xE1);// - polarity
WriteDAT(0x06);
WriteDAT(0x10);
WriteDAT(0x05);
WriteDAT(0x21);
WriteDAT(0x27);
WriteDAT(0x22);
WriteDAT(0x1C);
WriteDAT(0x21);
WriteDAT(0x1F);
WriteDAT(0x1D);
WriteDAT(0x27);
WriteDAT(0x2F);
WriteDAT(0x05);
WriteDAT(0x03);
WriteDAT(0x00);
WriteDAT(0x3F);
//***************************RAM ADDRESS*******************
WriteCOM(0x2A);//column address set
WriteDAT(0x00);//xs = 02h = 2
WriteDAT(0x02);
WriteDAT(0x00);//xe = 81h = 129
WriteDAT(0x81);
WriteCOM(0x2B);//row address set
WriteDAT(0x00);//ys = 03h = 3
WriteDAT(0x03);
WriteDAT(0x00);//ye = 82h = 130
WriteDAT(0x82);
WriteCOM(0x29);//display on
delayms(100);
WriteCOM(0x2C); //memory write
while(1)
{
for (i=0;i<128;i++)
{
for (j=0;j<128;j++)
{
WriteDAT(colorc[k]);
WriteDAT(colorc[k+1]); //display green
}
}
delayms(2000);
k+=2;
if(k>14)
k=0;
}
}
表示テスト
試行錯誤ののち、色を表示出来るようになりました。
使用した部品リスト。
- 秋月150円ブレットボード 1コ
- ZY-FGD1442701V1、基盤配線済み 1コ
- 黄色ケーブル(芯線が1本のもの。ブレッドボードでの使用に最適) 適宜
- FT245RL 1コ(usb-パラレル変換IC)
- 74HC164 1コ(シリアル・パラレル変換IC)
- 104積層セラミクコンデンサ =10^4pF
- 10uF電解コンデンサ
- USB Bコネクタ
配線は簡単に表すと、
パソコン -> USB -> FT245RL -> (74HC164 (D[7:0]のみ)) -> FGD1442701V1
FT245RL + 74HC164でデータはシリアル転送しています。FT245RLが3.3Vを出力してくれるので、それでLCDのLEDもすべて駆動しています。USBバスパワーだけで駆動出来るので楽です。
が、一枚表示するのに5-10分かかるんじゃないかという速度で、どうしたものかというところです。HD74HC164はtpd(clock to Q) = 14.5ns typで、今後ネックになりそうですが、今の速度のネックではなさそう。FT245RLのbitbangモードの転送速度,スループットが問題かなあと思っています。
->いま書き込みを1バイトずつしているのですが、これをまとめたら(バッファリングしたら)数十倍に高速化出来ました。->1281282*27bytes=884kBをまとめて送っても初期化(~2sec)含めて24secかかります・・。データ量からするとこれが限界ぽい気が。データ量を減らさないと。シリアル転送なので1コマンド送るのに27bytes使うというのが原因。
左から、赤線の表示、ALICE・ぱれーど、カタハネ。
16bitビットマップの扱いについて
絵を表示するために、gimpなどを使い16bit bitmapを作ります。コントローラが受け付けるのは、R-G-B = 5-6-5bitでGreenが一ビット多いのに対し、16bitビットマップはR,G,Bそれぞれ5bitですから、Greenの最上位ビットを0で埋めてやります。さらにbmpはリトルエンディアンなので、gggbbbbb 0rrrrrggという並びになっています(ネット上の情報では色々違いが有るようですがうちの場合はこれでした)。つまり、これをrrrrr0gg gggbbbbbrrrrrggg gg0bbbbbとして転送してやるわけです(Gの最大値が64なので、2倍してやります)。私は次のようにしているわけですが、ハッカーのなんとかという論理演算本を読むともっとトリッキーにかけると思われます。
//dat2 = ((dat2 & 0x7c) << 1) | (dat2 & 0x03); wrong
dat2 = (dat2 << 1) | (dat >> 7);
dat = ((dat & 0x60) << 1) | (dat & 0x1F);
なおヘッダは、パレット情報がない場合、35hまで詰まっているのでその部分はとばします。
コード
まだいろいろ書き換えていますが、末尾に現段階のコードを貼っておきます(gnu/linux+gcc)。上記のコードをそのまま移植したものです。ピン接続はdefineのところに。他のピンは、HC164-B=VCCIO,RESET=VCCIO, LCD-RDX=VCCIOです。VCCIO=3.3V。
(高速化といって書き換えたので、リセットコマンドが送れていませんが、とりあえず現段階のコードで・・。すみません)
-> LCDコントロラ初期化コマンドのところで、cで配列代入出来ないの忘れてて宣言のところで配列を初期化してひどいことに。まあ、うごくので、これでいいか・・。二枚の絵がぱたぱた入れ替わります。
電圧制御(power control)はデフォルトのままの方が発色がよい気がします。これは私が3.0でなく3.3V入力しているせいかもしれません。
完成?
表示速度が頭打ちですがこれ以上は、AVR+eeprom(2MB)とかでやるのがいいかなと思っています。
(んー?これは、、libftdi:ftdi.c
int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate);)
ftdi_set_baudrate(ftdic, 921600);
を追記したら、1.5secでかけるようになった。
それでも表示速度が1枚1.5secで頭打ちですがこれ以上は、AVR+eeprom(2MB)とかでやるのがいいかなと思っています。
または、FT2232Lというデュアルパラレル変換ICを使えば、74HC164がいらなくなり、3/27=1/9の速度でかけることになりそうです。
#include <stdio.h>
#include <time.h> //nanosleep()
#include <unistd.h> //sleep()
#include <ftdi.h> //FTDI
#define DIN 0x01 // d0 HC164-A
#define DCLK 0x02 // d1 HC164-clock
// d2 nc 0x04
#define CSX 0x08 // d3 cs0
// d4 nc 0x10
#define RESX 0x20 // d5 lcd RESX
#define DCX 0x40 // d6 lcd DCX
#define WRX 0x80 // d7 lcd WRX
#define DATA_SIZE 128*128*2 //
#define CD_SIZE 27 //size of one command/data
int make_cd(unsigned char *stat, unsigned char dat,
unsigned char is_dat, unsigned char *buf);//buf > 27Bytes
int setb(unsigned char *stat, unsigned char pin, unsigned char enable);
int write_buf(struct ftdi_context *ftdic, unsigned char *buf, int size);
inline void nsleep(int nsec);
int lcd_init(struct ftdi_context *ftdic, unsigned char *stat);
struct timespec treq;
int colorc[] = {0x07,0x00,0x07,0xe0,0x00,0x1f,0xff,0xe0,0x1f,0xff,0x00,0x00,0xff,0xff};
int main(int argc, char **argv)
{
struct ftdi_context ftdic[1];
int f,i,j,k=0;
int l = 0;
FILE *fp;
unsigned char dat, dat2;
unsigned char stat[1]; //status buffer
unsigned char dbuf[DATA_SIZE][CD_SIZE]; //data buffer
unsigned char cbuf[CD_SIZE]; //one command buffer
char* files[] = {"kat16.bmp", "img16.bmp"};
ftdi_init(ftdic); //FTDI init
f = ftdi_usb_open(ftdic, 0x0403, 0x6001); //FTDI open
if(f < 0 && f != -5) { //5 is ftdi_sio error
fprintf(stderr, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdic));
exit(-1);
}
printf("ftdi open succeeded: %d\n",f);
printf("enabling bitbang mode\n");
ftdi_enable_bitbang(ftdic, 0xFF); //all bits are bitbang
nsleep(200*1000*1000);
lcd_init(ftdic, stat);//LCD init
make_cd(stat, 0x2C, 0, cbuf); //memory write
write_buf(ftdic, cbuf, CD_SIZE);
while(1){
l = 1 - l;
if((fp = fopen(files[l], "rb")) == NULL){
printf("file open error.\n");
exit(EXIT_FAILURE);
}
for(i=0; i<0x36; i++){
getc(fp);
}
/* while(1){
for (i = 0; i < 128; i++){
printf("i : %d\n", i);
for (j = 0; j < 128; j++){
write_cd(ftdic, stat, colorc[k], 1);
write_cd(ftdic, stat, colorc[k+1], 1);
}
}
nsleep(2000*1000*1000);
k += 2;
if(k > 14){
k=0;
}
}*/
//gggbbbbb 0rrrrrgg -> rrrrr0gg gggbbbbb?
//rrrrrggg gg0bbbbb?
for(i=0; i<DATA_SIZE/2; i++){
dat = getc(fp);dat2 = getc(fp);
//dat2 = ((dat2 & 0x7c) << 1) | (dat2 & 0x03) ;
dat2 = (dat2 << 1) | (dat >> 7);
dat = ((dat & 0x60) << 1) | (dat & 0x1F);
make_cd(stat, dat2, 1, dbuf[2*i]);
make_cd(stat, dat, 1, dbuf[2*i+1]);
}
write_buf(ftdic, (unsigned char*)dbuf, DATA_SIZE * CD_SIZE);
fclose(fp);
/* while(1){
printf("end\n");
sleep(60);
}*/
printf("end\n");
}
setb(stat, CSX, 1);//data pins disenable
write_buf(ftdic, stat, 1);
printf("disabling bitbang mode\n");
ftdi_disable_bitbang(ftdic); //bitbang end
ftdi_usb_close(ftdic); //close device
ftdi_deinit(ftdic);
return 0;
}
int make_cd(unsigned char *stat, unsigned char dat,
unsigned char is_dat, unsigned char *buf){ //buf > 27Bytes
int i;
// setb(ftdic, stat, CSX, 0);
setb(stat, DCX, is_dat);
buf[0] = *stat;
setb(stat, WRX, 0);
buf[1] = *stat;
//D[7:0]
for(i=0; i<8; i++){
setb(stat, DCLK, 0);
buf[3*i+2] = *stat;
setb(stat, DIN, ((dat >> (7-i)) % 2));
buf[3*i+3] = *stat;
setb(stat, DCLK, 1);
buf[3*i+4] = *stat;
}
setb(stat, WRX, 1);
buf[26] = *stat;
// setb(ftdic, stat, CSX, 1);
return 0;
}
int setb(unsigned char *stat, unsigned char pin, unsigned char enable){
if(enable == 1){
*stat |= pin;
}else{
*stat &= ~pin;
}
return 0;
}
int write_buf(struct ftdi_context *ftdic, unsigned char *buf, int size){
int f;
f = ftdi_write_data(ftdic, buf, size);
if(f < 0) {
fprintf(stderr,"write failed for 0x%x, error %d (%s)\n",buf[0],f, ftdi_get_error_string(ftdic));
return 1;
}
// nsleep(50);
return 0;
}
inline void nsleep(int nsec){
treq.tv_sec = (time_t)0;
treq.tv_nsec = nsec;//200 * 1000 * 1000;//mun
nanosleep(&treq, NULL);
}
int lcd_init(struct ftdi_context *ftdic, unsigned char *stat){
unsigned char cbuf[27];
unsigned char cbufs[100][27];
// unsigned char cmd[100][2];
int cmdsize, i;
unsigned char vcomcmd[][2] = {
{0xFF, 0},//VCOM4 level
{0x40, 1},//TC2=4, TC1=0 clock delay
{0x03, 1},//TC3=3 clock delay
{0x1A, 1},
{0xd9, 0},//EEPROM control status
{0x30, 1},//30h
{0xc7, 0},//Set VCOM offset control
{0x10, 1},// vmf = vmh (same as 10h)
};
unsigned char cmd2[][2] = {
{0xB1, 0},//Frame Rate Control(In normal mode/ Full colors)
//Frame rate= f_osc/((RTNA + 20)*(LINE+FPA+BPA))
{0x04, 1},//RTNA = 4h
{0x25, 1},//FPA=25h = 37
{0x18, 1},//BPA=18h = 24
{0xB2, 0},//Frame Rate Control (In Idle mode/ 8-colors)
{0x04, 1},
{0x25, 1},
{0x18, 1},
{0xB3, 0},//Frame Rate Control (In Partial mode/ full colors)
//1st parameter to 3rd parameter are used in line inversion mode.
{0x04, 1},
{0x25, 1},
{0x18, 1},
//4th parameter to 6th parameter are used in frame inversion mode.
{0x04, 1},
{0x25, 1},
{0x18, 1},
{0xB4, 0},//Display Inversion Control(0:line inversion, 1:frame inversion)
//[3:0] in full colors normal mode, in idle mode, in full colors partial mode (Partial mode on / Idle mode off)
{0x07, 1},// 011
{0xB6, 0},//Display Function set 5
{0x15, 1},//NO=1,SDT=1,EQ=1 (default)
{0x02, 1},//PTG=0,PT=2
{0xC0, 0},// POWER CONTROL 1 GVDD&AVDD
{0x02, 1},//4.7V (default)
{0x70, 1},//1.0uA (default)
{0xC1, 0},// POWER CONTROL 2 VGHH&VCLL
{0x07, 1},// 14.7V, -12.25V
{0xC2, 0},// POWER CONTROL 3 (in Normal mode/ Full colors)
{0x01, 1},// (default)
{0x01, 1},// (default)
{0xC3, 0},// POWER CONTROL 4 (in Idle mode/ 8-colors)
{0x02, 1},// (default)
{0x07, 1},// (default)
{0xC4, 0},// POWER CONTROL 5 (in Partial mode/ full-colors)
{0x02, 1},// (default)
{0x04, 1},// (default)
{0xFC, 0},// POWER CONTROL 6 (in Partial mode + Idle mode)
{0x11, 1},// (default)
{0x17, 1},// 15h (default) -> 17h dcd
{0xC5, 0},// VCOMH&VCOML
{0x3c, 1},// 4V (default)
{0x4f, 1},// 3a:-1.050V(default) -> 4f:-0.525V
{0x36, 0},//Memory data access control
{0x88, 1},//MY-MX-MV-ML-RGB-MH-0-0 = 11001000 , (mirror xy, BGR)
{0x3a, 0},//Interface pixel format
{0x05, 1},//16bit mode
};
unsigned char gamma[][2] = {// + polarity
{0xE0, 0},
{0x06, 1},
{0x0E, 1},
{0x05, 1},
{0x20, 1},
{0x27, 1},
{0x23, 1},
{0x1C, 1},
{0x21, 1},
{0x20, 1},
{0x1C, 1},
{0x26, 1},
{0x2F, 1},
{0x00, 1},
{0x03, 1},
{0x00, 1},
{0x24, 1},//17
{0xE1, 0},// - polarity
{0x06, 1},
{0x10, 1},
{0x05, 1},
{0x21, 1},
{0x27, 1},
{0x22, 1},
{0x1C, 1},
{0x21, 1},
{0x1F, 1},
{0x1D, 1},
{0x27, 1},
{0x2F, 1},
{0x05, 1},
{0x03, 1},
{0x00, 1},
{0x3F, 1},
};
unsigned char ramad[][2] = {
{0x2A, 0},//column address set
{0x00, 1},//xs = 02h = 2
{0x02, 1},
{0x00, 1},//xe = 81h = 129
{0x81, 1},
{0x2B, 0},//row address set
{0x00, 1},//ys = 03h = 3
{0x03, 1},
{0x00, 1},//ye = 82h = 130
{0x82, 1},
};
// init state (WRX=0,DCX=0,RESX=0,CSX=1,DCLK=0,DIN=0)
printf("init WRX=0,DCX=0,RESX=0,CSX=1,DCLK=0,DIN=0\n");
*stat = 0x00 | CSX;
write_buf(ftdic, stat, 1);
// reset
printf("RESET...\n");
setb(stat, RESX, 1);
write_buf(ftdic, stat, 1);
nsleep(50*1000*1000);
setb(stat, RESX, 0);
write_buf(ftdic, stat, 1);
nsleep(50*1000*1000);
setb(stat, RESX, 1);
write_buf(ftdic, stat, 1);
nsleep(120*1000*1000);// wait for more than 120ms
//data pins enable
setb(stat, CSX, 0);
write_buf(ftdic, stat, 1);
// software reset
make_cd(stat, 0x01, 0, cbuf);
write_buf(ftdic, cbuf, CD_SIZE);
nsleep(100*1000*1000);
//sleep out
printf("sleep out\n");
make_cd(stat, 0x11, 0, cbuf);
write_buf(ftdic, cbuf, CD_SIZE);
nsleep(100*1000*1000);
make_cd(stat, 0x28, 0, cbuf);//display off
write_buf(ftdic, cbuf, CD_SIZE);
//vcom
cmdsize = sizeof(vcomcmd)/sizeof(vcomcmd[0]);
for(i=0; i<cmdsize; i++){
make_cd(stat, vcomcmd[i][0], vcomcmd[i][1], cbufs[i]);
}
write_buf(ftdic, (unsigned char*)cbufs, cmdsize * CD_SIZE);
nsleep(200*1000*1000);
//cmd2
cmdsize = sizeof(cmd2)/sizeof(cmd2[0]);
for(i=0; i<cmdsize; i++){
make_cd(stat, cmd2[i][0], cmd2[i][1], cbufs[i]);
}
write_buf(ftdic, (unsigned char*)cbufs, cmdsize * CD_SIZE);
//GAMMA SET BY REGISTER
//***********************GAMMA*************************
printf("gamma set\n");
cmdsize = sizeof(gamma)/sizeof(gamma[0]);
for(i=0; i<cmdsize; i++){
make_cd(stat, gamma[i][0], gamma[i][1], cbufs[i]);
}
write_buf(ftdic, (unsigned char*)cbufs, cmdsize * CD_SIZE);
//***************************RAM ADDRESS*******************
printf("set ram address\n");
cmdsize = sizeof(ramad)/sizeof(ramad[0]);
for(i=0; i<cmdsize; i++){
make_cd(stat, ramad[i][0], ramad[i][1], cbufs[i]);
}
write_buf(ftdic, (unsigned char*)cbufs, cmdsize * CD_SIZE);
printf("display on\n");
make_cd(stat, 0x29, 0, cbuf);//display on
write_buf(ftdic, cbuf, CD_SIZE);
nsleep(50*1000*1000);
return 0;
}
突然で申し訳ありませんが今、そのカラーLCDを動かそうと試みているのですが砂嵐が表示されてしまいます。beizさんは何が原因で砂嵐が表示されたんでしょうか?(読みにくい構文申し訳ありません)
事が解決したのでお返事頂けなくても大丈夫です。このブログとても参考になりました。ありがとうございます!
事が解決したのでお返事頂けなくても大丈夫です。このブログとても参考になりました。ありがとうございます!