[其他ST产品] ST7789-TFT屏幕驱动(整理有stm32/51单片机/arduino等驱动代码)

[复制链接]
 楼主| 发GV第几啊 发表于 2023-3-30 16:41 | 显示全部楼层 |阅读模式
前言

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

       后续我们将陆续分享有关ST7789、GC9A01、ST7735、ILI9341等驱动IC的屏幕驱动案例。

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

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

3317264254b397f365.png
————————————————

评论

版权声明:本文为CSDN博主「优信电子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_42250136/article/details/126854335  发表于 2023-3-30 16:41
 楼主| 发GV第几啊 发表于 2023-3-30 16:42 | 显示全部楼层
综合了解并观察屏幕一下的一些参数之后开始进行驱动。

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

1232264254b7db9662.png
 楼主| 发GV第几啊 发表于 2023-3-30 16:42 | 显示全部楼层
产商在屏幕设计上添加了3.3V稳压芯片以及电平转换芯片,使得这款原本3.3V供电的裸屏可以兼容5V和3.3V的单片机,这也意味着arduino和51单片机的用户也可以驱动这款屏幕了,虽然51单片机性能很一般但总比不能驱动的好。

       最后了解各个引脚功能之后就可以开始进行驱动
4819664254b8daf2de.png
 楼主| 发GV第几啊 发表于 2023-3-30 16:48 | 显示全部楼层
stm32驱动
引脚接线

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

5272664254cd3c15e3.png
 楼主| 发GV第几啊 发表于 2023-3-30 16:48 | 显示全部楼层
   BLK背光引脚不用可以悬空不接

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

       驱动成功之后用户可以开始移植代码。
 楼主| 发GV第几啊 发表于 2023-3-30 16:48 | 显示全部楼层
代码移植
       文件复制

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

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

void delay_ms(u16 a)

    1

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

       和上面的接线不变,编写下面主函数先进行测试
 楼主| 发GV第几啊 发表于 2023-3-30 16:49 | 显示全部楼层
  1. int main(void)
  2. {
  3.         LCD_Init();
  4.         LCD_Fill(0,0,LCD_W,LCD_H,WHITE);   //填充为白色背景色
  5.         while(1)
  6.         {
  7.                 LCD_ShowPicture(0,0,LCD_W,LCD_H,YXDZ_**);   //显示一张图片
  8.         }
  9. }
 楼主| 发GV第几啊 发表于 2023-3-30 16:50 | 显示全部楼层
     端口修改

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

  1. //-----------------LCD端口定义----------------

  2. #define LCD_SCLK_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_5)//SCL=SCLK
  3. #define LCD_SCLK_Set() GPIO_SetBits(GPIOA,GPIO_Pin_5)

  4. #define LCD_MOSI_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_4)//SDA=MOSI
  5. #define LCD_MOSI_Set() GPIO_SetBits(GPIOA,GPIO_Pin_4)

  6. #define LCD_RES_Clr()  GPIO_ResetBits(GPIOA,GPIO_Pin_6)//RES
  7. #define LCD_RES_Set()  GPIO_SetBits(GPIOA,GPIO_Pin_6)

  8. #define LCD_DC_Clr()   GPIO_ResetBits(GPIOA,GPIO_Pin_7)//DC
  9. #define LCD_DC_Set()   GPIO_SetBits(GPIOA,GPIO_Pin_7)
  10.                      
  11. #define LCD_CS_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_6)//CS
  12. #define LCD_CS_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_6)

  13. #define LCD_BLK_Clr()  GPIO_ResetBits(GPIOB,GPIO_Pin_7)//BLK
  14. #define LCD_BLK_Set()  GPIO_SetBits(GPIOB,GPIO_Pin_7)
 楼主| 发GV第几啊 发表于 2023-3-30 16:51 | 显示全部楼层
  但值得注意的是仅仅修改这里的宏定义是没办法使用的,在lcdfont.c文件中包含着对GPIO引脚以及时钟初始化的函数需要进行端口的修改

  1. void LCD_GPIO_Init(void)
  2. {
  3.         GPIO_InitTypeDef  GPIO_InitStructure;
  4.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);         //使能端口时钟
  5.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;         
  6.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
  7.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
  8.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  9.         GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
  10.        
  11.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
  12.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
  13.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
  14.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  15.         GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);
  16. }
 楼主| 发GV第几啊 发表于 2023-3-30 16:51 | 显示全部楼层
修改完这里之后才算是将端口修改完毕

       在lcdfont.h顶部还有两个宏定义可以自行决定是否修改,分别对应这屏幕显示方向和屏幕分辨率的参数
  1. #define USE_HORIZONTAL 0  //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏

  2. #define LCD_W 240
  3. #define LCD_H 240
 楼主| 发GV第几啊 发表于 2023-3-30 17:04 | 显示全部楼层
