前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >基于STM32 HAL库硬件SPI的ST7789驱动(TFT-LCD 240*320)

基于STM32 HAL库硬件SPI的ST7789驱动(TFT-LCD 240*320)

作者头像
用户8913398
发布于 2021-08-16 04:22:56
发布于 2021-08-16 04:22:56
8.9K13
代码可运行
举报
运行总次数:3
代码可运行

  在日常开发项目中,显示屏是经常使用的一个部件,显示屏的种类也是多种多样,但对于开发者来说,主要关心的是显示屏所用到的驱动芯片,本次给小伙伴们带来的是 STM32 下的 HAL 库硬件 SPI 驱动 320*240 分辨率的 TFT-LCD,LCD 显示屏驱动芯片为 ST7789,一步步实现如何驱动此类驱动芯片的 LCD 屏幕,话不多说,上干货!

  • 完成目标

1、cubemx配置硬件SPI

2、驱动240*320分辨率LCD显示屏(驱动芯片为ST7789)

  • 硬件环境

1、STM32F103C8T6(自设计)

2、ST7789驱动LCD显示屏

  • 软件环境

1、cubemx

2、keil5

一、cubemx配置硬件SPI及LCD相关引脚

1.1 时钟配置

  第一步仍然是时钟配置,由于板子上设计没有预留外部晶振,我使用的是内部RC振荡器,内部RC振荡器只能配置到64MHZ,如下,如果你使用的是外部晶振,最大到72MHZ

1.2 LCD与STM32硬件连接关系

LCD

MCU

LCD-RST

PB1

LCD-CS

PB0

LCD-DC

PA4

LCD-MOSI

PA7

LCD-CLK

PA5

LCD-LDE+

VCC-3.3(可接IO控制)

LCD-LDE-

GND

LCD-VCC

VCC-3.3V

LCD-GND

GND

1.3 LCD相关引脚配置

  本次使用的是SPI1,对SPI1的引脚及参数进行配置,相关IO初始化状态可以根据需要进行配置u,比如CS引脚,拉低有效,初始化我们可以配置为高,根据自己需要进行配置即可

  小伙伴们有没有遇到过配置完发现不能仿真,这里需要设置一下,根据自己的仿真器接口进行配置,是SWD模式还是JTAG模式

生成工程配置,配置完之后,直接点击生成即可,注意工程路径不要有中文,记得以前可以有,不知道什么时候有的臭毛病...只能按照做了

二、代码编写

  先定义LCD相关引脚,CS、RST、DC

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define LCD_REST_LOW()   HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET);
#define LCD_REST_HIGH()  HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET);

#define LCD_DC_LOW()     HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_RESET);
#define LCD_DC_HIGH()    HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET);

#define LCD_CS_LOW()     HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
#define LCD_CS_HIGH()    HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);

#define LCD_WR_RS(n) (n?HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_RESET))

  定义用到的几个基本函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @brief  写16位的数据(两个字节)到LCD
 * @param   dat —— 需要发送的16bit数据
 * @return  none
 */
void LCD_Write_2Bytes(const uint16_t dat)
{
    uint8_t data[2] = {0};

    data[0] = dat >> 8;
    LCD_data_write(data[0]);
    data[1] = dat;
    LCD_data_write(data[1]);

    // LCD_SPI_Send(data, 2);
}

void LCD_command_write(uint8_t command)
{ // 写命令
    LCD_DC_LOW();
    LCD_CS_LOW();
    lcd_SendBytes(command);
    LCD_CS_HIGH();
}
void LCD_data_write(uint8_t data)
{ //写数据
    LCD_DC_HIGH();
    LCD_CS_LOW();
    lcd_SendBytes(data);
    LCD_CS_HIGH();
}

void delay_lcd(unsigned int time)
{
    while (time)
    {
        time--;
        time--;
        time--;
        time--;
    }
}

void LCD_Reset(void)
{
    LCD_REST_HIGH();
    delay_lcd(1000);
    LCD_REST_LOW();
    delay_lcd(10000);
    LCD_REST_HIGH();
    delay_lcd(10000);
    LCD_CS_HIGH();
}

LCD行列设置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//========================================================
//CASET (2Ah): Column Address Set
//RASET (2Bh): Row Address Set
//x1,y1:起始地址,x2,y2:终点地址
//========================================================
void lcd_set_address(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
    LCD_command_write(0x2a);
    LCD_data_write(x1 >> 8);
    LCD_data_write(x1);
    LCD_data_write(x2 >> 8);
    LCD_data_write(x2);

    LCD_command_write(0x2b);
    LCD_data_write(y1 >> 8);
    LCD_data_write(y1);
    LCD_data_write(y2 >> 8);
    LCD_data_write(y2);

    LCD_command_write(0x2C); // write_ram
}

