打印
[其他ST产品]

stm32 hal库硬件spi(软件spi)驱动1.8寸tft—lcd屏幕

[复制链接]
1354|42
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
前言
屏幕是嵌入式开发中的一个重要的部分,cdsn上有许多解释原理的,还有很多是采用正点原子的屏幕来驱动的,对于刚刚入门不久的我们可能没有资金去购买较为昂贵的屏幕。而对于底层原理我们暂时也不必了解的那么深入,能点亮屏幕就是我们最大的快乐。
除了中景园的资料全一些以外,没有啥更好的驱动了! 嘛?
无意中找到了一个很不错的网站,他们的代码和中景园相似但又有所不同,毕竟科技以换壳为本嘛!所以本篇拙笔就是记录如何将代码移植到stm32上。
官网地址:官网地址
在官网中可下载相应的代码,我在每节的链接中会贴出移植好的代码。

环境搭建

cubemx、keil5、tft_lcd屏幕(spi接口)、stm32开发板

一、stm32软件spi驱动lcd

链接:百度网盘——my
提取码:fnov

1 cubemx配置
cubemx配置如上图所示,记得一定要改名字,不然每次都要修改lcd的源码会很麻烦,名字就写图中的就可以了。(这个还不知道是什么的需要补习一下cubemx了后续会出一期期cubemx的基础使用

使用特权

评论回复
沙发
一点点0321|  楼主 | 2023-11-21 00:36 | 只看该作者
2 代码移植
将官网中的文件下载下来以后继续解压,
这个链接里面有官网的文件
链接:百度网盘
提取码:2eq4

打开这个目录下的代码并在自己创建的工程下创建一个user文件夹。
在user文件夹下创建需要的.h .c文件

使用特权

评论回复
板凳
一点点0321|  楼主 | 2023-11-21 00:36 | 只看该作者
1)lcd.c
上面的大段注释就不需要了,直接把下面的代码加入就可以了,再把lcd.h加入
这个时候要根据叉叉和感叹号去修改代码
第一步
删除#include “delay.h”。
删除void LCD_Init(void)中的LCD_GPIOInit();//LCD GPIO初始化 这句代码,因为cube已经帮我们初始化过了不需要初始化了。
把delay_ms改成hal_delay;因为标准库中没有带延时而hal库中有,我们直接用hal库的就可以了。
第二步
把#include “sys.h”改成#include “main.h”

使用特权

评论回复
地板
一点点0321|  楼主 | 2023-11-21 00:36 | 只看该作者
并在下面加一下
#define u8 uint8_t
#define u16 uint16_t
因为hal库中没有u8 和u 16,所以需要宏定义一下。

使用特权

评论回复
5
一点点0321|  楼主 | 2023-11-21 00:36 | 只看该作者
第三步
删除lcd端口定义,因为cube引脚帮我们配置好了,不需要这个了

使用特权

评论回复
6
一点点0321|  楼主 | 2023-11-21 00:36 | 只看该作者
修改引脚电平的跳变,这一步是很重要的
这里我们修改为:

使用特权

评论回复
7
一点点0321|  楼主 | 2023-11-21 00:37 | 只看该作者
这里并没有调用hal_gpio_write()因为直接操纵寄存器的话会快很多。

lcd.h就自己写了,这个也很简单,实在不会就对照我的【百度网盘——my】中的文件抄写一下,后面基本都是只介绍.c库的修改

使用特权

评论回复
8
一点点0321|  楼主 | 2023-11-21 00:37 | 只看该作者
2)spi.c
在这里直接移植过去就可以了不需要继续更改(可以把头部注释都删除)

在spi.h文件中我们修改宏定义如图:

这一步是修改模拟spi信号的跳变的。

使用特权

评论回复
9
一点点0321|  楼主 | 2023-11-21 00:37 | 只看该作者
3)gui.c
第一步:
删除#include "delay.h"
第二步:
在gui.h中写:

