打印
[STM32F4]

STM32F407VET6+ST7735TFT LCD彩屏驱动程序

[复制链接]
855|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
硬件准备 STM32F407VET6开发板一块
编译器使用的是STM32cubeide。
屏幕使用的是如图所示的屏幕,驱动芯片是st7735.
驱动协议采用的是spi通讯协议。


使用特权

评论回复
沙发
逢dududu必shu|  楼主 | 2022-5-29 12:56 | 只看该作者
和stm32芯片的连接方式如下,使用的是spi2.
CS片选脚  PA4
A0脚(数据指令控制脚) PA5
LED脚(背光脚)  PA3
reset(屏幕复位脚) PA2
sck(spi时钟脚) PB10
SDA(SPIs数据脚) PC3
vcc和gnd连接到5V电源上就可以了。

使用特权

评论回复
板凳
逢dududu必shu|  楼主 | 2022-5-29 12:58 | 只看该作者
由于使用的是cubeide,代码都是直接生成的,在此就不提及cubeide该怎么生成工程了。我使用的是spi2,开启了dma传输功能。你们可以和我一样,也可以按照自己的需要自己修改。

使用特权

评论回复
地板
逢dududu必shu|  楼主 | 2022-5-29 12:59 | 只看该作者
根据手册写代码

网上也有许多关于st7735的代码,但都是只贴一下代码,关于原理部分提及较少,本着授人以鱼不如授人以渔的原则,我决定对照着数据手册教大家看懂每一行代码,让大家知其然知其所以然。

使用特权

评论回复
5
逢dududu必shu|  楼主 | 2022-5-29 12:59 | 只看该作者
底层驱动

有屏幕使用经验的朋友都知道,操作屏幕分为写数据,写指令。因此对于ST7735来说,也是同样的原理。对于屏幕的一些的gpio操作,我把封装成了宏定义,所以先贴在前面。只需要注意前面的片选脚,数据命令选择脚就可以了。

使用特权

评论回复
6
逢dududu必shu|  楼主 | 2022-5-29 13:00 | 只看该作者
 //LCD片选脚
#define CS_HIGH   HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET)
#define CS_LOW   HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET)

//指令数据选择脚   对应屏幕上面的a0脚  输出低电平,代表命令,高电平,代表数据
#define COMMAND  HAL_GPIO_WritePin(CMD_DATA_GPIO_Port, CMD_DATA_Pin, GPIO_PIN_RESET)
#define DATA     HAL_GPIO_WritePin(CMD_DATA_GPIO_Port, CMD_DATA_Pin, GPIO_PIN_SET)

//复位脚
#define reset_high  HAL_GPIO_WritePin(RESET_GPIO_Port, RESET_Pin, GPIO_PIN_SET)
#define reset_low  HAL_GPIO_WritePin(RESET_GPIO_Port, RESET_Pin, GPIO_PIN_RESET)
//背光脚
#define  led_high HAL_GPIO_WritePin(BACK_LED_GPIO_Port,BACK_LED_Pin,GPIO_PIN_SET)
#define  led_low HAL_GPIO_WritePin(BACK_LED_GPIO_Port,BACK_LED_Pin,GPIO_PIN_RESET)
//lcd背光颜色
#define RED    0xf800
#define GREEN  0x07e0
#define BLUE   0x001f
#define YELLOW 0xffe0
#define WHITE  0xffff
#define BLACK  0x0000
#define PURPLE 0xf81f
#define MAGENTA   0xF81F        //  品红

使用特权

评论回复
7
逢dududu必shu|  楼主 | 2022-5-29 13:00 | 只看该作者

使用特权

评论回复
8
逢dududu必shu|  楼主 | 2022-5-29 13:02 | 只看该作者
通过数据手册我们可以看到,如果D/CX脚为低电平,就是写指令,为高电平就是写数据。D/CX就是实物图上的A0脚,也是上面宏定义中的COMMAND。因此就 可以来写我们的驱动程序了。数据已经贴在下面了,通过数据手册,现在是不是一目了然。

使用特权