LCD初始化代码,这部分主要是参考网上已经完成的,相关配置可以在手册具体查看

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void lcd_init(void)
{

    LCD_CS_HIGH();
    LCD_Reset();

    /************* display Setting *************/
    LCD_command_write(0x01);
    delay_lcd(10000);
    LCD_command_write(LCD_CMD_SLPOUT);
    delay_lcd(10000);
 
  //修改此处,可以改变屏幕的显示方向,横屏,竖屏等
    LCD_command_write(LCD_CMD_MADCTL); // 0x36  ///< Memory Data Access Control
    LCD_data_write(0x00);              //50//40//C0

    LCD_command_write(LCD_CMD_COLMOD); //  0x3A     ///< Interface Pixel Format
    LCD_data_write(0x05);              /// 16bit/pixel

    /*********** Frame Rate Setting ***********/
    LCD_command_write(LCD_CMD_PORCTRL); //0xB2     ///< Porch Setting
    LCD_data_write(0x0c);               ///< Back porch in normal mode
    LCD_data_write(0x0c);               ///< Front porch in normal mode
    LCD_data_write(0x00);               ///< Disable separate porch control
    LCD_data_write(0x33);               ///< Back and front porch in idle mode
    LCD_data_write(0x33);               ///< Back and front porch in partial mode

    LCD_command_write(LCD_CMD_GCTRL); //  0xB7     ///< Gate Control
    LCD_data_write(0x72);             ///< VGH:13.26, VGL:-10.43

    LCD_command_write(LCD_CMD_VCOMS); // 0xBB     ///< VCOM Setting
    LCD_data_write(0x3d);             ///< VCOM: 1.425

    LCD_command_write(LCD_CMD_LCMCTRL); ///0xC0     ///< LCM Control
    LCD_data_write(0x2c);

    LCD_command_write(LCD_CMD_VDVVRHEN); //0xC2     ///< VDV and VRH Command Enable
    LCD_data_write(0x01);
    LCD_data_write(0xFF);

    /* VRH Set */
    LCD_command_write(LCD_CMD_VRHS); //0xC3
    LCD_data_write(0x19);

    /* VDV Set */
    LCD_command_write(LCD_CMD_VDVS); //0xC4
    LCD_data_write(0x20);

    LCD_command_write(LCD_CMD_FRCTRL2); //  0xC6     ///< Frame Rate Control in Normal Mode
    LCD_data_write(0x0f);               ///< 60Hz

    LCD_command_write(LCD_CMD_PWCTRL1); // 0xD0     ///< Power Control 1
    LCD_data_write(0xa4);
    LCD_data_write(0xa1); ///< AVDD:6.8V, AVCL:-4.8V, VDDS:2.3V

    /* Positive Voltage Gamma Control */
    LCD_command_write(0xE0);
    LCD_data_write(0xD0);
    LCD_data_write(0x04);
    LCD_data_write(0x0D);
    LCD_data_write(0x11);
    LCD_data_write(0x13);
    LCD_data_write(0x2B);
    LCD_data_write(0x3F);
    LCD_data_write(0x54);
    LCD_data_write(0x4C);
    LCD_data_write(0x18);
    LCD_data_write(0x0D);
    LCD_data_write(0x0B);
    LCD_data_write(0x1F);
    LCD_data_write(0x23);

    /* Negative Voltage Gamma Control */
    LCD_command_write(0xE1);
    LCD_data_write(0xD0);
    LCD_data_write(0x04);
    LCD_data_write(0x0C);
    LCD_data_write(0x11);
    LCD_data_write(0x13);
    LCD_data_write(0x2C);
    LCD_data_write(0x3F);
    LCD_data_write(0x44);
    LCD_data_write(0x51);
    LCD_data_write(0x2F);
    LCD_data_write(0x1F);
    LCD_data_write(0x1F);
    LCD_data_write(0x20);
    LCD_data_write(0x23);

    // LCD_command_write( 0x21);     ///< Display Inversion On
    //LCD_command_write( 0x13);
    //LCD_InitSequence();
    //Display_logo();
    // lcd_clear(LCD_DISP_RED);
  lcd_clear(LCD_DISP_WRITE);
    LCD_command_write(LCD_CMD_DISPON); ///< Display on
}