#include "main.h"
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
1
2
3
4
第三步:
移植font.h文件,这里是不需要修改的

使用特权

评论回复
10
一点点0321|  楼主 | 2023-11-21 00:37 | 只看该作者
4)test.c
第一步:
删除#include "delay.h"
#include "touch.h"
#include "key.h"
#include "led.h"
以及最下面的void Touch_Test(void)函数
第二步:
移植test.h文件
并写入:

#include "main.h"
#define u8 uint8_t

使用特权

评论回复
11
一点点0321|  楼主 | 2023-11-21 00:37 | 只看该作者
5)验证

在主函数中写这些即可。

使用特权

评论回复
12
一点点0321|  楼主 | 2023-11-21 00:38 | 只看该作者
3 屏幕背光亮度调节
背光的原理就不介绍了,我们的lcd会有一个BL引脚,这样引脚就是调节背光的,即调节屏幕亮度,这个引脚我们一般设置为3.3v即为正常亮度,当想让他暗一些的时候就需要对这个引脚pwm输出,通过控制占空比来调节亮度,高电平占比越多,屏幕越亮。

使用特权

评论回复
13
一点点0321|  楼主 | 2023-11-21 00:38 | 只看该作者
二、stm32硬件spi驱动lcd
硬件spi要比软件模拟的spi快很多,在本次有一个test_time函数,用软件和硬件分别跑,硬件所需的时间仅仅是软件的一半。

链接:硬件spi_myhttps://pan.baidu.com/share/init?surl=xBffDxYtVHwHxTGYGlXb3w
提取码:6ikf

使用特权

评论回复
14
一点点0321|  楼主 | 2023-11-21 00:38 | 只看该作者
1 cubemx配置


并不需要要重新创建文件,只需要将上一份的文件复制粘贴以后进cubemx继续修改就可以了。
模式选择为只做主机发送。随后生成代码即可。

使用特权

评论回复
15
一点点0321|  楼主 | 2023-11-21 00:38 | 只看该作者
2 代码修改
本次我们只需要修改spi.c和spi.h即可,首先就是把user文件夹下的这两个文件改名为my_user.h 和my_user.c因为本来名字会和cubemx生成的文件重名。

把my_user.c中的删除掉,添加下面代码:
#include "my_spi.h"
#include "spi.h"

/*****************************************************************************
* [url=home.php?mod=space&uid=139335]@name[/url]       :u8 SPI_WriteByte(SPI_TypeDef* SPIx,u8 Byte)
* [url=home.php?mod=space&uid=212281]@date[/url]       :2018-08-09
* [url=home.php?mod=space&uid=42490]@function[/url]   :Write a byte of data using STM32's hardware SPI
* [url=home.php?mod=space&uid=2814924]@parameters[/url] :SPIx: SPI type,x for 1,2,3
                Byte:Data to be written
* @retvalue   :Data received by the bus
******************************************************************************/
u8 SPI_WriteByte(SPI_TypeDef* SPIx,u8 Byte)
{
        while((SPIx->SR&SPI_FLAG_TXE)==RESET);                //等待发送区空          
        SPIx->DR=Byte;                 //发送一个byte   
        while((SPIx->SR&SPI_FLAG_RXNE)==RESET);//等待接收完一个byte  
        return SPIx->DR;                       //返回收到的数据                       
}
//u8 SPI_WriteByte(SPI_TypeDef* SPIx,u8 Byte)
//{
//        HAL_SPI_Transmit(&hspi1,&Byte,1,10);
//        return SPIx->DR;                       //返回收到的数据                       
//}


