ST7789-TFT屏幕驱动 & 整理有stm32/51单片机/arduino等驱动代码

  • 前言
  • 关于ST7789
  • stm32驱动
    • 引脚接线
    • 代码移植
      • 文件复制
      • 端口修改
      • 显示函数
      • 中文汉字数组
      • 图片
  • 其他单片机驱动
    • 51单片机
    • arduino/ESP32
  • 总结

前言

不久前我们收到用户反馈问题中,多次反馈各种不同型号的屏幕驱动不起来,从0开始编写代码花费大量时间,也有不少初次学习驱动屏幕代码编写经验过少等问题,为此我们决定以文章的形式发布到CSDN来分享相应的一些经验以及收集整理好的资料,希望可以帮助用户更加简单的学习或快速移植代码进行项目开发。

后续我们将陆续分享有关ST7789GC9A01ST7735ILI9341等驱动IC的屏幕驱动案例。

还是老样子需要整理好的代码可以在评论区留言或私信邮箱!

关于ST7789

市面采用ST7789驱动IC的屏幕不算少见,本人有幸使用过的屏幕中有一款1.3寸和一款1.54寸的屏幕驱动芯片为ST7789,两者的分辨率均为240x240,网上搜集加上自己编写以及移植整理有stm32f10x、stm32f407、arduino、stc89c516、ESP32等单片机代码,需要整理好的代码可以在评论区留言或私信邮箱!

综合了解并观察屏幕一下的一些参数之后开始进行驱动。

硬件接口使用的 2.54mm 间距的排针接口,这使用杜邦线进行连接,需要设计到自己的PCB上高度也是刚好匹配上面的铜柱做定位使用的。

ST7789 参数
供电电压 3.3~5.5V
驱动IC ST7789
分辨率 240x240
尺寸 1.3 / 1.54寸
驱动接口 4线SPI

产商在屏幕设计上添加了3.3V稳压芯片以及电平转换芯片,使得这款原本3.3V供电的裸屏可以兼容5V和3.3V的单片机,这也意味着arduino51单片机的用户也可以驱动这款屏幕了,虽然51单片机性能很一般但总比不能驱动的好。

最后了解各个引脚功能之后就可以开始进行驱动

引脚名称 引脚功能
VCC 电源正,3.3 - 5V,需要与通信电平一致
GND 电源负,地
CS 片选,低电平使能
RST 复位,低电平使能
DC 数据/命令选择,低电平命令,高电平数据
SDA SPI数据输入端口
SCL SPI时钟信号输入端口
BLK 背光,悬空使能接地关闭,默认上拉至3.3V

stm32驱动

引脚接线

代码方面先按照下表接好线烧录程序之后再对代码移植的关键部分进行说明

stm32f10x ST7789
3V3 VIN
GND GND
CS PB6
RST PA6
DC PA7
SDA PA4
SCL PA5
BLK PB7

BLK背光引脚不用可以悬空不接

默认的代码烧录进行之后显示上面图片中大大的 优信电子logo,先把示例代码驱动起来,如果示例代码驱动不起来先检查一下接线供电方面的问题,不然后面代码改了半天没有用找问题就和我刚驱动的时候一样头皮发麻。


       驱动成功之后用户可以开始移植代码。

代码移植

文件复制

lcdlcd_initC文件h文件复制到自己的工程里面,这四个文件包含屏幕初始化以及驱动画点划线显示文字图像的代码。
       另外还有两个文件为image.hlcdfont.h,这两个文件分别存储显示图片数组与显示文字数组。

复制到自己工程中编译后会报错,因为缺少了pbdata.h中的毫秒级延时函数,可以把原工程中的ms延时函数复制过来也可以使用自己编写的,名称与下面的相同即可

void delay_ms(u16 a)

添加好文件到工程里面之后再次编译一般不会报错,如果仍然报错就只能看具体报错信息去修改了

和上面的接线不变,编写下面主函数先进行测试

int main(void)
{LCD_Init();LCD_Fill(0,0,LCD_W,LCD_H,WHITE);   //填充为白色背景色while(1){LCD_ShowPicture(0,0,LCD_W,LCD_H,YXDZ_logo);   //显示一张图片}
}

需要用户修改的接口一般有一下几个点

端口修改

lcdfont.h文件中包含对使用引脚的宏定义,修改其中的GPIO以及引脚即可修改使用的端口

