ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【原理】从零编写ILI9341驱动全过程(基于Arduino)

2020-01-12 23:00:39  阅读:383  来源: 互联网

标签:Pin Arduino digitalWrite LcdWriteCommand LcdWriteData LCD 全过程 ILI9341 define


最近在淘宝入手了一块ILI9341彩色屏幕,支持320x240分辨率。之前一直很好奇这类单片机驱动的彩色屏幕的原理,就打算自己写一个驱动,从电流层面操控ILI9341屏幕。话不多说,我们开始吧( ̄▽ ̄)~*

1.ILI9341芯片和ILI9341驱动板

首先这里要明确两个概念,ILI9341芯片和ILI9341驱动板。

ILI9341芯片是ilitek发布的液晶驱动芯片,是这个样子的:

而淘宝上的ILI9341驱动板是把ILI9341芯片、屏幕和针脚焊接在一起的电路板,它可能是这个样子的:

 

也可能是这个样子的:

 

 还可能是这个样子的:

 

没错,不同的厂家可以制造不同形状,不同接口的ILI9341驱动板,但他们上面都有ILI9341芯片,所以我们可以用相同的方法操作它。

2.如何操作它呢?

这是ILI9341驱动板的背面,我在上面做了些标注,应该会方便理解些。我们只要控制这些针脚的通电与否(高电平与低电平),就能够获得操控这块屏幕的“完整权限”!那这些针脚的定义是什么呢?我们一个一个看:

左上角有五个最重要的针脚,分别是LCD_RST、LCD_CS、LCD_RS、LCD_WR和LCD_RD:(直接用文字写不能冒号对齐,没办法,开个代码框( ̄▽ ̄)~*)

LCD_RST : 即LCD Reset,用于在通电之后复位,初始化整个模块。

LCD_CS  : 即LCD Chip Select,用于多个芯片之间的片选操作。由于这块驱动板只有一个可用的芯片,所以一般该针脚不通电。

LCD_RS  : 又称D/CX信号线,用于切换写命令(Command)和写数据(Data),当对显示屏写命令(Command)时,应该让针脚不通电,当对显示屏写数据(Data)时,应该让针脚通电。

LCD_WR  : 写使能。当LCD_WR不通电,并且LCD_RD通电时,数据传输方向为写入。

LCD_RD  : 读使能。

左下角的针脚负责供电,不细讲。

右上角的LCD_D0到LCD_D7是数据脚,通过控制它的通电与否来传输8个比特,也就是8个0或1。这种方式可以传输一个最小值0,最大值255的数字,我们用它来传输所有命令和数据。

右下角的SD_SS,SD_DI,SD_D0,SD_SCK适用于控制SD卡读写的,不属于ILI9341的范畴,我们先不讨论。

那么,如何操作它呢?这张图能够很清楚的说明:(下面用拉低代表示不通电,拉高表示通电,这样术语会更加标准)

 

  • 单片机开机,ILI9341驱动板接收到电流,开始进入待命状态
  • 拉低LCD_CS片选信号,选择对ILI9341芯片发送命令
  • 通过拉高拉低LCD_D0到LCD_D7数据脚,来表示二进制数据
  • 拉低拉高LCD_RS针脚来告诉机器这是一个命令,还是一个数据
  • 拉低LCD_WR,进行写使能(可以理解为按下回车键,把LCD_D0到D7的数据发送出去)

这就是发送一个命令或者数据的方法。二进制,十进制和十六进制的转换和表达先直接略过,如果要展开,那可能可以出一本书了( • ̀ω•́ )✧,关于LCD_D0到D7脚应该发送什么,ILITEK在设计ILI9341时就已经规定好了,中文文档在此:

接下来,就是,愉快的,编码时间啦( • ̀ω•́ )✧!!!

3.兼容性设定

不知刚才你有没有注意到数据脚是从LCD_D2开始的?那是因为Arduino Uno开发板的第0和1脚是USB针脚,不能被使用,只能从第2个针脚开始设计:

那我们在编程时要用到LCD_D0和LCD_D1时,就必须写成8和9。另外不同机器脚位也不一样,所以我用宏定义来简化程序:

#define LCD_D0   8
#define LCD_D1   9
#define LCD_D2   2
#define LCD_D3   3
#define LCD_D4   4
#define LCD_D5   5
#define LCD_D6   6
#define LCD_D7   7
#define LCD_RD   A0
#define LCD_WR   A1
#define LCD_RS   A2
#define LCD_CS   A3
#define LCD_RST  A4

这样即解决了LCD_D0和LCD_D1脚的问题,还搞定的不同开发板的兼容性问题。由于#define是在预编译阶段生成的,所以不会影响代码运行的速度。

4.发送命令和数据

调用这块屏幕的方法很明确,就是写入2进制数字。通过设计厂商提供的命令表发送相应的2进制命令和数据,实现操控。这样做的好处是无论你使用的是什么机器,什么驱动板,只要实现了LcdWriteCommand()和LcdWriteData()两个函数,就可以实现对屏幕的完全控制。

你当然可以用最直接的办法去控制引脚,比如digitalWrite():

void LcdWriteCommand(unsigned char d){
  //Write Command Mode On
  digitalWrite(LCD_RS,LOW);
  //Write Datas to LCD_D0 to LCD_D7
  digitalWrite(LCD_D0,d%2);
  d = d >> 1;
  digitalWrite(LCD_D1,d%2);
  d = d >> 1;
  digitalWrite(LCD_D2,d%2);
  d = d >> 1;
  digitalWrite(LCD_D3,d%2);
  d = d >> 1;
  digitalWrite(LCD_D4,d%2);
  d = d >> 1;
  digitalWrite(LCD_D5,d%2);
  d = d >> 1;
  digitalWrite(LCD_D6,d%2);
  d = d >> 1;
  digitalWrite(LCD_D7,d%2);
  d = d >> 1;
  //Enable Datas
  digitalWrite(LCD_WR,LOW);
  digitalWrite(LCD_WR,HIGH);
}

void LcdWriteData(unsigned char d){
  //Write Data Mode On
  digitalWrite(LCD_RS,HIGH);
  //Write Datas to LCD_D0 to LCD_D7
  digitalWrite(LCD_D0,d%2);
  d = d >> 1;
  digitalWrite(LCD_D1,d%2);
  d = d >> 1;
  digitalWrite(LCD_D2,d%2);
  d = d >> 1;
  digitalWrite(LCD_D3,d%2);
  d = d >> 1;
  digitalWrite(LCD_D4,d%2);
  d = d >> 1;
  digitalWrite(LCD_D5,d%2);
  d = d >> 1;
  digitalWrite(LCD_D6,d%2);
  d = d >> 1;
  digitalWrite(LCD_D7,d%2);
  d = d >> 1;
  //Enable Datas
  digitalWrite(LCD_WR,LOW);
  digitalWrite(LCD_WR,HIGH);
}

但是这样做的话,速度嘛。。。看看这个,你就不会想用digitalWrite了:

 

 单片机中,速度为王,我们还是直接改Register吧:

void LcdWriteCommand(unsigned char d){
  //Write Command Mode On
  fastDigitalWriteLOW(LCD_RS);
  //Write Datas to LCD_D0 to LCD_D7
  PORTD = (PORTD & B00000011) | ((d) & B11111100); 
  PORTB = (PORTB & B11111100) | ((d) & B00000011); 
  //Enable Datas
  fastDigitalWriteLOW(LCD_WR);
  fastDigitalWriteHIGH(LCD_WR);
}

