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とディスプレイの配線を見直して最高速を目指そうと思う。