2.8寸LCD屏驱动(ILI9341)
·
软件模拟8080时序驱动2.8寸LCD屏驱动,实现指定位置画点、绘制直线、矩形、显示图片等功能。

完整代码(基于STM32)
my_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);
#endif
my_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.id=my8080_readData(); //dummy read
lcd.id=my8080_readData(); //读到0X00
lcd.id=my8080_readData(); //读取93
lcd.id<<=8;
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 i=0;
// 逐行扫描
for(y=0;y<height;y++)
{
// 逐列扫描
for(x=0;x<width;x++)
{
// RGB565 2字节存一个颜色
color = pic[i+1]<<8 | pic[i];
lcd_draw_point(x0+x,y0+y,color);
i+=2;
}
}
}
/**
* @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 xlen=0;
xlen=x2-x1+1;
for(i=y1;i<=y2;i++)
{
lcd_set_cursor(x1,i); //设置光标位置
my8080_writeCommand(0x2C); //开始写入GRAM
for(j=0;j<xlen;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);
}
更多推荐


所有评论(0)