void LcdWriteData(unsigned char d){
  //Write Command Mode On
  fastDigitalWriteHIGH(LCD_RS);
  //Write Datas to LCD_D0 to LCD_D7
  PORTD = (PORTD & B00000011) | ((d) & B11111100);
  PORTB = (PORTB & B11111100) | ((d) & B00000011);
  //Enable Datas
  fastDigitalWriteLOW(LCD_WR);
  fastDigitalWriteHIGH(LCD_WR);
}

这段代码中,我用了宏定义来实现fastDigitalWriteHIGH()和fastDigitalWriteLOW(),这两个定义能避免函数的栈调用。其实用内联函数来写也可以实现:

inline void fastDigitalWriteHIGH(int Pin){
  *(portOutputRegister(digitalPinToPort(Pin)))|=digitalPinToBitMask(Pin);
  return;
}

但我就是喜欢宏定义,而且宏定义行数少些。

另外你可能会疑惑:什么是PORTB和PORTD?

PORTB其实就是针脚8-13,PORTD其实就是针脚0-7:

 

 

 假如你有一个这样的二进制数:

00000100

把他转换成十进制:

4     

再把它赋值给PORTD

PORTD = 4;

你就会发现针脚2通电了(图中连接到左边第一个红色灯泡):

 

 

 这就是PORTD的真正意义,它使用一个从0到255的数,记录针脚0到7的通电情况。

那我们为什么不用digitalWrite(),而是要用PORTB和PORTD呢?因为快啊( ̄▽ ̄)~*

5.Enjoy!

我们刚刚实现了LcdWriteCommand()和LcdWriteData()两个函数,现在,我们就可以实现对屏幕的完全控制了!

首先,先运行一段初始化命令:

  //Initialize Data Pins
  pinMode(LCD_D0,OUTPUT);
  pinMode(LCD_D1,OUTPUT);
  pinMode(LCD_D2,OUTPUT);
  pinMode(LCD_D3,OUTPUT);
  pinMode(LCD_D4,OUTPUT);
  pinMode(LCD_D5,OUTPUT);
  pinMode(LCD_D6,OUTPUT);
  pinMode(LCD_D7,OUTPUT);

  //Initialize Command Pins
  pinMode(LCD_RD,OUTPUT);
  pinMode(LCD_WR,OUTPUT);
  pinMode(LCD_RS,OUTPUT);
  pinMode(LCD_CS,OUTPUT);
  pinMode(LCD_RST,OUTPUT);
  digitalWrite(LCD_CS,LOW);
  digitalWrite(LCD_RD,HIGH);
  digitalWrite(LCD_WR,LOW);

  //Reset
  digitalWrite(LCD_RST,HIGH);
  delay(5);
  digitalWrite(LCD_RST,LOW);
  delay(15);
  digitalWrite(LCD_RST,HIGH);
  delay(15);

  LcdWriteCommand(0xCB);
  LcdWriteData(0x39);
  LcdWriteData(0x2C);
  LcdWriteData(0x00);
  LcdWriteData(0x34);
  LcdWriteData(0x02);

  LcdWriteCommand(0xCF);
  LcdWriteData(0x00);
  LcdWriteData(0XC1);
  LcdWriteData(0X30);

  LcdWriteCommand(0xE8);
  LcdWriteData(0x85);
  LcdWriteData(0x00);
  LcdWriteData(0x78);

  LcdWriteCommand(0xEA);
  LcdWriteData(0x00);
  LcdWriteData(0x00);
 
  LcdWriteCommand(0xED);
  LcdWriteData(0x64);
  LcdWriteData(0x03);
  LcdWriteData(0X12);
  LcdWriteData(0X81);

  LcdWriteCommand(0xF7);
  LcdWriteData(0x20);
  
  LcdWriteCommand(0xC0);    //Power control 
  LcdWriteData(0x23);   //VRH[5:0] 
 
  LcdWriteCommand(0xC1);    //Power control 
  LcdWriteData(0x10);   //SAP[2:0];BT[3:0] 

  LcdWriteCommand(0xC5);    //VCM control 
  LcdWriteData(0x3e);   //Contrast
  LcdWriteData(0x28); 
 
  LcdWriteCommand(0xC7);    //VCM control2 
  LcdWriteData(0x86);   //--
 
  LcdWriteCommand(0x36);    // Memory Access Control 
  LcdWriteData(0x48);   

  LcdWriteCommand(0x3A);
  LcdWriteData(0x55);

  LcdWriteCommand(0xB1);
  LcdWriteData(0x00);
  LcdWriteData(0x18);
 
  LcdWriteCommand(0xB6);    // Display Function Control 
  LcdWriteData(0x08);
  LcdWriteData(0x82);
  LcdWriteData(0x27);

  LcdWriteCommand(0x11);    //Exit Sleep 
  delay(120);
        
  LcdWriteCommand(0x29);    //Display on 
  LcdWriteCommand(0x2c);