/*****************************************************************************
* @name       :void SPI_SetSpeed(SPI_TypeDef* SPIx,u8 SpeedSet)
* @date       :2018-08-09
* @function   :Set hardware SPI Speed
* @parameters :SPIx: SPI type,x for 1,2,3
                SpeedSet:0-high speed
                                                                                                 1-low speed
* @retvalue   :None
******************************************************************************/
void SPI_SetSpeed(SPI_TypeDef* SPIx,u8 SpeedSet)
{
        SPIx->CR1&=0XFFC7;
        if(SpeedSet==1)//高速
        {
                SPIx->CR1|=SPI_BAUDRATEPRESCALER_2;//Fsck=Fpclk/2       
        }
        else//低速
        {
                SPIx->CR1|=SPI_BAUDRATEPRESCALER_32; //Fsck=Fpclk/32
        }
        SPIx->CR1|=1<<6; //SPI设备使能
}

/*****************************************************************************
* @name       :void SPI2_Init(void)       
* @date       :2018-08-09
* @function   :Initialize the STM32 hardware SPI2
* @parameters :None
* @retvalue   :None
******************************************************************************/
void SPI_Init(void)       
{
        __HAL_SPI_ENABLE(&hspi1);//这句话很重要
}


使用特权

评论回复
16
一点点0321|  楼主 | 2023-11-21 00:39 | 只看该作者
在my_spi.h中写:
#include "main.h"

#ifndef _SPI_H_
#define _SPI_H_

#define u8 uint8_t

u8 SPI_WriteByte(SPI_TypeDef* SPIx,u8 Byte);
void SPI_Init(void);
void SPI_SetSpeed(SPI_TypeDef* SPIx,u8 SpeedSet);

#endif

使用特权

评论回复
17
一点点0321|  楼主 | 2023-11-21 00:39 | 只看该作者
再把lcd.c中的打叉的地方改为SPI_WriteByte(SPI1,…….)红色的省略号就是填写本来那里填的数据。

这样就完成了,直接烧录即可。

使用特权

评论回复
18
一点点0321|  楼主 | 2023-11-21 00:39 | 只看该作者
3 速度测试
分别在软件和硬件的test.c文件的末尾写上:
void test_time(void)
{
       
        LCD_Fill(0,0,lcddev.width,lcddev.height,WHITE);
        Show_Str(20,30,BLUE,YELLOW,"BL Test",16,1);HAL_Delay(1);
        LCD_Fill(0,0,lcddev.width,lcddev.height,RED);
        Show_Str(20,30,BLUE,YELLOW,"RED ",16,1);HAL_Delay(1);
        LCD_Fill(0,0,lcddev.width,lcddev.height,GREEN);
        Show_Str(20,30,BLUE,YELLOW,"GREEN ",16,1);HAL_Delay(1);
        LCD_Fill(0,0,lcddev.width,lcddev.height,BLUE);
        Show_Str(20,30,RED,YELLOW,"BLUE ",16,1);HAL_Delay(1);       
}

使用特权

评论回复
19
一点点0321|  楼主 | 2023-11-21 00:39 | 只看该作者
并把主函数中的原有测试代码注释,写成如图:

当复位键按下以后开始计时,在我的板子上,硬件spi跑完只需要14秒,即屏幕的刷新率可以达到30fps,而使用软件的话只能达到10多fps。由此可见硬件spi是很不错的选择。

使用特权

评论回复
20
一点点0321|  楼主 | 2023-11-21 00:39 | 只看该作者
三、提高屏幕刷新率
在tft_lcd的屏幕下,我们对于屏幕呈像素质的关注是比较少的,我们主要是希望屏幕有较快的相应速度,使用我们在上两节分别使用了软件spi和硬件spi。在硬件spi中我们参考的是标准库,移植到的是hal库,其中不难发现我们在使用写数据函数的时候,使用到的都是寄存器方法,而没有使用标准库以及hal库提供的库函数。为什么留着方便的库函数不用而才用寄存器呢?
其实当你F12库函数你就能发现,库函数中存积着大量的代码,有些代码是为了检查通信协议的。我们在追求速度的时候总要舍弃些什么,毕竟有舍才有得嘛!

使用特权

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

本版积分规则

46

主题

387

帖子

0

粉丝