Подключение дисплея.
Диспллей с SPI - последовательным интерфейсом.
SCK - тактирование, данные с линии SDA защелкиваются по нарастающему фронту
SDA - Данные для записи в дисплей (биты передаются от старшего к младшему)
RES(RST) - Сброс, активный уровень низкий
RS(A0) - низкий уровень - команда, высокий уровень - данные
CS - выбор дисплея (chip select), активный уровень низкий
SCK дисплея - к SCK контроллера
SDA дисплея - к MOSI контроллера.
RES, RS, CS - к любым портам контроллера.
Инициализация железа.
Спойлер
все 5 линий настраиваем на выход, на линии CS и RES выводим 1.
Так же настраиваем SPI на максимальную скорость:
SPCR = 1<<SPE | 1<<MSTR | 0<<SPR1 | 0<<SPR0;
SPSR |= (1<<SPI2X);Теперь процедуры низкоуровневого общения с дисплеем.
Спойлер
У нас 4 процедуры :
процедура отправки байта по СПИ и три процедуры управления сигналами RST, RS, CS.
определение, куда у нас подключен выводы RST, RS и CS дисплея
Код:
#define LCD_RST_PORT B
#define LCD_RST_BITVAL (1<<PORTB4)
#define LCD_RS_PORT D
#define LCD_RS_BITVAL (1<<PORTD5)
#define LCD_CS_PORT D
#define LCD_CS_BITVAL (1<<PORTD3)
и процедуры управления выводами этими:
Код:
void setResetPinILI9341(unsigned char resetLevel){
if (resetLevel) __OUTPORT(LCD_RST_PORT) |= LCD_RST_BITVAL; else __OUTPORT(LCD_RST_PORT) &= ~LCD_RST_BITVAL;
}
void setRsLevelILI9341(unsigned char rsLevel){
if (rsLevel) __OUTPORT(LCD_RS_PORT) |= LCD_RS_BITVAL; else __OUTPORT(LCD_RS_PORT) &= ~LCD_RS_BITVAL;
}
void setСsLevelILI9341(unsigned char сsLevel){
if (сsLevel) __OUTPORT(LCD_СS_PORT) |= LCD_СS_BITVAL; else __OUTPORT(LCD_СS_PORT) &= ~LCD_СS_BITVAL;
}
И процедура отправки 2 байт в дисплей
Код:
void sendWordILI9341(unsigned int wordToSend) {
setСsLevelILI9341(0);
SPDR = wordToSend >> 8;
while((SPSR & (1<<SPIF)) == 0);
SPDR = wordToSend & 0xFF;
while((SPSR & (1<<SPIF)) == 0);
setСsLevelILI9341(1);
}
Всё. с железной частью разобрались.
теперь библиотека дисплея.
Спойлер
Код:
#ifndef ILI9341_H_
#define ILI9341_H_
#define DISPLAY_ILI9341_WIDTH 240
#define DISPLAY_ILI9341_HEIGHT 320
#define ILI9341_MADCTL_MY 0x80
#define ILI9341_MADCTL_MX 0x40
#define ILI9341_MADCTL_MV 0x20
#define ILI9341_MADCTL_RGB 0x00
#define ILI9341_MADCTL_BGR 0x08
#define ILI9341_MADCTL_ML 0x10
#define ILI9341_MADCTL_MH 0x04
#define ILI9341_RGB444 0x03
#define ILI9341_RGB565 0x05
#define ILI9341_RGB666 0x06
#define ILI9341_NOP 0x00
#define ILI9341_SWRESET 0x01
#define ILI9341_SLPIN 0x10
#define ILI9341_SLPOUT 0x11
#define ILI9341_PTLON 0x12
#define ILI9341_NORON 0x13
#define ILI9341_INVOFF 0x20
#define ILI9341_INVON 0x21
#define ILI9341_DISPOFF 0x28
#define ILI9341_DISPON 0x29
#define ILI9341_CASET 0x2A
#define ILI9341_RASET 0x2B
#define ILI9341_RAMWR 0x2C
#define ILI9341_RGBSET 0x2D
#define ILI9341_PTLAR 0x30
#define ILI9341_COLMOD 0x3A
#define ILI9341_MADCTL 0x36
#define RED_565 0xF800
#define ORANGE_565 0xFC00
#define YELLOW_565 0xFFE0
#define LIME_565 0x7FE0
#define GREEN_565 0x07E0
#define CYAN_565 0x07FF
#define BLUE_565 0x001F
#define MAGENTA_565 0xF81F
#define WHITE_565 0xFFFF
#define BLACK_565 0x0000
#define GRAY0_565 0xEF7D
#define GRAY1_565 0x8410
#define GRAY2_565 0x4208
extern void setResetPinILI9341(unsigned char resetLevel);
extern void setRsLevelILI9341(unsigned char rsLevel);
extern void sendWordILI9341(unsigned int wordToSend);
void initDisplayILI9341(void);
void sleepModeILI9341(unsigned char isSleep);
void powerModeILI9341(unsigned char isPowerOn);
void inversionModeILI9341(unsigned char isInversionOn);
void setMemoryWriteModeILI9341(unsigned char madctlFlags);
void setOutputAreaILI9341(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2);
void setColorWriteModeILI9341(void);
void sendColorDataILI9341(unsigned int colorData);
void sendCommandILI9341(unsigned char displayCommand);
void sendDataILI9341(unsigned int displayData);
void clearDisplayILI9341(void);
void fillDisplayILI9341(unsigned int fillColor);
void fillAreaILI9341(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int fillColor);
void putPixelILI9341(unsigned int x, unsigned int y, unsigned int pixelColor);
#endif
Код:
#include "ILI9341.h"
#include <util/delay.h>
static unsigned char isSwapCoordinates = 0;
void initDisplayILI9341(void){
setResetPinILI9341(0);
_delay_ms(50);
setResetPinILI9341(1);
_delay_ms(10);
sendCommandILI9341(ILI9341_SWRESET);
_delay_ms(120);
sendCommandILI9341(0xCB);
sendDataILI9341(0x39);
sendDataILI9341(0x2C);
sendDataILI9341(0x00);
sendDataILI9341(0x34);
sendDataILI9341(0x02);
sendCommandILI9341(0xCF);
sendDataILI9341(0x00);
sendDataILI9341(0xC1);
sendDataILI9341(0x30);
sendCommandILI9341(0xE8);
sendDataILI9341(0x85);
sendDataILI9341(0x00);
sendDataILI9341(0x78);
sendCommandILI9341(0xEA);
sendDataILI9341(0x00);
sendDataILI9341(0x00);
sendCommandILI9341(0xED);
sendDataILI9341(0x64);
sendDataILI9341(0x03);
sendDataILI9341(0x12);
sendDataILI9341(0x81);
sendCommandILI9341(0xF7);
sendDataILI9341(0x20);
sendCommandILI9341(0xC0);
sendDataILI9341(0x23);
sendCommandILI9341(0xC1);
sendDataILI9341(0x10);
sendCommandILI9341(0xC5);
sendDataILI9341(0x3E);
sendDataILI9341(0x28);
sendCommandILI9341(0xC7);
sendDataILI9341(0x86);
sendCommandILI9341(0x36);
sendDataILI9341(0x48);
sendCommandILI9341(0x3A);
sendDataILI9341(0x55);
sendCommandILI9341(0xB1);
sendDataILI9341(0x00);
sendDataILI9341(0x18);
sendCommandILI9341(0xB6);
sendDataILI9341(0x08);
sendDataILI9341(0x82);
sendDataILI9341(0x27);
sendCommandILI9341(0xF2);
sendDataILI9341(0x00);
sendCommandILI9341(ILI9341_CASET);
sendDataILI9341(0x00);
sendDataILI9341(0x00);
sendDataILI9341(0x00);
sendDataILI9341(0xEF);
sendCommandILI9341(ILI9341_RASET);
sendDataILI9341(0x00);
sendDataILI9341(0x00);
sendDataILI9341(0x01);
sendDataILI9341(0x3F);
sendCommandILI9341(0x26);
sendDataILI9341(0x01);
sendCommandILI9341(0xE0);
sendDataILI9341(0x0F);
sendDataILI9341(0x31);
sendDataILI9341(0x2B);
sendDataILI9341(0x0C);
sendDataILI9341(0x0E);
sendDataILI9341(0x08);
sendDataILI9341(0x4E);
sendDataILI9341(0xF1);
sendDataILI9341(0x37);
sendDataILI9341(0x07);
sendDataILI9341(0x10);
sendDataILI9341(0x03);
sendDataILI9341(0x0E);
sendDataILI9341(0x09);
sendDataILI9341(0x00);
sendCommandILI9341(0xE1);
sendDataILI9341(0x00);
sendDataILI9341(0x0E);
sendDataILI9341(0x14);
sendDataILI9341(0x03);
sendDataILI9341(0x11);
sendDataILI9341(0x07);
sendDataILI9341(0x31);
sendDataILI9341(0xC1);
sendDataILI9341(0x48);
sendDataILI9341(0x08);
sendDataILI9341(0x0F);
sendDataILI9341(0x0C);
sendDataILI9341(0x31);
sendDataILI9341(0x36);
sendDataILI9341(0x0F);
sleepModeILI9341(0);
_delay_ms(120);
powerModeILI9341(1);
_delay_us(150);
sendCommandILI9341(ILI9341_COLMOD);
sendDataILI9341(ILI9341_RGB565);
setMemoryWriteModeILI9341(ILI9341_MADCTL_RGB);
}
void sleepModeILI9341(unsigned char isSleep){
if (isSleep) sendCommandILI9341(ILI9341_SLPIN);
else sendCommandILI9341(ILI9341_SLPOUT);
}
void powerModeILI9341(unsigned char isPowerOn){
if (isPowerOn) sendCommandILI9341(ILI9341_DISPON);
else sendCommandILI9341(ILI9341_DISPOFF);
}
void inversionModeILI9341(unsigned char isInversionOn){
if (isInversionOn) sendCommandILI9341(ILI9341_INVON);
else sendCommandILI9341(ILI9341_INVOFF);
}
void setMemoryWriteModeILI9341(unsigned char madctlFlags){
sendCommandILI9341(ILI9341_MADCTL);
sendDataILI9341(madctlFlags);
isSwapCoordinates = madctlFlags & ILI9341_MADCTL_MV;
}
void setOutputAreaILI9341(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2){
sendCommandILI9341(ILI9341_CASET);
sendDataILI9341(HI(x1));
sendDataILI9341(LO(x1));
sendDataILI9341(HI(x2));
sendDataILI9341(LO(x2));
sendCommandILI9341(ILI9341_RASET);
sendDataILI9341(HI(y1));
sendDataILI9341(LO(y1));
sendDataILI9341(HI(y2));
sendDataILI9341(LO(y2));
setColorWriteModeILI9341();
}
void setColorWriteModeILI9341(void){
sendCommandILI9341(ILI9341_RAMWR);
}
void sendColorDataILI9341(unsigned int colorData){
sendDataILI9341( colorData );
}
void sendCommandILI9341(unsigned char displayCommand){
setRsLevelILI9341(0);
sendWordILI9341(displayCommand);
}
void sendDataILI9341(unsigned int displayData){
setRsLevelILI9341(1);
sendWordILI9341(displayData);
}
void clearDisplayILI9341(void){
fillDisplayILI9341(0x0000);
}
void fillDisplayILI9341(unsigned int fillColor){
if (isSwapCoordinates) fillAreaILI9341(0,0,DISPLAY_ILI9341_HEIGHT-1,DISPLAY_ILI9341_WIDTH-1,fillColor);
else fillAreaILI9341(0,0,DISPLAY_ILI9341_WIDTH-1,DISPLAY_ILI9341_HEIGHT-1,fillColor);
}
void fillAreaILI9341(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int fillColor){
setOutputAreaILI9341(x1,y1,x2,y2);
unsigned int i=x1;
while(1) {
unsigned int j=y1;
while(2) {
sendColorDataILI9341(fillColor);
if (j==y2) break;
j++;
}
if (i==x2) break;
i++;
}
}
void putPixelILI9341(unsigned int x, unsigned int y, unsigned int pixelColor){
fillAreaILI9341(x,y,x,y,pixelColor);
}
Как пользоваться.
1. Проинициализировать интерфейс СПИ и выводы управления дисплеем.
2. вызвать initDisplayILI9341();
3. Рисовать.
И да, я тут не рассматривал вопросы питания и подсветки.
Хоть контроллер ILI9341 и толерастен к 5 вольтам питания, входная логика исключительно 3.3 вольта. Соответственно, на 5 линий интерфейса надо 5 делителей, или питать контроллер от источника 3,3 вольта
В том дисплее, что у меня - управление подсветкой - это логический вход, т.е. им можно управлять без всяких резисторов и транзисторов прямо с ноги контроллера.
Читайте описание вашего дисплея, что бы убедиться, что у вас так же.
Или смотрите по плате - куда и как идут дорожки подсветки.