这么多!不要怕,原样复制过去运行就好。这段命令是按照ILITEK设计文档中的规则发送的,用于初始化屏幕。运行完这段命令之后,我们就可以开始发自己的命令了。

我们试着来清一下屏。清屏就是指定一块区域,然后给屏幕每一个像素点的颜色为白色,这样就好了。

首先定义我们要写入的区域,这里就是从(0,0)写入到(239,319):

int x1 = 0;
int x2 = 239;
int y1 = 0;
int y2 = 319;

接着通知屏幕我们要写入的区域的X坐标的起始、终止位置(命令0x2a):

LcdWriteCommand(0x2a);

然后发送X坐标的起始位置(x1),和X坐标的终止位置(x2)。我们的机器一次只能发送八位数字,但八位数字最大只能表示255,所以我们要分两次发送,先发送前八位,再发送后八位:

LcdWriteData(x1>>8);
LcdWriteData(x1);
LcdWriteData(x2>>8);
LcdWriteData(x2);

Y坐标也是一样,只是把通知命令改成0x2b:

LcdWriteCommand(0x2b);
LcdWriteData(y1>>8);
LcdWriteData(y1);
LcdWriteData(y2>>8);
LcdWriteData(y2);

接着,我们发送开始写入的命令(0x2c),告诉屏幕我要开始发送像素了:

LcdWriteCommand(0x2c);

最后,发送所有像素的颜色数据(Data)。里面的RGB()宏定义是我在上一篇文章实现的。另外,因为是数据,所以我们要使用LcdWriteData():

#define RGB(r,g,b) ((b&31)+((g&63)<<5)+((r&31)<<11))

for(int i=y1;i<=y2;i++){
  for(int j=x1;j<=x2;j++){
    LcdWriteData(RGB(31,63,31)>>8);
    LcdWriteData(RGB(31,63,31));
  }
}

保存,下载。

刷屏完整代码:

// Breakout/Arduino UNO pin usage:
// LCD Data Bit :   7   6   5   4   3   2   1   0
// Uno dig. pin :   7   6   5   4   3   2   9   8
// Uno port/pin : PD7 PD6 PD5 PD4 PD3 PD2 PB1 PB0
// Mega dig. pin:  29  28  27  26  25  24  23  22
#define LCD_D0   8
#define LCD_D1   9
#define LCD_D2   2
#define LCD_D3   3
#define LCD_D4   4
#define LCD_D5   5
#define LCD_D6   6
#define LCD_D7   7
#define LCD_RD   A0
#define LCD_WR   A1
#define LCD_RS   A2
#define LCD_CS   A3
#define LCD_RST  A4
#define fastDigitalWriteHIGH(Pin) *(portOutputRegister(digitalPinToPort(Pin)))|=digitalPinToBitMask(Pin)  //Faster digitalWrite(Pin,HIGH);
#define fastDigitalWriteLOW(Pin) *(portOutputRegister(digitalPinToPort(Pin)))&=~digitalPinToBitMask(Pin)  //Faster digitalWrite(Pin,LOW);
#define RGB(r,g,b) ((b&31)+((g&63)<<5)+((r&31)<<11))