//-----------------LCD端口定义---------------- #define LCD_SCLK_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_5)//SCL=SCLK
#define LCD_SCLK_Set() GPIO_SetBits(GPIOA,GPIO_Pin_5)#define LCD_MOSI_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_4)//SDA=MOSI
#define LCD_MOSI_Set() GPIO_SetBits(GPIOA,GPIO_Pin_4)#define LCD_RES_Clr()  GPIO_ResetBits(GPIOA,GPIO_Pin_6)//RES
#define LCD_RES_Set()  GPIO_SetBits(GPIOA,GPIO_Pin_6)#define LCD_DC_Clr()   GPIO_ResetBits(GPIOA,GPIO_Pin_7)//DC
#define LCD_DC_Set()   GPIO_SetBits(GPIOA,GPIO_Pin_7)#define LCD_CS_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_6)//CS
#define LCD_CS_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_6)#define LCD_BLK_Clr()  GPIO_ResetBits(GPIOB,GPIO_Pin_7)//BLK
#define LCD_BLK_Set()  GPIO_SetBits(GPIOB,GPIO_Pin_7)

但值得注意的是仅仅修改这里的宏定义是没办法使用的,在lcdfont.c文件中包含着对GPIO引脚以及时钟初始化的函数需要进行端口的修改

void LCD_GPIO_Init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);     //使能端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);
}

修改完这里之后才算是将端口修改完毕

lcdfont.h顶部还有两个宏定义可以自行决定是否修改,分别对应这屏幕显示方向屏幕分辨率的参数

#define USE_HORIZONTAL 0  //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏#define LCD_W 240
#define LCD_H 240

显示函数

lcd.h中包含了屏幕显示内容的函数,以及部分颜色的色号主要用于刷新屏幕背景色

void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color);//指定区域填充颜色
void LCD_DrawPoint(u16 x,u16 y,u16 color);//在指定位置画一个点
void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color);//在指定位置画一条线
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color);//在指定位置画一个矩形
void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color);//在指定位置画一个圆void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示汉字串
void LCD_ShowChinese12x12(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个12x12汉字
void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个16x16汉字
void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个24x24汉字
void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个32x32汉字void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode);//显示一个字符
void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode);//显示字符串
u32 mypow(u8 m,u8 n);//求幂
void LCD_ShowIntNum(u16 x,u16 y,u16 num,u8 len,u16 fc,u16 bc,u8 sizey);//显示整数变量
void LCD_ShowFloatNum1(u16 x,u16 y,float num,u8 len,u16 fc,u16 bc,u8 sizey);//显示两位小数变量void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[]);//显示图片//画笔颜色
#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 //灰色
#define DARKBLUE         0X01CF //深蓝色
#define LIGHTBLUE        0X7D7C //浅蓝色
#define GRAYBLUE         0X5458 //灰蓝色
#define LIGHTGREEN       0X841F //浅绿色
#define LGRAY                0XC618 //浅灰色(PANNEL),窗体背景色
#define LGRAYBLUE        0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE           0X2B12 //浅棕蓝色(选择条目的反色)

在使用的时候只需要看后面的中文注释调用对应的函数即可,非常方便使用

但是如果需要显示文字图片的话只是直接调用上面的函数还不够,汉字数组存储的lcdfont.h文件中只包含了中英文字母数字符号以及非常少量的中文数组,中文数组存储在以下几个数组中,按照相同的格式自行添加进去即可

中文汉字数组

