0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

jf_88434166 来源:jf_88434166 作者:jf_88434166 2025-04-18 10:56 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

前言

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

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

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

关于ST7735

市面采用ST7789驱动IC的屏幕不算少见,本人有幸使用过的屏幕中有一款1.44寸和一款1.8寸的屏幕驱动芯片ST7735,两者的分辨率为128x128128x160,比较遗憾的一个点是这款驱动芯片驱动的一些屏幕市面上分辨率相对比较低,显示效果不如之前使用的ST7789GC9A01好,这里有网上搜集加上自己编写以及移植整理有stm32f10x、stm32f407、arduino、stc89c516、ESP32单片机代码,需要整理好的代码可以在评论区留言邮箱!

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

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

ST7735参数
供电电压3.3~5.5V
驱动ICST7735
分辨率128x128/128x160
尺寸1.44 / 1.8寸
驱动接口4线SPI

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

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

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

stm32驱动

引脚接线

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

stm32f10xST7735
3V3VIN
GNDGND
CSPB6
RSTPA6
DCPA7
SDAPA4
SCLPA5
BLKPB7

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;//速度50MHz
     GPIO_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;//速度50MHz
     GPIO_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[32768] =  { /* 0X10,0X10,0X00,0X80,0X00,0X80,0X01,0X1B, */
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
...................
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驱动库非常方便了用户的使用与移植,供大家共同学习进步,前行路上,优信与大家同在,欢迎一键三连,感谢各位大佬!

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5210

    文章

    20680

    浏览量

    337366
  • STM32
    +关注

    关注

    2313

    文章

    11195

    浏览量

    374749
  • Arduino
    +关注

    关注

    190

    文章

    6527

    浏览量

    197515
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    51单片机驱动HMI串口屏,串口屏的下载方式

    串口屏 串口屏是一个集成了单片机屏幕模块,采用的是TTL串口协议,可以直接通过对应指令控制屏幕, 本文采用的串口屏是T0系列的基本型,目的是通过单片机的串口来控制串口屏 串口屏的程序
    的头像 发表于 03-17 11:44 351次阅读
    <b class='flag-5'>51</b><b class='flag-5'>单片机</b><b class='flag-5'>驱动</b>HMI串口屏,串口屏的下载方式

    ST7LITE1xB 8 位单片机:功能特性与应用解析

    ST7LITE1xB 8 位单片机:功能特性与应用解析 在电子工程领域,单片机作为核心控制元件,广泛应用于各种嵌入式系统中。ST7LITE1xB 系列
    的头像 发表于 03-02 15:10 478次阅读

    TFT-LCD液晶驱动线路及其激光修复方法

    一、引言 TFT-LCD液晶驱动线路是实现像素精准驱动与显示控制的核心链路,主要由栅极驱动线路(横向)、数据驱动线路(纵向)及薄膜晶体管(
    的头像 发表于 02-12 15:08 815次阅读

    小白也能听懂的单片机知识路径

    已经掌握了51单片机的基础知识,包括编程逻辑、硬件接口。这将有助于你更快地适应STM32的学习节奏。 STM32学习要点: 硬件平台:选
    发表于 02-04 16:44

    RA MCU众测宝典 | SPI驱动TFT屏幕

    IC是ST7735。实验的主要目的是根据屏幕的引脚定义来调用FSP库的SPI功能,为之后的项目模块整合打个基础。01硬件部分1.8寸TFT屏幕的引脚定义如下:观察
    的头像 发表于 02-03 17:02 7817次阅读
    RA MCU众测宝典 | SPI<b class='flag-5'>驱动</b><b class='flag-5'>TFT</b><b class='flag-5'>屏幕</b>

    STM32驱动4寸ST7796S LCD-TFT

    屏幕驱动芯片ST7796S最大支持320*480分辨率的屏幕,显存GRAM达345600字节,支持8/9/16/18/24位并口数据总线,还支持3/4线制SPI通信。
    的头像 发表于 02-01 11:15 3048次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>驱动</b>4寸<b class='flag-5'>ST</b>7796S LCD-<b class='flag-5'>TFT</b>屏

    类似51单片机可以能驱动智能显示模块吗?

    51单片机就可以驱动智能显示模块吗?
    发表于 01-19 15:50

    51单片机RS485编程实例资料

    详细介绍51单片机RS485通信接线和编程代码
    发表于 10-20 14:57 6次下载

    INA240电流检测放大器使用及电流计算(附STM32驱动代码

    引脚定义、4种可选增益及电流量程计算公式,并通过实例演示了如何计算最大/最小电流。用stm32单片机实现电压、电流的实时采样检测并显示。适用于电机驱动、螺线管控制需要精确电流检测的场
    的头像 发表于 09-28 17:32 2113次阅读
    INA240电流检测放大器使用及电流计算(附<b class='flag-5'>STM32</b><b class='flag-5'>驱动</b><b class='flag-5'>代码</b>)

    [ADC/AFE] [求助] 求CS1239的驱动代码和资料

    正在准备使用贵司的CS1239应用到我们的项目中,希望能提供该芯片的单片机驱动代码51STM32)、单端应用的参考原理图和数据手册,谢谢
    发表于 09-26 09:14

    单片机最小系统工作原理及搭建

    单片机最小系统是指使单片机正常运行所需的最简电路配置,它是所有单片机应用的开发基础。以下是其核心组成、工作原理及搭建指南: 一、最小系统核心组成 单片机芯片 常见型号 :STC89C
    的头像 发表于 08-11 10:55 4390次阅读
    <b class='flag-5'>单片机</b>最小系统工作原理及搭建

    单片机怎么驱动电机?

    在各类自动化设备和智能装置中,电机是重要的执行部件,而单片机作为控制核心,需要通过特定的方式驱动电机运转。单片机驱动电机并非直接连接即可,而是要根据电机类型和功率,搭配合适的
    的头像 发表于 07-25 09:31 1349次阅读

    AT89C51 单片机中文资料

    电子发烧友网站提供《AT89C51 单片机中文资料.pdf》资料免费下载
    发表于 06-24 15:29 1次下载

    使用USB转TTL串口板和ST-LINK调试下载器给STM32单片机下载程序

    本文详细介绍如何使用ST-LINK/V2和USB转TTL串口板为STM32单片机下载程序,包括STM32启动模式、JTAG与SWD接口对比、驱动
    的头像 发表于 06-20 17:26 3287次阅读
    使用USB转TTL串口板和<b class='flag-5'>ST</b>-LINK调试下载器给<b class='flag-5'>STM32</b><b class='flag-5'>单片机</b>下载程序

    2.4寸TFT彩屏配套测试程序-51单片机

    如题,2.4寸TFT彩屏配套测试程序-51单片机
    发表于 06-04 16:26 0次下载