void LcdWriteCommand(unsigned char d){
  //Write Command Mode On
  fastDigitalWriteLOW(LCD_RS);
  //Write Datas to LCD_D0 to LCD_D7
  PORTD = (PORTD & B00000011) | ((d) & B11111100); 
  PORTB = (PORTB & B11111100) | ((d) & B00000011); 
  //Enable Datas
  fastDigitalWriteLOW(LCD_WR);
  fastDigitalWriteHIGH(LCD_WR);
}

void LcdWriteData(unsigned char d){
  //Write Command Mode On
  fastDigitalWriteHIGH(LCD_RS);
  //Write Datas to LCD_D0 to LCD_D7
  PORTD = (PORTD & B00000011) | ((d) & B11111100);
  PORTB = (PORTB & B11111100) | ((d) & B00000011);
  //Enable Datas
  fastDigitalWriteLOW(LCD_WR);
  fastDigitalWriteHIGH(LCD_WR);
}

void setup(){
  //Initialize Data Pins
  pinMode(LCD_D0,OUTPUT);
  pinMode(LCD_D1,OUTPUT);
  pinMode(LCD_D2,OUTPUT);
  pinMode(LCD_D3,OUTPUT);
  pinMode(LCD_D4,OUTPUT);
  pinMode(LCD_D5,OUTPUT);
  pinMode(LCD_D6,OUTPUT);
  pinMode(LCD_D7,OUTPUT);

  //Initialize Command Pins
  pinMode(LCD_RD,OUTPUT);
  pinMode(LCD_WR,OUTPUT);
  pinMode(LCD_RS,OUTPUT);
  pinMode(LCD_CS,OUTPUT);
  pinMode(LCD_RST,OUTPUT);
  digitalWrite(LCD_CS,LOW);
  digitalWrite(LCD_RD,HIGH);
  digitalWrite(LCD_WR,LOW);

  //Reset
  digitalWrite(LCD_RST,HIGH);
  delay(5);
  digitalWrite(LCD_RST,LOW);
  delay(15);
  digitalWrite(LCD_RST,HIGH);
  delay(15);

  LcdWriteCommand(0xCB);
  LcdWriteData(0x39);
  LcdWriteData(0x2C);
  LcdWriteData(0x00);
  LcdWriteData(0x34);
  LcdWriteData(0x02);

  LcdWriteCommand(0xCF);
  LcdWriteData(0x00);
  LcdWriteData(0XC1);
  LcdWriteData(0X30);

  LcdWriteCommand(0xE8);
  LcdWriteData(0x85);
  LcdWriteData(0x00);
  LcdWriteData(0x78);

  LcdWriteCommand(0xEA);
  LcdWriteData(0x00);
  LcdWriteData(0x00);
 
  LcdWriteCommand(0xED);
  LcdWriteData(0x64);
  LcdWriteData(0x03);
  LcdWriteData(0X12);
  LcdWriteData(0X81);

  LcdWriteCommand(0xF7);
  LcdWriteData(0x20);
  
  LcdWriteCommand(0xC0);    //Power control 
  LcdWriteData(0x23);   //VRH[5:0] 
 
  LcdWriteCommand(0xC1);    //Power control 
  LcdWriteData(0x10);   //SAP[2:0];BT[3:0] 

  LcdWriteCommand(0xC5);    //VCM control 
  LcdWriteData(0x3e);   //Contrast
  LcdWriteData(0x28); 
 
  LcdWriteCommand(0xC7);    //VCM control2 
  LcdWriteData(0x86);   //--
 
  LcdWriteCommand(0x36);    // Memory Access Control 
  LcdWriteData(0x48);   

  LcdWriteCommand(0x3A);
  LcdWriteData(0x55);

  LcdWriteCommand(0xB1);
  LcdWriteData(0x00);
  LcdWriteData(0x18);
 
  LcdWriteCommand(0xB6);    // Display Function Control 
  LcdWriteData(0x08);
  LcdWriteData(0x82);
  LcdWriteData(0x27);

  LcdWriteCommand(0x11);    //Exit Sleep 
  delay(120);
        
  LcdWriteCommand(0x29);    //Display on 
  LcdWriteCommand(0x2c);

  //Set Writing Area
  int x1 = 0;
  int x2 = 239;
  int y1 = 0;
  int y2 = 319;
  LcdWriteCommand(0x2a);
  LcdWriteData(x1>>8);
  LcdWriteData(x1);
  LcdWriteData(x2>>8);
  LcdWriteData(x2);
  LcdWriteCommand(0x2b);
  LcdWriteData(y1>>8);
  LcdWriteData(y1);
  LcdWriteData(y2>>8);
  LcdWriteData(y2);

  //Start Writing
  LcdWriteCommand(0x2c);
  for(int i=y1;i<=y2;i++){
    for(int j=x1;j<=x2;j++){
      LcdWriteData(RGB(31,63,31)>>8);
      LcdWriteData(RGB(31,63,31));
    }
  }
}