typedef struct
{unsigned char Index[2];    unsigned char Msk[24];
}typFNT_GB12;
const typFNT_GB12 tfont12[]={"优",0x24,0x01,0x24,0x02,0x22,0x00,0xFA,0x07,0xA3,0x00,0xA2,0x00,0xA2,0x00,0xA2,0x00,
0x92,0x00,0x92,0x04,0x8A,0x04,0x06,0x07,
"信",0x44,0x00,0x84,0x00,0xFA,0x07,0x02,0x00,0xF3,0x03,0x02,0x00,0xF2,0x03,0x02,0x00,
0xF2,0x03,0x12,0x02,0xF2,0x03,0x12,0x02,
"电",0x10,0x00,0x10,0x00,0xFF,0x01,0x11,0x01,0x11,0x01,0xFF,0x01,0x11,0x01,0x11,0x01,
0xFF,0x01,0x11,0x04,0x10,0x04,0xE0,0x07,
"子",0x00,0x00,0xFC,0x01,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0xFF,0x07,0x20,0x00,
0x20,0x00,0x20,0x00,0x20,0x00,0x38,0x00,
};typedef struct
{unsigned char Index[2];    unsigned char Msk[32];
}typFNT_GB16;
const typFNT_GB16 tfont16[]={"优",0x10,0x09,0x10,0x11,0x10,0x11,0x08,0x01,0xE8,0x7F,0x0C,0x05,0x0C,0x05,0x0A,0x05,
0x09,0x05,0x08,0x05,0x88,0x04,0x88,0x44,0x88,0x44,0x48,0x44,0x48,0x78,0x28,0x00,
"信",0x10,0x02,0x10,0x04,0xD0,0x7F,0x08,0x00,0x08,0x00,0x8C,0x3F,0x0C,0x00,0x0A,0x00,
0x89,0x3F,0x08,0x00,0x08,0x00,0x88,0x3F,0x88,0x20,0x88,0x20,0x88,0x3F,0x88,0x20,
"电",0x80,0x00,0x80,0x00,0x80,0x00,0xFC,0x1F,0x84,0x10,0x84,0x10,0x84,0x10,0xFC,0x1F,
0x84,0x10,0x84,0x10,0x84,0x10,0xFC,0x1F,0x84,0x50,0x80,0x40,0x80,0x40,0x00,0x7F,
"子",0x00,0x00,0xFE,0x1F,0x00,0x08,0x00,0x04,0x00,0x02,0x80,0x01,0x80,0x00,0xFF,0x7F,
0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xA0,0x00,0x40,0x00,
};

数组名字里面的GB12GB16代表了12号字体16号字体的数组,文件中也有24号32号

图片

图片存储在image.h文件中,图片文件中的内容比较简单,一个纯数组取模放进去的

const unsigned char YXDZ_logo[115200] = { /*0X10,0X10,0X00,0XF0,0X00,0XF0,0X01,0X1B,*/
0XFF,0XDF,0XFF,0XDF,0XFF,0XDF,0XFF,0XFF,0XFF,0XFF,0XFF,0XDF,0XFF,0XDF,0XFF,0XDF,
...................
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
};

记得在数组前面加const就行

其他单片机驱动

使用其他单片机编写的代码显示的效果与上面的STM32的相同,都是一张图片,空间不够的单片机只是显示了一张小一点的图片。

51单片机

51单片机程序由stm32的移植过去的,所以是一样的使用,唯一的区别是51单片机空间小显示不了大图片,速度也比较慢。

arduino/ESP32

arduinoESP32的代码也是从原来STM32的移植过去的,不过因为编译器不同做了比较多的修改,总体上做的函数接口stm32的是一致的并没有做修改,由于数据兼容性不一样在调用汉字显示之类的功能的时候需要对数据做类型转换,如下所示的中文汉字显示函数调用。

LCD_ShowChinese(0,0,(unsigned char*)"优信电子",RED,WHITE,32,0);

其他的参数没发现有哪里和STM32函数上的不同,由于是移植,并没有像C++一样做库进行使用(还是懒。。。),所以函数修改还是在文件中进行修改,而不是声明的方式去定义使用引脚,用户修改使用引脚的话只需要打开lcd_init.h文件找到下面的代码段,看到了自然知道怎么进行修改。

//-----------------LCD端口定义----------------
#define CS 5
#define RST 33
#define DC 27
#define SDA 23
#define SCL 18
#define BLK 22

没有采用硬件SPI,所以速度没有想象中的那么快,确实肉眼可见的慢了很多。

总结

后续我们将编写、移植或者收集测试好的一些屏幕代码分享相应的一些LCD、OLED等显示器件的驱动案例,也由衷的感谢中景园开源了如此优秀的LCD驱动库非常方便了用户的使用与移植,供大家共同学习进步,前行路上,优信与大家同在,欢迎一键三连,感谢各位大佬!