常用颜色定义,为RGB565格式,其他颜色可以自己改变配比

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/************** 颜色(RGB 5,6,5) **************/
#define LCD_DISP_RED                    0xF800       //先高字节,后低字节      
#define LCD_DISP_GREEN                  0x07E0
#define LCD_DISP_BLUE                   0x001F
#define LCD_DISP_WRITE                  0xFFFF
#define LCD_DISP_BLACK                  0x0000
#define LCD_DISP_GRAY                   0xEF5D
#define LCD_DISP_GRAY75                 0x39E7
#define LCD_DISP_GRAY50                 0x7BEF
#define LCD_DISP_GRAY25                 0xADB5

LCD清屏,可以填充指定的颜色

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//========================================================
//LCD清屏  color:要写入的颜色
//先关显示,等所有的数据写入到RAM后,再打开显示
//========================================================
void lcd_clear(uint16_t color)
{

    uint16_t i, j;
    LCD_command_write(0x2A);
    LCD_data_write(0);
    LCD_data_write(0);
    LCD_data_write(0);
    LCD_data_write(240);
    LCD_command_write(0X2B);
    LCD_data_write(0);
    LCD_data_write(0);
    LCD_data_write(0X01);
    LCD_data_write(0X40);

    LCD_command_write(0X2C);

    for (i = 0; i < 240; i++)
    {
        for (j = 0; j < 320; j++)
        {
            LCD_data_write(color >> 8);
            LCD_data_write(color);
        }
    }
    lcd_display_on(); /* 开LCD显示 */
}

  还有一些打点、划线、画圆等函数,就不再一一介绍了,编写测试代码,刷屏,画圆、画矩形、显示汉字,一气呵成,直接来看演示视频吧~

后面会分享更多有意思的显示小项目,包括界面等的设计,敬请期待吧!

本次的介绍就到这里啦,后面有更精彩的内容,欢迎大家持续关注嵌入式实验基地!

  如果你觉得对自己有帮助的话,给个赞,点个关注,点个在看,感谢前进的道路上有你的陪伴!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小飞哥玩嵌入式 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