void loop(){
  
}

接下来的路线就很简单了,把指定区域的命令(0x2a,0x2b,0x2c)分装成LcdOpenWindow()函数,再实现LcdFill()函数,一个完整的ILI9341驱动就完成了:

#define LCD_D0   8
#define LCD_D1   9
#define LCD_D2   2
#define LCD_D3   3
#define LCD_D4   4
#define LCD_D5   5
#define LCD_D6   6
#define LCD_D7   7
#define LCD_RD   A0
#define LCD_WR   A1
#define LCD_RS   A2
#define LCD_CS   A3
#define LCD_RST  A4
#define fastDigitalWriteHIGH(Pin) *(portOutputRegister(digitalPinToPort(Pin)))|=digitalPinToBitMask(Pin)  //Faster digitalWrite(Pin,HIGH);
#define fastDigitalWriteLOW(Pin) *(portOutputRegister(digitalPinToPort(Pin)))&=~digitalPinToBitMask(Pin)  //Faster digitalWrite(Pin,LOW);
#define RGB(r,g,b) ((b&31)+((g&63)<<5)+((r&31)<<11))

void LcdWriteCommand(unsigned char d){
  //Write Command Mode On
  fastDigitalWriteLOW(LCD_RS);
  //Write Datas to LCD_D0 to LCD_D7
  PORTD = (PORTD & B00000011) | ((d) & B11111100); 
  PORTB = (PORTB & B11111100) | ((d) & B00000011); 
  //Enable Datas
  fastDigitalWriteLOW(LCD_WR);
  fastDigitalWriteHIGH(LCD_WR);
}

void LcdWriteData(unsigned char d){
  //Write Command Mode On
  fastDigitalWriteHIGH(LCD_RS);
  //Write Datas to LCD_D0 to LCD_D7
  PORTD = (PORTD & B00000011) | ((d) & B11111100);
  PORTB = (PORTB & B11111100) | ((d) & B00000011);
  //Enable Datas
  fastDigitalWriteLOW(LCD_WR);
  fastDigitalWriteHIGH(LCD_WR);
}

