驱动代码
#include "ili9341.h"
#include "ili9341_command.h"
#include "color.h"
#include "Resources/Picture/picture.h"
//GPIO定义,尽管用了一定的空间,但是变得很直观了,可以直接放进ILI9341_gpio_init()里面
static LGPIO D0 = {
.GPIOx = GPIOD,
.GPIO_Pin = GPIO_Pin_14,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D1 = {
.GPIOx = GPIOD,
.GPIO_Pin = GPIO_Pin_15,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D2 = {
.GPIOx = GPIOD,
.GPIO_Pin = GPIO_Pin_0,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D3 = {
.GPIOx = GPIOD,
.GPIO_Pin = GPIO_Pin_1,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D4 = {
.GPIOx = GPIOE,
.GPIO_Pin = GPIO_Pin_7,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D5 = {
.GPIOx = GPIOE,
.GPIO_Pin = GPIO_Pin_8,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D6 = {
.GPIOx = GPIOE,
.GPIO_Pin = GPIO_Pin_9,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D7 = {
.GPIOx = GPIOE,
.GPIO_Pin = GPIO_Pin_10,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D8 = {
.GPIOx = GPIOE,
.GPIO_Pin = GPIO_Pin_11,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D9 = {
.GPIOx = GPIOE,
.GPIO_Pin = GPIO_Pin_12,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D10 = {
.GPIOx = GPIOE,
.GPIO_Pin = GPIO_Pin_13,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D11 = {
.GPIOx = GPIOE,
.GPIO_Pin = GPIO_Pin_14,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D12 = {
.GPIOx = GPIOE,
.GPIO_Pin = GPIO_Pin_15,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D13 = {
.GPIOx = GPIOD,
.GPIO_Pin = GPIO_Pin_8,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D14 = {
.GPIOx = GPIOD,
.GPIO_Pin = GPIO_Pin_9,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO D15 = {
.GPIOx = GPIOD,
.GPIO_Pin = GPIO_Pin_10,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO CS = {
.GPIOx = GPIOG,
.GPIO_Pin = GPIO_Pin_12,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO DC = {
.GPIOx = GPIOG,
.GPIO_Pin = GPIO_Pin_0,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO WR = {
.GPIOx = GPIOD,
.GPIO_Pin = GPIO_Pin_5,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO RD = {
.GPIOx = GPIOD,
.GPIO_Pin = GPIO_Pin_4,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP };
static LGPIO BL = {
.GPIOx = GPIOB,
.GPIO_Pin = GPIO_Pin_0,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_Out_PP };
static void ILI9341_gpio_init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);
LGPIO_Init(&D0);
LGPIO_Init(&D1);
LGPIO_Init(&D2);
LGPIO_Init(&D3);
LGPIO_Init(&D4);
LGPIO_Init(&D5);
LGPIO_Init(&D6);
LGPIO_Init(&D7);
LGPIO_Init(&D8);
LGPIO_Init(&D9);
LGPIO_Init(&D10);
LGPIO_Init(&D11);
LGPIO_Init(&D12);
LGPIO_Init(&D13);
LGPIO_Init(&D14);
LGPIO_Init(&D15);
LGPIO_Init(&CS);
LGPIO_Init(&DC);
LGPIO_Init(&WR);
LGPIO_Init(&RD);
LGPIO_Init(&BL);
LGPIO_WriteBit(&BL, 1);
}
void ILI9341_fsmc_init()
{
FSMC_NORSRAMTimingInitTypeDef readWriteTiming = { //读写时序
.FSMC_AddressSetupTime = 0x01, //地址建立时间(ADDSET)为2个HCLK 1/36M=27ns
.FSMC_AddressHoldTime = 0x00, //地址保持时间(ADDHLD)模式A未用到
.FSMC_DataSetupTime = 0x0f, // 数据保存时间为16个HCLK,因为液晶驱动IC的读数据的时候,速度不能太快,尤其对1289这个IC。
.FSMC_BusTurnAroundDuration = 0x00, //
.FSMC_CLKDivision = 0x00,
.FSMC_DataLatency = 0x00,
.FSMC_AccessMode = FSMC_AccessMode_A, //模式A
};
FSMC_NORSRAMTimingInitTypeDef writeTiming = { //写时序
.FSMC_AddressSetupTime = 0x00, //地址建立时间(ADDSET)为1个HCLK
.FSMC_AddressHoldTime = 0x00, //地址保持时间(A
.FSMC_DataSetupTime = 0x03, 数据保存时间为4个HCLK
.FSMC_BusTurnAroundDuration = 0x00,
.FSMC_CLKDivision = 0x00,
.FSMC_DataLatency = 0x00,
.FSMC_AccessMode = FSMC_AccessMode_A //模式A
};
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure = { //NORSRAM初始化结构体
.FSMC_Bank = FSMC_Bank1_NORSRAM4, // 这里我们使用NE4 ,也就对应BTCR[6],[7]。
.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable, // 不复用数据地址
.FSMC_MemoryType = FSMC_MemoryType_SRAM, // FSMC_MemoryType_SRAM; //SRAM
.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b, //存储器数据宽度为16bit
.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable, // FSMC_BurstAccessMode_Disable;
.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low,
.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable,
.FSMC_WrapMode = FSMC_WrapMode_Disable,
.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState,
.FSMC_WriteOperation = FSMC_WriteOperation_Enable, // 存储器写使能
.FSMC_WaitSignal = FSMC_WaitSignal_Disable,
.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable, // 读写使用不同的时序
.FSMC_WriteBurst = FSMC_WriteBurst_Disable,
.FSMC_ReadWriteTimingStruct = &readWriteTiming, //读写时序
.FSMC_WriteTimingStruct = &writeTiming //写时序
};
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_FSMC, ENABLE); // 使能FSMC时钟
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //初始化FSMC配置
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE); // 使能BANK1
}
static void ILI9341_write_command(u16 command)
{
LCD->LCD_REG = command; //写入要写的寄存器序号
}
static void ILI9341_write_data(u16 data)
{
LCD->LCD_RAM = data;
}
u16 ILI9341_read_data()
{
vu16 ram; //防止被优化
ram = LCD->LCD_RAM;
return ram;
}
u16 ILI9341_read_register(u16 reg)
{
ILI9341_write_command(reg); //写入要读的寄存器序号
delay_us(5);
return ILI9341_read_data(); //返回读到的值
}
void ILI9341_register_init()
{
ILI9341_write_command(COMMAND_POWCTRLB);
ILI9341_write_data(0x00);
ILI9341_write_data(0xC1);
ILI9341_write_data(0X30);
ILI9341_write_command(0xED);
ILI9341_write_data(0x64);
ILI9341_write_data(0x03);
ILI9341_write_data(0X12);
ILI9341_write_data(0X81);
ILI9341_write_command(0xE8);
ILI9341_write_data(0x85);
ILI9341_write_data(0x10);
ILI9341_write_data(0x7A);
ILI9341_write_command(COMMAND_POWCTRLA);
ILI9341_write_data(0x39);
ILI9341_write_data(COMMAND_RAMWR);
ILI9341_write_data(0x00);
ILI9341_write_data(0x34);
ILI9341_write_data(0x02);
ILI9341_write_command(0xF7);
ILI9341_write_data(0x20);
ILI9341_write_command(0xEA);
ILI9341_write_data(0x00);
ILI9341_write_data(0x00);
ILI9341_write_command(0xC0); //Power control //电源控制
ILI9341_write_data(0x1B); //VRH[5:0]
ILI9341_write_command(0xC1); //Power control
ILI9341_write_data(0x01); //SAP[2:0];BT[3:0]
ILI9341_write_command(0xC5); //VCM control
ILI9341_write_data(0x30); //3F
ILI9341_write_data(0x30); //3C
ILI9341_write_command(0xC7); //VCM control2
ILI9341_write_data(0XB7);
ILI9341_write_command(0x36); //Memory Access Control (存储器访问控制)
ILI9341_write_data(0x48);
ILI9341_write_command(0x3A); //像素格式设置
ILI9341_write_data(0x55);
ILI9341_write_command(0xB1);
ILI9341_write_data(0x00);
ILI9341_write_data(0x1A);
ILI9341_write_command(0xB6); // Display Function Control
ILI9341_write_data(0x0A);
ILI9341_write_data(0xA2);
ILI9341_write_command(0xF2); // 3Gamma Function Disable
ILI9341_write_data(0x00);
ILI9341_write_command(0x26); // Gamma curve selected
ILI9341_write_data(0x01);
ILI9341_write_command(0xE0); // Set Gamma
ILI9341_write_data(0x0F);
ILI9341_write_data(COMMAND_CASET);
ILI9341_write_data(0x28);
ILI9341_write_data(0x08);
ILI9341_write_data(0x0E);
ILI9341_write_data(0x08);
ILI9341_write_data(0x54);
ILI9341_write_data(0XA9);
ILI9341_write_data(0x43);
ILI9341_write_data(0x0A);
ILI9341_write_data(0x0F);
ILI9341_write_data(0x00);
ILI9341_write_data(0x00);
ILI9341_write_data(0x00);
ILI9341_write_data(0x00);
ILI9341_write_command(0XE1); // Set Gamma
ILI9341_write_data(0x00);
ILI9341_write_data(0x15);
ILI9341_write_data(0x17);
ILI9341_write_data(0x07);
ILI9341_write_data(0x11);
ILI9341_write_data(0x06);
ILI9341_write_data(COMMAND_PASET);
ILI9341_write_data(0x56);
ILI9341_write_data(0x3C);
ILI9341_write_data(0x05);
ILI9341_write_data(0x10);
ILI9341_write_data(0x0F);
ILI9341_write_data(0x3F);
ILI9341_write_data(0x3F);
ILI9341_write_data(0x0F);
ILI9341_write_command(COMMAND_PASET); //页地址四个参数
ILI9341_write_data(0x00); //1
ILI9341_write_data(0x00); //2
ILI9341_write_data(0x01); //3
ILI9341_write_data(0x3f); //4
ILI9341_write_command(COMMAND_CASET); //列地址设定
ILI9341_write_data(0x00); //第一个参数
ILI9341_write_data(0x00); //第二参数
ILI9341_write_data(0x00); //第三参数
ILI9341_write_data(0xef); //第四参数
ILI9341_write_command(0x11); //Exit Sleep(退出休眠)
delay_ms(120);
ILI9341_write_command(COMMAND_DISPON); //display on (开显示)
}
void ILI9341_Init()
{
ILI9341_gpio_init();
ILI9341_fsmc_init();
ILI9341_register_init();
delay_ms(50); // delay 50 ms
LCD_clear(RGB565_RED);
}
void LCD_setCursor(u16 x, u16 y)
{
ILI9341_write_command(COMMAND_CASET);
ILI9341_write_data(x >> 8);
ILI9341_write_data(x & 0XFF);
ILI9341_write_command(COMMAND_PASET);
ILI9341_write_data(y >> 8);
ILI9341_write_data(y & 0XFF);
}
void LCD_drawPoint(u16 x, u16 y, u16 color)
{
LCD_setCursor(x, y); //设置光标位置
ILI9341_write_command(COMMAND_RAMWR); //开始写入GRAM
LCD->LCD_RAM = color;
}
void LCD_setWindow(u16 x, u16 y, u16 width, u16 height)
{
ILI9341_write_command(COMMAND_CASET);
ILI9341_write_data(x >> 8);
ILI9341_write_data(x & 0XFF);
ILI9341_write_data((x + width - 1) >> 8);
ILI9341_write_data((x + width - 1) & 0XFF);
ILI9341_write_command(COMMAND_PASET);
ILI9341_write_data(y >> 8);
ILI9341_write_data(y & 0XFF);
ILI9341_write_data((y + height - 1) >> 8);
ILI9341_write_data((y + height - 1) & 0XFF);
}
void LCD_clear(u16 color)
{
LCD_setCursor(0x00, 0x0000); //设置光标位置
ILI9341_write_command(COMMAND_RAMWR); //开始写入GRAM
for (u32 index = 0; index < 240 * 320; index++) {
LCD->LCD_RAM = color;
}
}
void LCD_drawPicture(Picture *picturePtr, u16 startX, u16 startY)
{
u32 i = 0;
for (u16 y = startY; y < picturePtr->height; y++)
for (u16 x = startX; x < picturePtr->width; x++) {
u16 color = (picturePtr->data)[i + 1];
color = color << 8;
color += (picturePtr->data)[i];
LCD_drawPoint(x, y, color);
i += 2;
}
}
void ILI9341_test()
{
ILI9341_Init();
LCD_clear(RGB565_RED);
while (1) {
LCD_drawPicture(&picture1, 0, 0);
delay_ms(1000);
LCD_drawPicture(&picture2, 0, 0);
delay_ms(1000);
}
}
头文件
#ifndef HARDWARE_ILI9341_FSMC_ILI9341_H_
#define HARDWARE_ILI9341_FSMC_ILI9341_H_
#include "llib.h"
typedef struct {
vu16 LCD_REG;
vu16 LCD_RAM;
} LCD_TypeDef;
//这个地址可以对着手册自己算,我直接抄的正点原子的代码然后改的
#define LCD_BASE ((u32)(0x6C000000 | 0x000007FE))
#define LCD ((LCD_TypeDef *) LCD_BASE)
#endif /* HARDWARE_ILI9341_FSMC_ILI9341_H_ */
其他头文件
ili9341_command.h
#ifndef HARDWARE_ILI9341_ILI9341_COMMAND_H_
#define HARDWARE_ILI9341_ILI9341_COMMAND_H_
//以下为指令表
#define COMMAND_NOP 0x00 //空指令
#define COMMAND_SWRESET 0x01 //软件复位
#define COMMAND_RDDIDIF 0x04 //读取ID
#define COMMAND_RDDST 0x09 //读显示状态
#define COMMAND_RDDPM 0x0A //读显示能耗模式
#define COMMAND_RDDMADCTL 0x0B //读显示 MADCTL
#define COMMAND_RDDCOLMOD 0x0C //读显示像素格式
#define COMMAND_RDDIM 0x0D //读显示图像模式
#define COMMAND_RDDSM 0x0E //读显示信号模式
#define COMMAND_RDDSDR 0x0F
#define COMMAND_SPLIN 0x10
#define COMMAND_SLPOUT 0x11
#define COMMAND_PTLON 0x12
#define COMMAND_NORON 0x13
#define COMMAND_DINVOFF 0x20
#define COMMAND_DINVON 0x21
#define COMMAND_GAMSET 0x26
#define COMMAND_DISPOFF 0x28 //关显示
#define COMMAND_DISPON 0x29 //关显示
#define COMMAND_CASET 0x2A //列地址设置
#define COMMAND_PASET 0x2B //页地址设置
#define COMMAND_RAMWR 0x2C //存储器写
#define COMMAND_RGBSET 0x2D
#define COMMAND_RAMRD 0x2E
#define COMMAND_PLTAR 0x30
#define COMMAND_VSCRDEF 0x33
#define COMMAND_TEOFF 0x34
#define COMMAND_TEON 0x35
#define COMMAND_MADCTL 0x36
#define COMMAND_VSCRSADD 0x37
#define COMMAND_IDMOFF 0x38
#define COMMAND_IDMON 0x39
#define COMMAND_PIXSET 0x3A
#define COMMAND_WMC 0x3C
#define COMMAND_RMC 0x3E
#define COMMAND_STS 0x44
#define COMMAND_GS 0x45
#define COMMAND_WRDISBV 0x51
#define COMMAND_RDDISBV 0x52
#define COMMAND_WRCTRLD 0x53
#define COMMAND_RDCTRLD 0x54
#define COMMAND_WRCABC 0x55
#define COMMAND_PDCABC 0x56
#define COMMAND_WCABCMB 0x5E
#define COMMAND_RCABCMB 0x5F
#define COMMAND_RDID1 0xDA
#define COMMAND_RDID2 0xDB
#define COMMAND_RDID3 0xDC
#define COMMAND_IFMODE 0xB0
#define COMMAND_FRMCTR1 0xB1
#define COMMAND_FRMCTR2 0xB2
#define COMMAND_FRMCTR3 0xB3
#define COMMAND_INVTR 0xB4
#define COMMAND_PRCTR 0xB5
#define COMMAND_DISCTRL 0xB6
#define COMMAND_ETMOD 0xB7
#define COMMAND_BC1 0xB8
#define COMMAND_BC2 0xB9
#define COMMAND_BC3 0xBA
#define COMMAND_BC4 0xBB
#define COMMAND_BC5 0xBC
#define COMMAND_BC7 0xBE
#define COMMAND_BC8 0xBF
#define COMMAND_PWCTRL1 0xC0
#define COMMAND_PWCTRL2 0xC1
#define COMMAND_VMCTRL1 0xC5
#define COMMAND_VMCTRL2 0xC7
#define COMMAND_NVMWR 0xD0
#define COMMAND_NVMPKEY 0xD1
#define COMMAND_RDNVM 0xD2
#define COMMAND_RDID4 0xD3
#define COMMAND_NGAMVTRL 0xE1
#define COMMAND_DGAMCTRL1 0xE2
#define COMMAND_DGAMCTAL2 0xE3
#define COMMAND_IFCTL 0xF6
#define COMMAND_POWCTRLA 0xCB //功耗控制A
#define COMMAND_POWCTRLB 0xCF //功耗控制B
#define COMMAND_DTCTRLA 0xE8
#define COMMAND_DTCTRLA2 0xE9
#define COMMAND_DTCTRLB 0xEA
#define COMMAND_POSCTRL 0xED
#define COMMAND_EN3G 0xF2
#define COMMAND_PRCTRL 0xF7
#endif /* HARDWARE_ILI9341_ILI9341_COMMAND_H_ */
color.h
#ifndef HARDWARE_ILI9341_COLOR_H_
#define HARDWARE_ILI9341_COLOR_H_
//RGB565常用色彩
#define RGB565_BLACK 0x0000 //黑色
#define RGB565_NAVY 0x000F //深蓝色
#define RGB565_DGREEN 0x03E0 //深绿色
#define RGB565_DCYAN 0x03EF //深青色
#define RGB565_MAROON 0x7800 //深红色
#define RGB565_PURPLE 0x780F //紫色
#define RGB565_OLIVE 0x7BE0 //橄榄绿
#define RGB565_LGRAY 0xC618 //灰白色
#define RGB565_DGRAY 0x7BEF //深灰色
#define RGB565_BLUE 0x001F //蓝色
#define RGB565_GREEN 0x07E0 //绿色
#define RGB565_CYAN 0x07FF //青色
#define RGB565_RED 0xF800 //红色
#define RGB565_MAGENTA 0xF81F //品红
#define RGB565_YELLOW 0xFFE0 //黄色
#define RGB565_WHITE 0xFFFF //白色
#endif /* HARDWARE_ILI9341_COLOR_H_ */
用到的llib.h文件中的宏定义和类型如下
typedef struct {
GPIO_TypeDef *GPIOx;
uint16_t GPIO_Pin;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOMode_TypeDef GPIO_Mode;
} LGPIO;
#define LGPIO_InitTypeDef(LGPIO_Ptr) ((GPIO_InitTypeDef *)&((LGPIO_Ptr)->GPIO_Pin))
#define LGPIO_Init(LGPIO_Ptr) GPIO_Init((LGPIO_Ptr)->GPIOx,LGPIO_InitTypeDef(LGPIO_Ptr))
|