评论回复
9
逢dududu必shu|  楼主 | 2022-5-29 13:02 | 只看该作者
//LCD屏幕写指令
void TFT_WRITE_DATA(uint8_t data)
{
        CS_LOW;
        DATA;
        HAL_SPI_Transmit_DMA(&hspi2,&data,1);
        CS_HIGH;

}
//  LCD屏幕写指令
void TFT_WRITE_COMMAND(uint8_t command)
{
        CS_LOW;
        COMMAND;
        HAL_SPI_Transmit_DMA(&hspi2,&command,1);
        CS_HIGH;
}

使用特权

评论回复
10
逢dududu必shu|  楼主 | 2022-5-29 13:03 | 只看该作者
有了这两个函数以后,就能进行屏幕的操作了,首先我们需要进行屏幕的初始化。

使用特权

评论回复
11
逢dududu必shu|  楼主 | 2022-5-29 13:03 | 只看该作者
屏幕初始化

使用特权

评论回复
12
逢dududu必shu|  楼主 | 2022-5-29 13:04 | 只看该作者
以B4H这个指令为例子,这是一个控制反显的指令,B4是指令的代码,参数控制如图所示。
**因此,如果需要控制一个具体的功能,需要先发送该指令码,在发送对应的数据。**以这个指令为例子。

使用特权

评论回复
13
逢dududu必shu|  楼主 | 2022-5-29 13:05 | 只看该作者
TFT_WRITE_COMMAND(0xB4); //Column inversion
        TFT_WRITE_DATA(0x07);

使用特权