void LcdInit(void){
  //Initialize Data Pins
  pinMode(LCD_D0,OUTPUT);
  pinMode(LCD_D1,OUTPUT);
  pinMode(LCD_D2,OUTPUT);
  pinMode(LCD_D3,OUTPUT);
  pinMode(LCD_D4,OUTPUT);
  pinMode(LCD_D5,OUTPUT);
  pinMode(LCD_D6,OUTPUT);
  pinMode(LCD_D7,OUTPUT);

  //Initialize Command Pins
  pinMode(LCD_RD,OUTPUT);
  pinMode(LCD_WR,OUTPUT);
  pinMode(LCD_RS,OUTPUT);
  pinMode(LCD_CS,OUTPUT);
  pinMode(LCD_RST,OUTPUT);
  digitalWrite(LCD_CS,LOW);
  digitalWrite(LCD_RD,HIGH);
  digitalWrite(LCD_WR,LOW);

  //Reset
  digitalWrite(LCD_RST,HIGH);
  delay(5);
  digitalWrite(LCD_RST,LOW);
  delay(15);
  digitalWrite(LCD_RST,HIGH);
  delay(15);

  LcdWriteCommand(0xCB);
  LcdWriteData(0x39);
  LcdWriteData(0x2C);
  LcdWriteData(0x00);
  LcdWriteData(0x34);
  LcdWriteData(0x02);

  LcdWriteCommand(0xCF);
  LcdWriteData(0x00);
  LcdWriteData(0XC1);
  LcdWriteData(0X30);

  LcdWriteCommand(0xE8);
  LcdWriteData(0x85);
  LcdWriteData(0x00);
  LcdWriteData(0x78);

  LcdWriteCommand(0xEA);
  LcdWriteData(0x00);
  LcdWriteData(0x00);
 
  LcdWriteCommand(0xED);
  LcdWriteData(0x64);
  LcdWriteData(0x03);
  LcdWriteData(0X12);
  LcdWriteData(0X81);

  LcdWriteCommand(0xF7);
  LcdWriteData(0x20);
  
  LcdWriteCommand(0xC0);    //Power control 
  LcdWriteData(0x23);   //VRH[5:0] 
 
  LcdWriteCommand(0xC1);    //Power control 
  LcdWriteData(0x10);   //SAP[2:0];BT[3:0] 

  LcdWriteCommand(0xC5);    //VCM control 
  LcdWriteData(0x3e);   //Contrast
  LcdWriteData(0x28); 
 
  LcdWriteCommand(0xC7);    //VCM control2 
  LcdWriteData(0x86);   //--
 
  LcdWriteCommand(0x36);    // Memory Access Control 
  LcdWriteData(0x48);   

  LcdWriteCommand(0x3A);
  LcdWriteData(0x55);

  LcdWriteCommand(0xB1);
  LcdWriteData(0x00);
  LcdWriteData(0x18);
 
  LcdWriteCommand(0xB6);    // Display Function Control 
  LcdWriteData(0x08);
  LcdWriteData(0x82);
  LcdWriteData(0x27);

  LcdWriteCommand(0x11);    //Exit Sleep 
  delay(120);
        
  LcdWriteCommand(0x29);    //Display on 
  LcdWriteCommand(0x2c);
}

void LcdOpenWindow(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2){
  LcdWriteCommand(0x2a);
  LcdWriteData(x1>>8);
  LcdWriteData(x1);
  LcdWriteData(x2>>8);
  LcdWriteData(x2);
  LcdWriteCommand(0x2b);
  LcdWriteData(y1>>8);
  LcdWriteData(y1);
  LcdWriteData(y2>>8);
  LcdWriteData(y2);
  LcdWriteCommand(0x2c);
}

void LcdFill(int x,int y,int width,int height,unsigned int color)
{
  LcdOpenWindow(x,y,x+width-1,y+height-1);
  for(int i=y;i<y+height;i++){
    for(int j=x;j<x+width;j++){
      LcdWriteData(color>>8);
      LcdWriteData(color);
    }
  }
}

void setup(){
  LcdInit();
  LcdFill(0,0,239,319,RGB(31,63,31));
  LcdFill(10,10,100,100,RGB(31,0,0));
  LcdFill(20,20,110,110,RGB(0,63,0));
  LcdFill(30,30,120,120,RGB(0,0,31));
}

void loop(){
  
}

 

 都看到这了,还不点个赞吗?(✪ω✪)

标签:Pin,Arduino,digitalWrite,LcdWriteCommand,LcdWriteData,LCD,全过程,ILI9341,define
来源: https://www.cnblogs.com/lyj00912/p/12180140.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有