2.8寸LCD屏驱动(ILI9341)

发布时间:2026/7/9 4:16:42
2.8寸LCD屏驱动(ILI9341) 软件模拟8080时序驱动2.8寸LCD屏驱动实现指定位置画点、绘制直线、矩形、显示图片等功能。8080时序介绍见我上篇文章软件模拟8080通信https://blog.csdn.net/qq_69110655/article/details/162700202?fromshareblogdetailsharetypeblogdetailsharerId162700202sharereferPCsharesourceqq_69110655sharefromfrom_link完整代码基于STM32my_lcd.h#ifndef __MY_LCD_H #define __MY_LCD_H #include stm32f10x.h #include my_8080.h //颜色宏定义 RGB565 #define WHITE 0xFFFF #define BLACK 0x0000 #define BLUE 0x001F #define BRED 0XF81F #define GRED 0XFFE0 #define GBLUE 0X07FF #define RED 0xF800 #define MAGENTA 0xF81F #define GREEN 0x07E0 #define CYAN 0x7FFF #define YELLOW 0xFFE0 #define BROWN 0XBC40 //棕色 #define BRRED 0XFC07 //棕红色 #define GRAY 0X8430 //灰色 void lcd_init(void); void lcd_readId(void); // 指定点设置指定颜色 void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color); // 画线 void lcd_draw_line(uint16_t s_x, uint16_t s_y, uint16_t e_x, uint16_t e_y, uint16_t color); // 显示图片 void lcd_show_pic(uint16_t x0,uint16_t y0,uint16_t width,uint16_t height,const uint8_t *pic); // 绘制矩形 void lcd_draw_rect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); // 绘制实心填充矩形 void lcd_draw_fill_rect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); #endifmy_lcd.c#include myLCD.h #include delay.h #include stdio.h // 背光引脚配置 #define lcd_BL_PIN GPIO_Pin_0 #define lcd_BL_PORT GPIOB #define lcd_backlight_control(x) GPIO_WriteBit(lcd_BL_PORT, lcd_BL_PIN, (x) ? Bit_SET : Bit_RESET) struct lcd_cmd { uint16_t setPointColor; // 设置像素点颜色信息; 将数据从 MCU微控制器传输到帧存储器显存/GRAM。 uint16_t setX; // 设置x坐标 uint16_t setY; // 设置y坐标 uint16_t readID; // 读ID uint16_t setScanDir; // 设置扫描方向 }; typedef struct { uint16_t width; // 屏幕宽度 uint16_t height; // 屏幕高度 uint16_t id; // 屏幕ID uint8_t dir; // 屏幕显示方向 1横屏 0 竖屏 struct lcd_cmd cmd; // 屏幕控制命令集 } LCD_DrvTypeDef; LCD_DrvTypeDef lcd { .dir 1, // 使用横屏 .width 320, .height 240, // .dir 0, // 使用竖屏 // .width 240, // .height 320, .cmd.setPointColor 0x2C, .cmd.setX 0x2A, // 设置列地址命令 .cmd.setY 0x2B, // 设置行地址命令 .cmd.readID 0xD3, // 获取ID命令 .cmd.setScanDir 0x36, // Memory Access Control (36h) }; void lcd_readId(void) { //9341 ID的读取 my8080_writeCommand(0XD3); lcd.idmy8080_readData(); //dummy read lcd.idmy8080_readData(); //读到0X00 lcd.idmy8080_readData(); //读取93 lcd.id8; lcd.id|my8080_readData(); //读取41 printf(lcd id%X\r\n, lcd.id); } static void lcd_Config(void) { my8080_writeCommand(0xCF); my8080_writeData(0x00); my8080_writeData(0xC1); my8080_writeData(0X30); my8080_writeCommand(0xED); my8080_writeData(0x64); my8080_writeData(0x03); my8080_writeData(0X12); my8080_writeData(0X81); my8080_writeCommand(0xE8); my8080_writeData(0x85); my8080_writeData(0x10); my8080_writeData(0x7A); my8080_writeCommand(0xCB); my8080_writeData(0x39); my8080_writeData(0x2C); my8080_writeData(0x00); my8080_writeData(0x34); my8080_writeData(0x02); my8080_writeCommand(0xF7); my8080_writeData(0x20); my8080_writeCommand(0xEA); my8080_writeData(0x00); my8080_writeData(0x00); my8080_writeCommand(0xC0); //Power control my8080_writeData(0x1B); //VRH[5:0] my8080_writeCommand(0xC1); //Power control my8080_writeData(0x01); //SAP[2:0];BT[3:0] my8080_writeCommand(0xC5); //VCM control my8080_writeData(0x30); //3F my8080_writeData(0x30); //3C my8080_writeCommand(0xC7); //VCM control2 my8080_writeData(0XB7); my8080_writeCommand(0x36); // Memory Access Control my8080_writeData(0x48); my8080_writeCommand(0x3A); my8080_writeData(0x55); my8080_writeCommand(0xB1); my8080_writeData(0x00); my8080_writeData(0x1A); my8080_writeCommand(0xB6); // Display Function Control my8080_writeData(0x0A); my8080_writeData(0xA2); my8080_writeCommand(0xF2); // 3Gamma Function Disable my8080_writeData(0x00); my8080_writeCommand(0x26); //Gamma curve selected my8080_writeData(0x01); my8080_writeCommand(0xE0); //Set Gamma my8080_writeData(0x0F); my8080_writeData(0x2A); my8080_writeData(0x28); my8080_writeData(0x08); my8080_writeData(0x0E); my8080_writeData(0x08); my8080_writeData(0x54); my8080_writeData(0XA9); my8080_writeData(0x43); my8080_writeData(0x0A); my8080_writeData(0x0F); my8080_writeData(0x00); my8080_writeData(0x00); my8080_writeData(0x00); my8080_writeData(0x00); my8080_writeCommand(0XE1); //Set Gamma my8080_writeData(0x00); my8080_writeData(0x15); my8080_writeData(0x17); my8080_writeData(0x07); my8080_writeData(0x11); my8080_writeData(0x06); my8080_writeData(0x2B); my8080_writeData(0x56); my8080_writeData(0x3C); my8080_writeData(0x05); my8080_writeData(0x10); my8080_writeData(0x0F); my8080_writeData(0x3F); my8080_writeData(0x3F); my8080_writeData(0x0F); my8080_writeCommand(0x2A); // 宽 my8080_writeData(0x00); my8080_writeData(0x00); // my8080_writeData(0x01); // my8080_writeData(0x3f); //0x13F 319 my8080_writeData(lcd.width 8); my8080_writeData(lcd.width 0xFF); my8080_writeCommand(0x2B); //设置屏高 my8080_writeData(0x00); my8080_writeData(0x00); // my8080_writeData(0x00); // my8080_writeData(0xef); //0xEF 239 my8080_writeData(lcd.height 8); my8080_writeData(lcd.height 0xFF); my8080_writeCommand(0x11); //Exit Sleep Delay_ms(120); my8080_writeCommand(0x29); //display on } // 在指定位置写入一个数据 void lcd_write_reg(uint16_t reg, uint16_t data) { my8080_writeCommand(reg); my8080_writeData(data); } // 设置屏幕显示方向 // 0竖屏 1横屏逆时针转90 void lcd_set_dir(uint8_t dir) { switch(dir) { case 0:// 竖屏 // lcd.width 240; // lcd.height 320; my8080_writeCommand(lcd.cmd.setScanDir); my8080_writeData(0x00); break; case 1: // 横屏 // lcd.width 320; // lcd.height 240; my8080_writeCommand(lcd.cmd.setScanDir); // my8080_writeData(0x68); my8080_writeData(0x60); // RGB565 break; } } void lcd_init(void) { my8080_pinInit(); // // 背光pin初始化 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure {0}; GPIO_InitStructure.GPIO_Pin lcd_BL_PIN; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(lcd_BL_PORT, GPIO_InitStructure); lcd_Config(); lcd_backlight_control(1); // 打开背光 lcd_set_dir(lcd.dir); // 设置显示方向 } // 设置光标位置 void lcd_set_cursor(uint16_t x, uint16_t y) { my8080_writeCommand(lcd.cmd.setX); my8080_writeData(x 8); // x 高8位 my8080_writeData(x 0xFF); // x 低8位 my8080_writeCommand(lcd.cmd.setY); my8080_writeData(y 8); // y 高8位 my8080_writeData(y 0xFF); // y 低8位 } // 指定点设置指定颜色 void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color) { lcd_set_cursor(x, y); my8080_writeCommand(lcd.cmd.setPointColor); my8080_writeData(color); } /** * brief 画线函数 * param s_x,s_y: 起点坐标 * param e_x,e_y: 终点坐标 * param color: 画线颜色 * note */ void lcd_draw_line(uint16_t s_x, uint16_t s_y, uint16_t e_x, uint16_t e_y, uint16_t color) { int16_t dx, dy; int16_t x, y; int16_t incx, incy; int16_t err; // 计算坐标差值 dx e_x - s_x; dy e_y - s_y; // 判断步进方向 if(dx 0) incx 1; else if(dx 0) incx -1; else incx 0; if(dy 0) incy 1; else if(dy 0) incy -1; else incy 0; // 取绝对值 dx dx 0 ? dx : -dx; dy dy 0 ? dy : -dy; x s_x; y s_y; // 斜率绝对值小于1 if(dx dy) { err dx / 2; for(uint16_t i 0; i dx; i) { lcd_draw_point(x, y, color); err - dy; if(err 0) { err dx; y incy; } x incx; } } // 斜率绝对值大于等于1 else { err dy / 2; for(uint16_t i 0; i dy; i) { lcd_draw_point(x, y, color); err - dx; if(err 0) { err dy; x incx; } y incy; } } } /** * brief LCD显示RGB565格式图片 * param x0,y0: 图片左上角起始坐标 * param width: 图片宽度 * param height:图片高度 * param pic: 图片像素数组(取模生成) */ void lcd_show_pic(uint16_t x0,uint16_t y0,uint16_t width,uint16_t height,const uint8_t *pic) { uint16_t x,y; uint16_t color; uint32_t i0; // 逐行扫描 for(y0;yheight;y) { // 逐列扫描 for(x0;xwidth;x) { // RGB565 2字节存一个颜色 color pic[i1]8 | pic[i]; lcd_draw_point(x0x,y0y,color); i2; } } } /** * brief 绘制实心填充矩形 * param x1,y1: 左上角 * param x2,y2: 右下角 * param color: 填充颜色 */ void lcd_draw_fill_rect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { u16 i,j; u16 xlen0; xlenx2-x11; for(iy1;iy2;i) { lcd_set_cursor(x1,i); //设置光标位置 my8080_writeCommand(0x2C); //开始写入GRAM for(j0;jxlen;j) { my8080_writeData(color); } } } /** * brief 绘制空心矩形 * param x1,y1: 左上角坐标 * param x2,y2: 右下角坐标 * param color: 边框颜色 */ void lcd_draw_rect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { // 上边框 lcd_draw_line(x1, y1, x2, y1, color); // 下边框 lcd_draw_line(x1, y2, x2, y2, color); // 左边框 lcd_draw_line(x1, y1, x1, y2, color); // 右边框 lcd_draw_line(x2, y1, x2, y2, color); }