评论回复
14
逢dududu必shu|  楼主 | 2022-5-29 13:06 | 只看该作者
因此在初始化的时候,只要按照这样的操作就可以了,初始化的代码贴在下面。
void tft_init()
{

        reset_low;
        HAL_Delay(100);
        reset_high;
        HAL_Delay(100);

        //根据数据手册,对应的寄存器写入对应的值,所以在发送完指令之后,就要发送对应的数据
        TFT_WRITE_COMMAND(0x11);//Sleep exit
        HAL_Delay(120);
                //ST7735R Frame Rate
        TFT_WRITE_COMMAND(0xB1);
        TFT_WRITE_DATA(0x01);
        TFT_WRITE_DATA(0x2C);
        TFT_WRITE_DATA(0x2D);

        TFT_WRITE_COMMAND(0xB2);
        TFT_WRITE_DATA(0x01);
        TFT_WRITE_DATA(0x2C);
        TFT_WRITE_DATA(0x2D);


        TFT_WRITE_COMMAND(0xB3);
        TFT_WRITE_DATA(0x01);
        TFT_WRITE_DATA(0x2C);
        TFT_WRITE_DATA(0x2D);
        TFT_WRITE_DATA(0x01);
        TFT_WRITE_DATA(0x2C);
        TFT_WRITE_DATA(0x2D);

        TFT_WRITE_COMMAND(0xB4); //Column inversion
        TFT_WRITE_DATA(0x07);


        //ST7735R Power Sequence
        TFT_WRITE_COMMAND(0xC0);
        TFT_WRITE_DATA(0xA2);
        TFT_WRITE_DATA(0x02);
        TFT_WRITE_DATA(0x84);
        TFT_WRITE_COMMAND(0xC1);
        TFT_WRITE_DATA(0xC5);


        TFT_WRITE_COMMAND(0xC2);
        TFT_WRITE_DATA(0x0A);
        TFT_WRITE_DATA(0x00);


        TFT_WRITE_COMMAND(0xC3);
        TFT_WRITE_DATA(0x8A);
        TFT_WRITE_DATA(0x2A);
        TFT_WRITE_COMMAND(0xC4);
        TFT_WRITE_DATA(0x8A);
        TFT_WRITE_DATA(0xEE);

        TFT_WRITE_COMMAND(0xC5); //VCOM
        TFT_WRITE_DATA(0x0E);


        TFT_WRITE_COMMAND(0x36); //MX, MY, RGB mode
        TFT_WRITE_DATA(0xC8);



        //ST7735R Gamma Sequence
        TFT_WRITE_COMMAND(0xe0);
        TFT_WRITE_DATA(0x0F);
        TFT_WRITE_DATA(0x1A);
        TFT_WRITE_DATA(0x0F);
        TFT_WRITE_DATA(0x18);
        TFT_WRITE_DATA(0x2F);
        TFT_WRITE_DATA(0x28);


        TFT_WRITE_DATA(0x20);
        TFT_WRITE_DATA(0x22);
        TFT_WRITE_DATA(0x1F);

        TFT_WRITE_DATA(0x1B);
        TFT_WRITE_DATA(0x23);
        TFT_WRITE_DATA(0x37);


        TFT_WRITE_DATA(0x00);

        TFT_WRITE_DATA(0x07);
        TFT_WRITE_DATA(0x02);
        TFT_WRITE_DATA(0x10);


        TFT_WRITE_COMMAND(0xe1);
        TFT_WRITE_DATA(0x0F);
        TFT_WRITE_DATA(0x1B);
        TFT_WRITE_DATA(0x0F);

        TFT_WRITE_DATA(0x17);



        TFT_WRITE_DATA(0x33);
        TFT_WRITE_DATA(0x2C);

        TFT_WRITE_DATA(0x29);

        TFT_WRITE_DATA(0x2E);
        TFT_WRITE_DATA(0x28);
        TFT_WRITE_DATA(0x30);


        TFT_WRITE_DATA(0x30);

        TFT_WRITE_DATA(0x39);
        TFT_WRITE_DATA(0x3F);

        TFT_WRITE_DATA(0x00);
        TFT_WRITE_DATA(0x07);
        TFT_WRITE_DATA(0x03);
        TFT_WRITE_DATA(0x10);

        //设置为了 RGB 5-6-5  65k颜色mode
        TFT_WRITE_COMMAND(0x2A); //65k mode
        TFT_WRITE_DATA(0x00);
        TFT_WRITE_DATA(0x00);
        TFT_WRITE_DATA(0x00);
        TFT_WRITE_DATA(0x7F);

        TFT_WRITE_COMMAND(0x2B); //65k mode
        TFT_WRITE_DATA(0x00);
        TFT_WRITE_DATA(0x00);
        TFT_WRITE_DATA(0x00);
        TFT_WRITE_DATA(0x9F);

        TFT_WRITE_COMMAND(0xF0); //65k mode
        TFT_WRITE_DATA(0x01);
        TFT_WRITE_COMMAND(0xF6); //65k mode
        TFT_WRITE_DATA(0x00);


        TFT_WRITE_COMMAND(0x3A); //这个指令将屏幕设置为了 65k颜色模式
        TFT_WRITE_DATA(0x05);
        TFT_WRITE_COMMAND(0x29);//Display on
        lcd_set_direction();

        TFT_WRITE_REG(0x36,(1<<3)|(1<<6)|(1<<7)); //这个指令很关键,控制了屏幕的显示方向等参数

        TFT_WRITE_COMMAND(0xc0);//Display on  TFT_WRITE_COMMAND(0x36  );设置�?始坐�?
        TFT_WRITE_DATA(0x0A);

        lcd_clear(0xffe0);
        led_high;
}

使用特权

评论回复
15
逢dududu必shu|  楼主 | 2022-5-29 13:07 | 只看该作者
显示数据
在初始化完成以后,就可以写数据了。
在写数据之前需要先设置显示的区域,然后在写入对应的数据。
与坐标设置相关的指令是2A,2B,2C。有了前面的教学,你应该可以看明白数据手册了,在此就不细说了。
程序源码在gitee源码
需要的点击下载就可以了。

使用特权

评论回复
16
Pulitzer| | 2022-10-5 08:29 | 只看该作者

代码量小的时候用来做条件判断

使用特权

评论回复
17
Uriah| | 2022-10-5 15:30 | 只看该作者

单片机一般都有内部程序区和数据区

使用特权

评论回复
18
Bblythe| | 2022-10-5 18:29 | 只看该作者

只要内存占用量不超过 256.0 就可以用 small 模式编译

使用特权

评论回复
19
周半梅| | 2023-4-1 07:26 | 只看该作者

格式化输出需要删除掉多余的空白行

使用特权

评论回复
20
Pulitzer| | 2023-4-1 08:29 | 只看该作者

I2C1工作时钟源选择;I2C1模块工作时钟的开启使能。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

65

主题

462

帖子

1

粉丝