lcd_SendBytes函数的定义没有吗
lcd_SendBytes函数的定义没有吗
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
STM32Cube-17 | 使用硬件SPI驱动TFT-LCD(ST7789)
本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件SPI外设与ST7789通信,驱动16bit TFT-LCD 屏幕。
Mculover666
2020/07/16
4.8K0
STM32Cube-17 | 使用硬件SPI驱动TFT-LCD(ST7789)
stm32l476芯片介绍(nvidia驱动无法找到兼容的图形硬件)
取模软件我使用的是PCtoLCD2002,原子论坛的资料有这个工具,取汉字配置和效果如下:
全栈程序员站长
2022/08/01
7250
stm32l476芯片介绍(nvidia驱动无法找到兼容的图形硬件)
05-HAL库硬件SPI点亮板载LCD屏幕
源码地址:https://gitee.com/MR_Wyf/hal-cubemx-rt-thread/tree/hal_rttNano_st7789_menu/
用户8913398
2024/01/22
7210
05-HAL库硬件SPI点亮板载LCD屏幕
06-HAL库硬件SPI DMA驱动LCD并移植LVGL 8.3
源码地址:https://gitee.com/MR_Wyf/hal-cubemx-rt-thread/tree/hal_rttNano_st7789_menu/
用户8913398
2024/06/17
1.4K0
06-HAL库硬件SPI DMA驱动LCD并移植LVGL 8.3
STM32软件模拟SPI协议控制KS1092 EEG芯片
实不相瞒,我觉得这个芯片就有毛病设计的,寄存器也不多,数据输出也不是走数字接口,但是就要用SPI接口。尤其脑电这种东西两个芯片能够?真的裂开了。。。
云深无际
2024/08/21
2820
STM32软件模拟SPI协议控制KS1092 EEG芯片
在全志XR806上移植st7789屏幕驱动
很高兴有机会参加本次极术社区举办的“「免费试用」搭载安谋科技STAR-MC1的全志XR806 Wi-Fi+BLE 开发板试用活动”。 去年就对全志的mcu芯片感兴趣了,一直没有机会接触,看到本次极术社区提供的全志wifi + BLE开发板试用,就马上参加了。板子拿到手之后,很快就搭建好了环境,由于自己时间安排的问题,一直没有空搞,这两天赶紧搞了一下。
阿志小管家
2024/02/02
2640
在全志XR806上移植st7789屏幕驱动
stm32cubemx软件库_STM32cube
前言: 本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用
全栈程序员站长
2022/09/28
8430
stm32cubemx软件库_STM32cube
STM32CubeMX系列 | 使用小熊派硬件SPI驱动W5500以太网模块
本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件SPI外设与W5500通信,并移植W550官方驱动,驱动以太网模块。
Mculover666
2021/03/26
3.7K0
STM32CubeMX系列 | 使用小熊派硬件SPI驱动W5500以太网模块
STM32CubeMX学习–(5)SPI读写W25Q128
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/129269.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/29
1.2K0
STM32CubeMX学习–(5)SPI读写W25Q128
基于STM32的智能饮水机系统设计
随着智能化的迅速发展,人们对于生活中的各类设备也越来越有智能化的需求,其中智能饮水机是一种比较常见的设备。智能饮水机不仅可以提供饮用水,还可以通过智能化的技术满足人们对于水质、水温、出水量等方面的需求。因此,当前设计了一种基于STM32的智能饮水机系统,以满足人们对智能化饮水机的需求。
DS小龙哥
2023/07/08
9250
基于STM32的智能饮水机系统设计
基于STM32设计的门禁照相机
当前文章介绍基于STM32设计的门禁照相机,本项目提供了一种更加智能、安全、便捷的门禁解决方案。门禁照相机采用STM32F103ZET6 MCU作为主控芯片,配合2.8寸LCD显示屏、OV7725数字摄像头、SD卡和模拟门铃按键等外设模块,实现了摄像头画面实时显示、门铃触发拍照、图片存储等功能。
DS小龙哥
2023/07/25
4050
基于STM32设计的门禁照相机
【STM32H7教程】第17章 STM32H7之GPIO的HAL库API
本章教程为大家讲解GPIO(General-purpose I/Os)的API使用和注意事项。GPIO是所有外设里面较容易掌握的,但也是用到最多的。
Simon223
2019/05/15
1.5K0
单片机—HLK-W801并口驱动ST7789
买了这块并口的屏幕,是为了做一个nes模拟器的游戏机,之前用的SPI的屏幕,显示游戏画面还是比较耗时,毕竟是串行数据,所以准备试一下并行接口的屏幕,顺便理解一下并口8080的驱动方式。
全栈程序员站长
2022/07/28
1.8K0
单片机—HLK-W801并口驱动ST7789
全志XR806开发板适配ST7789LCD屏幕测试
在XR806的示例程序中GPIO工程的基础上进行移植。在gpio示例文件夹中添加lcd的驱动代码。
阿志小管家
2024/02/02
1200
全志XR806开发板适配ST7789LCD屏幕测试
02-rt-thread 任务创建与HAL库点灯
上节课程我们介绍了cubemx的界面、时钟配置以及如何新建工程等,本节咱们就继续进行程序员届的“hello world”-“点灯”。
用户8913398
2022/11/16
1.4K0
02-rt-thread 任务创建与HAL库点灯
STM32CubeMX |42-使用DMA2D加速显存数据传输
STM32CubeMX | 41-使用LTDC驱动TFT-LCD屏幕(RGB屏)。
Mculover666
2021/07/23
3.1K2
STM32CubeMX |42-使用DMA2D加速显存数据传输
STM32通信模拟SPI
SPI(Serial Peripheral Interface,串行外设接口)是由摩托罗拉(Motorola)在1980前后提出的一种全双工同步串行通信接口,它用于MCU与各种外围设备以串行方式进行通信以交换信息,通信速度最高可达25MHz以上。
韦东山
2022/05/09
1.4K0
STM32通信模拟SPI
M-Arch(番外14)GD32L233评测-驱动段码LCD
结果后来细看,发现CCT6不支持,裸屏不能浪费了,又买了一块天微的TM1621D驱动,自己折腾了一块SLCD板,板子其实比较简单,打板如下:
滚神大人
2022/06/09
5300
M-Arch(番外14)GD32L233评测-驱动段码LCD
全志R128使用SPI驱动ST7789V1.47寸LCD
Supports DBI Type C 3 Line/4 Line Interface Mode
阿志小管家
2024/02/02
2020
全志R128使用SPI驱动ST7789V1.47寸LCD
HAL库控制PS2手柄「建议收藏」
最近买了个ps2手柄,结果买家发的例程全都是好几年前的库函数版本,尝试移植基本没啥可能。虽然PS2手柄已经被开发很久了,不过我看网上用hal库来写控制的很少,例程也都是用库函数写的,因此写篇文章来帮助刚开始接触PS2又懒得用库函数的同学。
全栈程序员站长
2022/07/01
1.2K0
HAL库控制PS2手柄「建议收藏」
相关推荐
STM32Cube-17 | 使用硬件SPI驱动TFT-LCD(ST7789)
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文