3.5寸ILI9488 SPI触摸屏在天空星GD32F407上的移植实战
3.5寸ILI9488 SPI触摸屏在天空星GD32F407上的移植实战最近在做一个带界面的小项目手头正好有一块3.5寸的ILI9488 SPI触摸屏想把它接到天空星GD32F407开发板上用。网上找的例程大多是针对STM32的直接拿来用肯定不行得自己动手移植。折腾了两天总算调通了屏幕显示和触摸都正常。今天就把这个移植过程完整地写下来如果你也在用GD32F407驱动这款屏幕跟着做一遍应该就能搞定。咱们这个教程会手把手带你走完整个流程从拿到厂家资料开始到把代码整合进工程再到修改引脚配置、适配硬件SPI最后完成功能验证。过程中我会把容易踩坑的地方都指出来。1. 准备工作了解屏幕与获取资料工欲善其事必先利其器。动手前咱们先得把屏幕的基本情况和要用到的资料搞清楚。1.1 屏幕规格与接口我用的这块3.5寸屏核心信息如下驱动芯片ILI9488。这是一款很常见的TFT LCD驱动IC支持26万色。分辨率320 x 480像素。注意它的高度是320宽度是480是竖屏的规格。通信接口SPI。这意味着数据传输是串行的比并口节省大量IO口但速度会慢一些。工作电压3.3V。和天空星GD32F407开发板的IO电压完美匹配直接连接就行不需要电平转换。物理接口14Pin的2.54mm间距排针。所有控制线和数据线都从这里引出。屏幕的详细规格书和资料可以在LCDwiki网站找到。资料里最关键的是厂家提供的示例代码这是我们移植的基础。原始文章里给出了资料下载链接你可以直接去那个页面下载全套资料。1.2 建立工程基础在开始移植屏幕驱动前你需要一个可以编译的GD32F407基础工程。这个工程至少需要包含正确的芯片型号支持包例如GigaDevice提供的GD32F4xx Firmware Library。系统时钟、延时等基础配置。一个简单的main函数入口。你可以使用天空星官方提供的“入门手册空白工程”或者自己用CubeMX之类的工具生成一个。确保工程里有一个微秒级us的延时函数因为屏幕初始化时序里会用到。我工程里的延时函数头文件是board.h你的可能叫delay.h或其他记住这个名字后面要改。2. 移植核心步骤代码整合与初步修改拿到厂家例程后别急着全部复制。我们要做的是“嫁接”把屏幕驱动代码移植到我们自己的GD32工程里。2.1 导入源码文件首先从厂家资料包里找到LCD的底层驱动文件。通常包括lcd.c/lcd.h屏幕显示驱动。touch.c/touch.h触摸屏驱动如果你的屏幕带触摸。spi.c/spi.hSPI通信底层可能是软件模拟SPI。gui.c/gui.h一些基本的图形绘制函数如画线、画圆、显示字符。test.c测试演示函数。把这些.c和.h文件复制到你工程目录下的合适位置比如一个新建的LCD文件夹里。然后在你的IDE如Keil MDK中将这些文件添加到工程的项目组里。2.2 解决基础编译错误添加文件后编译一下肯定会报错。别慌这是移植的正常过程。我们按顺序解决。第一步处理类型定义。厂家代码里可能用u8u16u32来定义变量但你的GD32工程里可能没有这些别名。我们需要在相关的头文件里定义它们。 打开lcd.htouch.hspi.h这三个文件在文件开头添加以下代码#include gd32f4xx.h #ifndef u8 #define u8 uint8_t #endif #ifndef u16 #define u16 uint16_t #endif #ifndef u32 #define u32 uint32_t #endif第二步替换延时函数头文件。厂家例程里用的延时函数头文件可能是delay.h我们需要改成自己工程里实际使用的。用编辑器的“查找并替换”功能在test.clcd.ctouch.c和GUI.c这几个文件中将#include “delay.h”替换成你的头文件比如我的是#include “board.h”。第三步处理位操作如果遇到。如果编译提示sys.h相关错误说明例程使用了位带操作Bit-Banding。位带操作可以像操作普通变量一样操作单个比特位非常方便。你可以将资料包里提供的sys.h文件复制到你的工程中例如board目录并确保在需要的地方包含它。做完这几步再编译大部分语法错误应该就消失了。接下来进入重头戏——硬件引脚配置。3. 硬件连接与引脚配置这是移植成功的关键一步引脚接错了或者配置不对屏幕肯定没反应。3.1 屏幕引脚定义与接线首先你得知道屏幕的14个引脚各自是干什么的。根据规格书主要信号线如下屏幕引脚标号信号名称功能说明VCC电源接3.3VGND地接GNDSCL时钟线SPI时钟信号SDA数据线SPI数据输出MCU - 屏幕RES复位低电平复位屏幕DC数据/命令选择高电平数据低电平命令CS片选低电平选中屏幕BLK背光控制高电平点亮背光触摸部分如果你的屏幕带触摸 | T_CLK, T_DIN, T_DO, T_CS, T_IRQ | 触摸SPI总线 | 用于触摸芯片通信 |我的接线方案是将其连接到GD32F407的SPI1接口上具体如下表。你可以完全照搬也可以根据自己板子的空闲IO口调整。屏幕信号对应MCU引脚引脚功能SCLPB10SPI1_SCKSDAPB15SPI1_MOSIRESPD12普通GPIO输出DCPD11普通GPIO输出CSPB12SPI1_NSS (或普通GPIO)BLKPD10普通GPIO输出T_CLKPB8普通GPIO输出T_DINPB6普通GPIO输出T_DOPB5普通GPIO输入T_CSPB7普通GPIO输出T_IRQPB4普通GPIO输入注意CS片选引脚即使我们使用硬件SPI也建议在初始化时配置为普通GPIO输出用软件控制其高低电平。这样更灵活避免硬件SPI的NSS引脚自动控制可能带来的问题。原文代码中也是这么做的。3.2 在代码中定义引脚为了方便管理和后续修改我们把所有用到的引脚在lcd.h文件中用宏定义起来。这样想换引脚时只需改这一个地方。下面是我的配置你可以对照上表理解//-----------------LCD端口移植---------------- //VCC - 3.3V //SCL - PB10 SPI1_SCK //SDA - PB15 SPI1_MOSI //RES - PD12 (可以接入复位) //DC - PD11 //CS - PB12 SPI1_NSS //BLK - PD10 #define RCU_LCD_SCL RCU_GPIOB//SCK #define PORT_LCD_SCL GPIOB #define GPIO_LCD_SCL GPIO_PIN_10 #define RCU_LCD_SDA RCU_GPIOB//MOSI #define PORT_LCD_SDA GPIOB #define GPIO_LCD_SDA GPIO_PIN_15 // ... 其他LCD引脚定义类似详见原始代码 // 触摸引脚定义 #define RCU_LCD_PEN RCU_GPIOB //PEN/T_IRQ #define PORT_LCD_PEN GPIOB #define GPIO_LCD_PEN GPIO_PIN_4 #define RCU_LCD_TCLK RCU_GPIOB //T_CLK #define PORT_LCD_TCLK GPIOB #define GPIO_LCD_TCLK GPIO_PIN_8 // ... 其他触摸引脚定义类似 // 硬件SPI定义 #define RCU_SPI_HARDWARE RCU_SPI1 #define PORT_SPI SPI1 #define LINE_AF_SPI GPIO_AF_53.3 修改GPIO初始化函数接下来我们要修改lcd.c文件中的void LCD_GPIOInit(void)函数。这个函数负责初始化所有连接屏幕的GPIO。厂家例程默认使用软件模拟SPI即用普通IO口模拟时钟和数据线的时序。为了获得更高的刷屏速度我们将其改为硬件SPI。代码中通过一个宏USE_HARDWARE_SPI来切换。我们只需要在lcd.h中定义#define USE_HARDWARE_SPI 1然后修改初始化函数即可。修改后的LCD_GPIOInit函数主要做以下几件事开启时钟开启所有用到的GPIO端口时钟和SPI1时钟。配置SPI引脚将PB10(SCK)和PB15(MOSI)配置为复用功能(AF)并映射到SPI1上。注意输出模式设置为推挽输出速度可以设为50MHz。配置控制引脚将RES、DC、CS、BLK配置为普通的推挽输出模式。初始化硬件SPI设置SPI1的工作模式为主机、全双工、8位数据帧、软件管理片选(NSS_SOFT)、时钟极性相位等。这里时钟预分频(PSC)很重要它决定了SPI速度。我设置为8分频在GD32F407主频200MHz下SPI时钟约为25MHz对于这款屏幕足够了。如果屏幕出现花屏或数据错误可以尝试增大分频系数如16分频降低速度。具体的代码很长请严格按照原始文章提供的LCD_GPIOInit函数代码进行修改。关键点在于硬件SPI的配置结构体spi_init_struct的各项参数。3.4 修改SPI数据发送函数使用硬件SPI后数据发送就不用一位一位地“模拟”了。我们需要修改spi.c中的void SPIv_WriteData(unsigned char Data)函数。找到这个函数将其改为void SPIv_WriteData(unsigned char Data) { #if USE_HARDWARE_SPI // 等待发送缓冲区空 while(RESET spi_i2s_flag_get(PORT_SPI, SPI_FLAG_TBE)); // 写入要发送的数据 spi_i2s_data_transmit(PORT_SPI, Data); // 等待接收缓冲区非空发送完成 while(RESET spi_i2s_flag_get(PORT_SPI, SPI_FLAG_RBNE)); // 读取数据以清除标志位虽然我们不需要接收的数据 spi_i2s_data_receive(PORT_SPI); #else // 原有的软件SPI代码... #endif }这个函数是屏幕驱动向ILI9488芯片发送命令或数据的最终出口改成硬件SPI后刷屏速度会有显著提升。4. 触摸屏驱动的适配如果你的屏幕带触摸功能还需要修改触摸驱动。触摸芯片通常也通过SPI通信但一般是接在另一组普通IO口上用软件模拟SPI。4.1 修改触摸初始化打开touch.c文件找到u8 TP_Init(void)函数。这个函数初始化触摸芯片的引脚。我们需要将其中的引脚配置改为我们之前宏定义的引脚。主要是配置T_PEN(中断引脚)为输入T_CLKT_DINT_CS为输出T_DO为输入。请用原始文章提供的TP_Init函数代码替换原有的函数内容。这段代码就是按照我们宏定义的引脚PB4 PB5 PB6 PB7 PB8进行初始化的。4.2 简化触摸校准可选厂家例程里可能包含触摸校准参数保存到Flash的功能。为了移植过程简单我们可以先注释掉这些复杂的部分使用默认值。在touch.c中找到void TP_Save_Adjdata(void)和u8 TP_Get_Adjdata(void)这两个函数将它们整体注释掉。找到void TP_Adjust(void)函数这是触摸校准函数将其内部调用的TP_Save_Adjdata()和TP_Get_Adjdata()也注释掉。这样触摸屏将使用代码中预定义的校准参数。如果触摸不准可以运行校准程序如果有的话但参数不会保存下次上电需要重新校准。先让功能跑起来后期再优化。4.3 修改触摸引脚宏定义最后修改touch.h文件中的引脚直接操作宏。厂家代码可能用了位带操作或其他方式我们将其改为与我们硬件连接对应的简单宏定义#define PEN PBin(4) //T_PEN, 即PB4输入状态 #define DOUT PBin(5) //T_DO/T_MISO, PB5输入 #define TDIN PBout(6) //T_DIN/T_MOSI, PB6输出 #define TCLK PBout(8) //T_CLK/T_SCK, PB8输出 #define TCS PBout(7) //T_CS, PB7输出这里的PBin(4)和PBout(6)需要是你工程中读取引脚输入状态和设置引脚输出电平的函数或宏。你需要根据自己工程的基础驱动库来实现它们。例如在GD32标准库中读取输入可以用gpio_input_bit_get(GPIOB GPIO_PIN_4) 设置输出可以用gpio_bit_write(GPIOB GPIO_PIN_6 SET/RESET)。你需要创建对应的宏或函数来匹配PENDOUT等定义。5. 功能验证与测试所有代码修改完成后就可以编译下载了。5.1 编写主函数进行测试在main.c中我们依次调用各个测试函数来验证显示和触摸是否正常。#include board.h #include Lcd.h #include gui.h #include test.h // 包含测试函数 #include spi.h #include touch.h int main(void) { board_init(); // 系统时钟、延时等初始化 bsp_uart_init(); // 初始化串口用于打印调试信息可选 LCD_Init(); // 液晶屏初始化 TP_Init(); // 触摸屏初始化如果有时 while(1) { main_test(); // 测试主界面可能是一个菜单 Test_Color(); // 简单刷屏填充测试看颜色是否正常 Test_FillRec(); // GUI矩形绘图测试 Test_Circle(); // GUI画圆测试 Test_Triangle(); // GUI三角形绘图测试 English_Font_test(); // 英文字体示例测试 Chinese_Font_test(); // 中文字体示例测试 Pic_test(); // 图片显示示例测试 Rotate_Test(); // 旋转显示测试 // 如果不带触摸或者不需要触摸功能请注释掉下面触摸屏测试项 Touch_Test(); // 触摸屏手写测试 } }5.2 上电调试与常见问题上电后你应该能看到屏幕依次执行各种测试。如果屏幕白屏、花屏或不亮请按以下顺序排查电源与背光首先检查VCC和GND是否接好。然后测量BLK背光控制引脚是否为高电平。如果不是检查LCD_GPIOInit中背光引脚的初始化代码确保将其设置为高电平输出。复位信号检查RESET引脚的上电时序。有些屏幕需要上电后一个低电平脉冲来复位。确保LCD_Init()函数中包含了正确的复位序列拉低-延时-拉高。SPI通信这是最可能出问题的地方。硬件连接再三检查SCK、SDAMOSI、CS、DC这几根线是否接对、接牢。软件配置确认USE_HARDWARE_SPI宏已定义为1。检查SPI的时钟极性(CPOL)和相位(CPHA)设置。ILI9488芯片通常需要模式0CPOL0 CPHA0或模式3CPOL1 CPHA1。原始代码中SPI_CK_PL_HIGH_PH_2EDGE对应的是哪种模式需要查阅GD32库手册确认如果不匹配会导致通信失败。一个常见的尝试是修改spi_init_struct.clock_polarity_phase这个参数。速度太快尝试将SPI的预分频spi_init_struct.prescale改大比如从SPI_PSC_8改为SPI_PSC_16或SPI_PSC_32降低通信速率。触摸失灵如果显示正常但触摸没反应。检查触摸部分的5根线T_CLK T_DIN T_DO T_CS T_IRQ连接。确认touch.h中的引脚操作宏PENDOUT等是否正确映射到了你的GPIO读写函数。用逻辑分析仪或示波器抓一下触摸SPI的波形看是否有数据交互。移植成功后你就可以在此基础上开发自己的图形界面了。这款屏幕搭配GD32F407做一些简单的嵌入式UI应用性能是绰绰有余的。希望这篇教程能帮你少走弯路。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2409136.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!