ST7789-TFT屏幕驱动(整理有stm32/51单片机/arduino等驱动代码)相关推荐

  1. GC9A01-TFT屏幕驱动(整理有stm32/51单片机/arduino等驱动代码)

    GC9A01-TFT屏幕驱动 & 整理有stm32/51单片机/arduino等驱动代码 前言 关于GC9A01 stm32驱动 引脚接线 代码移植 文件复制 端口修改 显示函数 中文汉字数组 ...

  2. ST7735-TFT屏幕驱动(整理有stm32/51单片机/arduino等驱动代码)

    ST7735-TFT屏幕驱动 & 整理有stm32/51单片机/arduino等驱动代码 前言 关于ST7735 stm32驱动 引脚接线 代码移植 文件复制 端口修改 显示函数 中文汉字数组 ...

  3. 51单片机 IIC OLED驱动显示通用程序模板

    51单片机 IIC OLED驱动显示通用程序模板 本模板是通过中景园OLED屏幕资料中提取保留ASCII字符集,点阵大小:6x8和8X16. 汉字取模方式 取模软件:pctolcd2002 /汉字取模 ...

  4. 74hc164驱动数码管c语言程序,基于51单片机的74HC164驱动数码管显示程序与仿真

    基于51单片机的74HC164驱动数码管显示程序与仿真 基于51单片机的74HC164驱动一位数码管显示程序与仿真 #include #include #define uchar unsigned c ...

  5. 基于51单片机的OLED驱动方式(iic通讯方式)

    基于51单片机的OLED驱动方式(iic通讯方式) 前言: 本人从事硬件开发,自学软件,因为发现在学习过程中,有很多问题对于没有项目实战经验的新手来讲太难解决了,可以说基本上是无从下手.现将自己学习过 ...

  6. STM32/51单片机实训day7——电机驱动|ULN2003A步进电机|Proteus电路设计|旋转角度控制函数|驱动函数|Keil5程序设计

    目录 1  ULN2003A步进电机简介 2  步进电机电路设计 3 旋转角度控制函数 4 程序设计 motor.c motor.h 前期LCD参考文章:​​​​​​​ 内  容:编程实现控制步进电机 ...

  7. LCD12864驱动(Proteus中用51单片机驱动AMPIRE128X64)

    致谢:先贴张图来感谢一下我那傻逼的王志学长,要不是你给我的资料跟我用的LCD型号不一样,我TM早就驱动起来了. 填坑:1.TMD Proteus的AMPIRE128X64这个型号的LCD内部没有所谓的 ...

  8. 51单片机DS18B20温度驱动

    51单片机DS18B20温度传感器驱动,仅有.h文件,无.c文件. /***************************************************************** ...

  9. 51单片机50个实例代码_【附代码】51单片机电子密码锁教程

    简介 大家好,这篇文章的内容是关于如何用51单片机来制作一个电子密码锁的教程,通过这篇教程可以让刚入门的朋友了解矩阵键盘.LCD1602的使用方法,以及密码输入和修改的程序介绍,我会对每个部分进行详细 ...

  10. 51单片机50个实例代码_常用的51单片机代码

    51单片机实验板原理图 1.流水灯实验 #include void delay(unsigned int Cnt){unsigned int t;while(Cnt--){t = 120;while( ...

最新文章

  1. 协同过滤:基于用户的协同过滤itemCF
  2. 手把手教你写C语言的动态库的开发
  3. python进程池和线程池_Python中的进程池与线程池(包含代码)
  4. 【iOS-Cocos2d游戏开发之七】添加/删除系统组件,并解决View设置透明会影响View中的其他组件的问题!...
  5. Teamviewer远程黑屏
  6. c语言 步进电机 程序,步进电机c语言控制程序
  7. 贪心 学员 高阶机器学习 魔鬼·训练营
  8. java dead store_jcip Java并发编程实战源码,这本书名为《 践》有些抹杀了它的价值,其中 Develop 238万源代码下载- www.pudn.com...
  9. 今日小程序推荐:文艺青年必备「轻芒杂志」
  10. python之pandas基础知识以及练习题
  11. PythonStock(37)股票系统:Python股票系统发布V2.0版本,改个名字吧,叫Python全栈股票系统2.0,可以实现数据的抓取(akshare),统计分析,数据报表展示。
  12. VS单解决方案多项目多DLL多exe管理
  13. 实变函数—有限覆盖定理的证明
  14. 界面今日头条:2018年中国旅游城市排行榜
  15. 租房子,光看数据怎么够,Python爬取某站租房图片
  16. LibGDX QQ群建立,欢迎对libGDX有兴趣的程序员加入。
  17. 368 银河(强连通分量)
  18. 史上最壕年会!微信送每人一台高配定制版iPhone X
  19. 传智健康2.0-6-移动端开发-体检预约
  20. 丛林战争游戏数据库设计

热门文章

  1. OJ密码岛 1243.谢尔宾斯基三角形
  2. Cpu调优 mpstat 命令
  3. minic 类型声明与变量定义句型处理
  4. PackageManager使用
  5. LeetCode题解:猜数字大小
  6. 新唐MS51FB9AE串口烧录程序
  7. 计网·网线制作(第二课)
  8. 如何在知网下载PDF格式的硕博毕业论文?
  9. python爬虫数据(中国人口信息)存入MYSQL数据库
  10. 将Table转换成HTML