OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 20631|回复: 22

【分享】STM32L475潘多拉IoT Board开发板TFTLCD ST7789V2 硬件SPI+软件SPI驱动+中文字符显示

[复制链接]

6

主题

48

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6222
金钱
6222
注册时间
2018-12-2
在线时间
112 小时
发表于 2019-1-9 19:14:20 | 显示全部楼层 |阅读模式
本帖最后由 Sanjay 于 2019-3-27 21:38 编辑

觉得有帮助就回复支持鼓励一下,觉得有错误或可以完善的,麻烦指正指出,,感谢!



最近购买了IoT Board 潘多拉开发板来研究,学习使用STM32CubeMX工具配置SPI,然后驱动了TFTLCD。潘多拉开发板的TFTLCD驱动IC是ST7789V2,结合原子哥的TFTLCD代码,分享自己的硬件SPI+软件SPI驱动ST7789V2+中文显示。
博客链接:https://blog.csdn.net/Sanjay_Wu/article/details/86172477

首先来看硬件SPI+软件SPI驱动代码:
[mw_shl_code=c,true]/*
如果使用软件SPI,只需把硬件SPI的宏开关去掉即可
*/
//#define __LCD_HW_SPI_DRIVE__
#define __LCD_SW_SPI_DRIVE__

/*
LCD_PWR:PB7
LCD_RST:PB6
LCD_WR: PB4
LCD_CS: PD7
*/
#define        LCD_PWR(n)        (n ? HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET) : HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET))
#define        LCD_RST(n)        (n ? HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET) : HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET))
#define        LCD_WR(n)        (n ? HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET) : HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET))
#define        LCD_CS(n)        (n ? HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_SET) : HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_RESET))

#define LCD_WIDTH 240
#define LCD_HEIHGT 240

/* 默认LCD的画笔颜色和背景色 */
u16 POINT_COLOR = 0x0000;        /* 画笔颜色 */
u16 BACK_COLOR = 0xFFFF; /* 背景色 */

#if defined(__LCD_HW_SPI_DRIVE__)        /* 硬件SPI驱动 */

SPI_HandleTypeDef hspi3;

/**************************************************************
函数名称 : spi3_init
函数功能 : 硬件sp3初始化
输入参数 : 无
返回值 : 无
备注        : 配置成主机模式
**************************************************************/
void spi3_init(void)
{
/* SPI3 parameter configuration*/
hspi3.Instance = SPI3;
hspi3.Init.Mode = SPI_MODE_MASTER;
hspi3.Init.Direction = SPI_DIRECTION_2LINES;
hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi3.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi3.Init.NSS = SPI_NSS_SOFT;
hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi3.Init.CRCPolynomial = 7;

if(HAL_SPI_Init(&hspi3) != HAL_OK)
{
printf("spi3 init failed\r\n");
}

__HAL_SPI_ENABLE(&hspi3);        /* 使能硬件SPI3 */
}

/**************************************************************
函数名称 : HAL_SPI_MspInit
函数功能 : 硬件SPI3底层驱动,时钟使能,引脚配置
输入参数 : hspi:硬件SPI3句柄
返回值 : 无
备注        : PB3 ------> SPI3_SCK
PB5 ------> SPI3_MOSI
**************************************************************/
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;

if(hspi->Instance==SPI3)
{
__HAL_RCC_SPI3_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();

GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
}

/**************************************************************
函数名称 : sp3_write_byte
函数功能 : SPI3 写一个字节
输入参数 : w_data:要写入的字节,size:写入字节大小
返回值 : 0 --> 写入成功,其他 --> 写入失败
备注        : 无
**************************************************************/
u8 sp3_write_byte(u8 *r_data, u16 size)
{
return HAL_SPI_Transmit(&hspi3, r_data, size, 1000);
}

/**************************************************************
函数名称 : lcd_gpio_init
函数功能 : lcd gpio初始化
输入参数 : 无
返回值 : 无
备注        : 无
**************************************************************/
void lcd_gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;

__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();

/*Configure GPIO pin : PD7 */
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

/*Configure GPIO pins : PB4 PB6 PB7 */
GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_RESET);

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_7, GPIO_PIN_RESET);

spi3_init();        /* spi3初始化 */        
}

/**************************************************************
函数名称 : lcd_write_reg
函数功能 : 向lcd驱动芯片写一个命令
输入参数 : reg:要写入的命令
返回值 : 无
备注        : LCD_WR为0时表示写命令
**************************************************************/
void lcd_write_reg(u8 reg)
{
LCD_CS(0);
LCD_WR(0);
sp3_write_byte(®, 1);
}

/**************************************************************
函数名称 : lcd_write_data
函数功能 : 向lcd驱动芯片写一个数据
输入参数 : data:要写入的数据
返回值 : 无
备注        : LCD_WR为1时表示写数据
**************************************************************/
void lcd_write_data(u8 data)
{
LCD_CS(0);
LCD_WR(1);
sp3_write_byte(&data, 1);
}