显示函数

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

  1. void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color);//指定区域填充颜色
  2. void LCD_DrawPoint(u16 x,u16 y,u16 color);//在指定位置画一个点
  3. void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color);//在指定位置画一条线
  4. void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color);//在指定位置画一个矩形
  5. void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color);//在指定位置画一个圆

  6. void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示汉字串
  7. void LCD_ShowChinese12x12(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个12x12汉字
  8. void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个16x16汉字
  9. void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个24x24汉字
  10. void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个32x32汉字

  11. void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode);//显示一个字符
  12. void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode);//显示字符串
  13. u32 mypow(u8 m,u8 n);//求幂
  14. void LCD_ShowIntNum(u16 x,u16 y,u16 num,u8 len,u16 fc,u16 bc,u8 sizey);//显示整数变量
  15. void LCD_ShowFloatNum1(u16 x,u16 y,float num,u8 len,u16 fc,u16 bc,u8 sizey);//显示两位小数变量

  16. void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[]);//显示图片


  17. //画笔颜色
  18. #define WHITE                  0xFFFF
  19. #define BLACK                  0x0000          
  20. #define BLUE                    0x001F  
  21. #define BRED             0XF81F
  22. #define GRED                                0XFFE0
  23. #define GBLUE                               0X07FF
  24. #define RED                    0xF800
  25. #define MAGENTA                0xF81F
  26. #define GREEN                  0x07E0
  27. #define CYAN                   0x7FFF
  28. #define YELLOW                 0xFFE0
  29. #define BROWN                              0XBC40 //棕色
  30. #define BRRED                              0XFC07 //棕红色
  31. #define GRAY                               0X8430 //灰色
  32. #define DARKBLUE               0X01CF        //深蓝色
  33. #define LIGHTBLUE               0X7D7C        //浅蓝色  
  34. #define GRAYBLUE                0X5458 //灰蓝色
  35. #define LIGHTGREEN              0X841F //浅绿色
  36. #define LGRAY                              0XC618 //浅灰色(PANNEL),窗体背景色
  37. #define LGRAYBLUE        0XA651 //浅灰蓝色(中间层颜色)
  38. #define LBBLUE           0X2B12 //浅棕蓝色(选择条目的反色)
 楼主| 发GV第几啊 发表于 2023-3-30 17:04 | 显示全部楼层
       在使用的时候只需要看后面的中文注释去调用对应的函数即可,非常方便使用

       但是如果需要显示文字和图片的话只是直接调用上面的函数还不够,汉字数组存储的lcdfont.h文件中只包含了中英文字母、数字、符号以及非常少量的中文数组,中文数组存储在以下几个数组中,按照相同的格式自行添加进去即可
 楼主| 发GV第几啊 发表于 2023-3-30 17:05 | 显示全部楼层
中文汉字数组
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,
};
 楼主| 发GV第几啊 发表于 2023-3-30 17:06 | 显示全部楼层
图片

       图片存储在image.h文件中,图片文件中的内容比较简单,一个纯数组取模放进去的
const unsigned char YXDZ_**[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,
};
 楼主| 发GV第几啊 发表于 2023-3-30 17:07 | 显示全部楼层
记得在数组前面加const就行
其他单片机驱动

       使用其他单片机编写的代码显示的效果与上面的STM32的相同,都是一张图片,空间不够的单片机只是显示了一张小一点的图片。
 楼主| 发GV第几啊 发表于 2023-3-30 17:08 | 显示全部楼层
51单片机

       51单片机程序由stm32的移植过去的,所以是一样的使用,唯一的区别是51单片机空间小显示不了大图片,速度也比较慢。
 楼主| 发GV第几啊 发表于 2023-3-30 17:08 | 显示全部楼层
arduino/ESP32

       arduino和ESP32的代码也是从原来STM32的移植过去的,不过因为编译器不同做了比较多的修改,总体上做的函数接口和stm32的是一致的并没有做修改,由于数据兼容性不一样在调用汉字显示之类的功能的时候需要对数据做类型转换,如下所示的中文汉字显示函数调用。
 楼主| 发GV第几啊 发表于 2023-3-30 17:08 | 显示全部楼层
  1. LCD_ShowChinese(0,0,(unsigned char*)"优信电子",RED,WHITE,32,0);

 楼主| 发GV第几啊 发表于 2023-3-30 17:08 | 显示全部楼层
其他的参数没发现有哪里和STM32函数上的不同,由于是移植,并没有像C++一样做库进行使用(还是懒。。。),所以函数修改还是在文件中进行修改,而不是声明的方式去定义使用引脚,用户修改使用引脚的话只需要打开lcd_init.h文件找到下面的代码段,看到了自然知道怎么进行修改。
 楼主| 发GV第几啊 发表于 2023-3-30 17:09 | 显示全部楼层
//-----------------LCD端口定义----------------
#define CS 5
#define RST 33
#define DC 27
#define SDA 23
#define SCL 18
#define BLK 22
您需要登录后才可以回帖 登录 | 注册

本版积分规则

20

主题

323

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部