4インチ 800x480ピクセル 液晶ディスプレイ DUEで動かす
前回はこの液晶ディスプレイとArduino MEGA2560をつないでサンプルプログラムを動かしてみた。 約6秒くらいで処理が終わる結果に。
詳しくは前回記事を参照
Arduino MEGA2560とArduino DUEは、ポートの数や位置は全く一緒である。
てなもんだから、この液晶ディスプレイをDUEに繋げることも可能だ。
だがしかし、ポートの位置が同じだからと言ってもハードウェア的には全くの別物なので、プログラムはDUE用に書き直さなければならない。 それに、SPI通信インターフェースの位置も違うので、SDカードやタッチパネルは使う事ができない。
DUE用のプログラムは以下に掲載する。
基本は変わらない。 変わっているのはデータを液晶ディスプレイに転送している所だけだ。
void Lcd_Write_Bus(unsigned int d) { REG_PIOA_CODR = 0x0000c080; REG_PIOB_CODR = 0x04000000; REG_PIOC_CODR = 0x0000003e; REG_PIOD_CODR = 0x0000064f; REG_PIOC_SODR = d << 5 & 1 << 5; //D0 REG_PIOC_SODR = d << 3 & 1 << 4; REG_PIOC_SODR = d << 1 & 1 << 3; REG_PIOC_SODR = d >> 1 & 1 << 2; REG_PIOC_SODR = d >> 3 & 1 << 1; REG_PIOD_SODR = d << 5 & 1 << 10; REG_PIOA_SODR = d << 1 & 1 << 7; REG_PIOD_SODR = d << 2 & 1 << 9; //D7 REG_PIOB_SODR = d << 18 & 1 << 26; //D8 REG_PIOA_SODR = d << 5 & 1 << 14; REG_PIOA_SODR = d << 5 & 1 << 15; REG_PIOD_SODR = d >> 11 & 1 << 0; REG_PIOD_SODR = d >> 11 & 1 << 1; REG_PIOD_SODR = d >> 11 & 1 << 2; REG_PIOD_SODR = d >> 11 & 1 << 3; //D14 REG_PIOD_SODR = d >> 9 & 1 << 6; //D15 REG_PIOC_CODR = 1 << 7; REG_PIOC_SODR = 1 << 7; } void Lcd_Write_Com(unsigned int VH) { REG_PIOC_CODR = 1 << 6; Lcd_Write_Bus(VH); } void Lcd_Write_Data(unsigned int VH) { REG_PIOC_SODR = 1 << 6; Lcd_Write_Bus(VH); } void Lcd_Write_Com_Data(unsigned int com,unsigned int dat) { Lcd_Write_Com(com); Lcd_Write_Data(dat); } void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2) { Lcd_Write_Com(0x2a00); Lcd_Write_Data(x1>>8); Lcd_Write_Com(0x2a01); Lcd_Write_Data(x1); Lcd_Write_Com(0x2a02); Lcd_Write_Data(x2>>8); Lcd_Write_Com(0x2a03); Lcd_Write_Data(x2); Lcd_Write_Com(0x2b00); Lcd_Write_Data(y1>>8); Lcd_Write_Com(0x2b01); Lcd_Write_Data(y1); Lcd_Write_Com(0x2b02); Lcd_Write_Data(y2>>8); Lcd_Write_Com(0x2b03); Lcd_Write_Data(y2); Lcd_Write_Com(0x2c00); } void Lcd_Init(void) { digitalWrite(41, HIGH); delay(10); digitalWrite(41, LOW); delay(100); digitalWrite(41, HIGH); delay(50); digitalWrite(40, HIGH); digitalWrite(39, HIGH); digitalWrite(40, LOW); delay(50); Lcd_Write_Com(0x2800); Lcd_Write_Com(0x3600); Lcd_Write_Data(0x00); Lcd_Write_Com(0x3a00); Lcd_Write_Data(0x55); Lcd_Write_Com(0x1100); delay(120); Lcd_Write_Com(0x2900); } void H_line(unsigned int x, unsigned int y, unsigned int l, unsigned int c) { unsigned int i, j; REG_PIOC_CODR = 1 << 8; l = l + x; Address_set(x, y, l, y); j = l * 2; for(i = 1; i <= j; i++) Lcd_Write_Data(c); REG_PIOC_SODR = 1 << 8; } void V_line(unsigned int x, unsigned int y, unsigned int l, unsigned int c) { unsigned int i, j; REG_PIOC_CODR = 1 << 8; l = l + y; Address_set(x, y, x, l); j = l * 2; for(i = 1; i <= j; i++) Lcd_Write_Data(c); REG_PIOC_SODR = 1 << 8; } void Rect(unsigned int x,unsigned int y,unsigned int w,unsigned int h,unsigned int c) { H_line(x , y , w, c); H_line(x , y+h, w, c); V_line(x , y , h, c); V_line(x+w, y , h, c); } void LCD_Clear(unsigned int j) { unsigned int i, m; REG_PIOC_CODR = 1 << 8; Address_set(0, 0, 479, 799); for(i = 0; i < 480; i++) for(m = 0; m < 800; m++) Lcd_Write_Data(j); REG_PIOC_SODR = 1 << 8; } void setup() { Serial.begin(9600); pinMode(22, OUTPUT); pinMode(23, OUTPUT); pinMode(24, OUTPUT); pinMode(25, OUTPUT); pinMode(26, OUTPUT); pinMode(27, OUTPUT); pinMode(28, OUTPUT); pinMode(29, OUTPUT); pinMode(30, OUTPUT); pinMode(31, OUTPUT); pinMode(32, OUTPUT); pinMode(33, OUTPUT); pinMode(34, OUTPUT); pinMode(35, OUTPUT); pinMode(36, OUTPUT); pinMode(37, OUTPUT); pinMode(38, OUTPUT); pinMode(39, OUTPUT); pinMode(40, OUTPUT); pinMode(41, OUTPUT); pinMode(43, OUTPUT); digitalWrite(38, HIGH); digitalWrite(39, HIGH); digitalWrite(40, HIGH); digitalWrite(41, HIGH); digitalWrite(43, HIGH); Lcd_Init(); } void loop() { unsigned long start = micros(); LCD_Clear(0xFFFF); LCD_Clear(0x0000); LCD_Clear(0xf800); LCD_Clear(0x07E0); LCD_Clear(0x001F); for(int i = 0; i < 300; i++) Rect(random(400), random(400), random(800), random(800), random(65535)); Serial.println(micros() - start); }
実行するとわかるが、だいたい6秒ちょっとで処理が終わる。 つまりMEGAとほぼ同等か若干遅い。
DUEにはかなり速いMPUが搭載されているのに、MEGAと同等とはこれいかに。 と思うかもしれないが、理由は簡単。 今までにもさんざん言ってきたLcd_Write_Bus関数の行数が多いから。
次回は、DUEとディスプレイの配線を見直して最高速を目指そうと思う。