#elif defined(__LCD_SW_SPI_DRIVE__)        /* 软件SPI驱动 */

/*
LCD_SDA:PB5
LCD_SCK:PB3
*/
#define        LCD_SDA(n)        (n ? HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET) : HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET))
#define        LCD_SCK(n)        (n ? HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET) : HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET))

/**************************************************************
函数名称 : lcd_gpio_init
函数功能 : lcd gpio初始化
输入参数 : 无
返回值 : 无
备注        : 无
**************************************************************/
void lcd_gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;

__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();

/*Configure GPIO pin : PD7 */
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

/*Configure GPIO pins : PB3 PB4 PB5 PB6 PB7 */
GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_SET);

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7, GPIO_PIN_SET);
}

/**************************************************************
函数名称 : lcd_write_reg
函数功能 : 向lcd驱动芯片写一个命令
输入参数 : reg:要写入的命令
返回值 : 无
备注        : LCD_WR为0时表示写命令
**************************************************************/
void lcd_write_reg(u8 reg)
{
u8 i;

LCD_CS(0);
LCD_WR(0);

for(i = 0; i < 8; i++)
{        
LCD_SCK(0);
if(reg & 0x80)
LCD_SDA(1);
else
LCD_SDA(0);
LCD_SCK(1);
reg <<= 1;
}
LCD_CS(1);
LCD_WR(1);
}

/**************************************************************
函数名称 : lcd_write_reg
函数功能 : 向lcd驱动芯片写一个数据
输入参数 : data:要写入的数据
返回值 : 无
备注        : LCD_WR为1时表示写数据
**************************************************************/
void lcd_write_data(u8 data)
{
u8 i;

LCD_CS(0);
LCD_WR(1);

for(i = 0; i < 8; i++)
{        
LCD_SCK(0);
if(data & 0x80)
LCD_SDA(1);
else
LCD_SDA(0);
LCD_SCK(1);
data <<= 1;
}
LCD_CS(1);
LCD_WR(1);
}

#endif[/mw_shl_code]

接着看汉字显示代码,汉字显示和字符串显示是一样的,都是打点显示,只不过汉字显示比字符串显示多一半,只需在字符串显示基础上做简单的修改即可:
[mw_shl_code=c,true]/**************************************************************
函数名称 : lcd_show_chinese
函数功能 : lcd显示字符串
输入参数 : x,y:起始坐标
*ch:汉字字符串起始地址
size:字体大小
n:汉字个数
mode:叠加方式(1)还是非叠加方式(0)
返回值 : 无
备注        : 无
**************************************************************/
void lcd_show_chinese(u16 x, u16 y, const u8 * ch, u8 size, u8 n, u8 mode)
{
u32 temp, t, t1;
u16 y0 = y;
u32 csize = ((size / 8) + ((size % 8) ? 1 : 0)) * (size) * n;        /* 得到字体字符对应点阵集所占的字节数 */

for(t = 0; t < csize; t++)
{
temp = ch[t];        /* 得到点阵数据 */

for(t1 = 0; t1 < 8; t1++)
{
if(temp & 0x80)
{
lcd_draw_point(x, y, POINT_COLOR);
}
else if(mode==0)
{
lcd_draw_point(x, y, BACK_COLOR);
}
temp <<= 1;
y++;
if((y - y0) == size)
{
y = y0;
x++;
break;
}
}
}
}
[/mw_shl_code]
main函数:
[mw_shl_code=c,true]int main(void)
{
        hardware_init();
        printf("IoT Board PANDORA\r\n");
        lcd_clear(YELLOW);
        
        while(1)
        {
                lcd_show_string(66, 0, 108, 12, "IoT Board", 24, 1);
                lcd_show_chinese(72, 32, pandora_ch, 32, 3, 1);
                delay_ms(1000);
        }
}[/mw_shl_code]

汉字取模方法和显示效果:

显示效果

显示效果

显示效果

显示效果

lcd.zip

16.22 KB, 下载次数: 1141

驱动代码和字库

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

13

主题

633

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1331
金钱
1331
注册时间
2016-8-1
在线时间
229 小时
发表于 2019-1-10 08:55:37 | 显示全部楼层
回复 支持 反对

使用道具 举报

64

主题

446

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1032
金钱
1032
注册时间
2017-7-26
在线时间
275 小时
发表于 2019-1-10 09:07:50 | 显示全部楼层
emmm。。。
TFT显示这种字体还是有点浪费的,
有木有显示抗锯齿字体的api
回复 支持 反对

使用道具 举报

0

主题

168

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
286
金钱
286
注册时间
2018-12-31
在线时间
12 小时
发表于 2019-1-10 09:36:53 | 显示全部楼层
多谢分享啊!!!
回复 支持 反对

使用道具 举报

6

主题

48

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6222
金钱
6222
注册时间
2018-12-2
在线时间
112 小时
 楼主| 发表于 2019-1-10 11:36:39 | 显示全部楼层
a3748622 发表于 2019-1-10 09:07
emmm。。。
TFT显示这种字体还是有点浪费的,
有木有显示抗锯齿字体的api

你有Windows抗锯齿字体吗,有的话就可以实现
回复 支持 反对

使用道具 举报

109

主题

5562

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10541
金钱
10541
注册时间
2017-2-18
在线时间
1908 小时
发表于 2019-1-10 18:45:53 | 显示全部楼层
多谢分享~~
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2019-1-11 02:10:43 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

40

主题

259

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
459
金钱
459
注册时间
2016-5-19
在线时间
192 小时
发表于 2019-3-19 13:58:21 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

40

主题

259

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
459
金钱
459
注册时间
2016-5-19
在线时间
192 小时
发表于 2019-3-19 16:58:54 | 显示全部楼层
您好,大神,我的液晶驱动芯片也是ST7789VS,用的是SPI,参考了汉字实现代码,就出现了3条斜杠。是怎么原因。。
回复 支持 反对

使用道具 举报

40

主题

259

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
459
金钱
459
注册时间
2016-5-19
在线时间
192 小时
发表于 2019-3-19 17:42:50 | 显示全部楼层
本帖最后由 h418452224 于 2019-3-19 17:44 编辑

微信图片_20190319173743.jpg
可以了,我是这样的
[mw_shl_code=c,true]void lcd_show_chinese(u16 x, u16 y, const u8 * ch, u8 size, u8 n)
{
u32 temp, t, t1;
u32 csize = ((size / 8) + ((size % 8) ? 1 : 0)) * (size) * n;
BlockWrite(x,x+(size-1)*n,y,y+(size-1)*n);
for(t = 0; t < csize; t++)
{
temp = ch[t];
for(t1 = 0; t1 < 8; t1++)
{
if(temp & 0x80)
{
  WriteOneDot(MAGENTA);  //字体色
}
else
{       
  WriteOneDot(CYAN);          //背景色
}
temp <<= 1;
}
}
}[/mw_shl_code]
回复 支持 反对

使用道具 举报

6

主题

48

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6222
金钱
6222
注册时间
2018-12-2
在线时间
112 小时
 楼主| 发表于 2019-3-19 20:05:06 | 显示全部楼层
h418452224 发表于 2019-3-19 17:42
可以了,我是这样的
[mw_shl_code=c,true]void lcd_show_chinese(u16 x, u16 y, const u8 * ch, u8 size ...

回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2019-7-8
在线时间
10 小时
发表于 2019-7-8 15:56:22 | 显示全部楼层
谢谢分享

回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2019-6-20
在线时间
0 小时
发表于 2019-8-7 00:02:02 | 显示全部楼层
支持一下
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2015-11-27
在线时间
8 小时
发表于 2019-12-4 16:00:36 | 显示全部楼层
借鉴一下,我们要用FSMC方式,还没有用过这个芯片
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2020-7-7
在线时间
16 小时
发表于 2021-5-26 09:26:37 | 显示全部楼层
楼主显示图片的例程能分享下吗?
回复 支持 反对

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2021-11-27
在线时间
1 小时
发表于 2021-11-29 12:19:06 来自手机 | 显示全部楼层
想问一下有没有stm32cubemx的步骤啊,实在不知道怎么配置了
回复 支持 反对

使用道具 举报

4

主题

80

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1045
金钱
1045
注册时间
2020-8-4
在线时间
247 小时
发表于 2022-2-15 16:06:43 | 显示全部楼层
感谢分享!
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2020-3-29
在线时间
5 小时
发表于 2022-3-5 12:06:40 | 显示全部楼层
先不说代码,就冲你这个资料在完整性  五星好评
回复 支持 反对

使用道具 举报

0

主题

81

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
208
金钱
208
注册时间
2014-9-18
在线时间
21 小时
发表于 2022-5-2 18:21:38 | 显示全部楼层
好东西,下来学习学习
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
9
金钱
9
注册时间
2022-5-4
在线时间
2 小时
发表于 2022-5-5 10:12:30 | 显示全部楼层
你好请问如果要在同一个地方显示除了clear之外(会一闪一闪)怎么覆盖掉之前的内容呢
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2022-5-7
在线时间
5 小时
发表于 2022-5-7 17:01:50 | 显示全部楼层
感谢,慢慢学习一下
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2020-5-11
在线时间
0 小时
发表于 2022-11-6 10:07:28 | 显示全部楼层
ganxiefenxiang
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2022-9-20
在线时间
7 小时
发表于 2023-7-5 17:26:35 | 显示全部楼层
感谢分享
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 06:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表