ST7789驱动实战:从SPI时序到RGB565显示的完整配置解析
1. ST7789驱动芯片初探从数据手册到实战准备第一次拿到ST7789的数据手册时我完全被里面密密麻麻的时序图和寄存器描述搞懵了。这玩意儿看起来就像天书但别担心跟着我的步骤走你也能轻松搞定。ST7789是一款240x320分辨率的TFT液晶驱动芯片支持SPI和并行接口我们这里重点讲SPI 4线模式因为这是最常用的方式。数据手册就像一本产品说明书但比宜家家具的说明书复杂100倍。我的经验是先别急着从头到尾读而是带着问题去找答案。比如SPI怎么配置、怎么设置显示方向、颜色格式怎么选这样效率会高很多。手册里最重要的几个部分电气特性、接口时序、命令集和寄存器描述这些是我们需要重点关注的。硬件连接很简单SCK接时钟线SDA接数据线再加上D/CX数据/命令选择和RESET复位线。有些开发板可能还需要背光控制线这个看具体设计。我用的是一块STM32F103开发板SPI时钟设到20MHz左右就够用了再高可能会出问题。2. SPI接口配置从时序图到代码实现2.1 解读SPI时序图打开数据手册第23页你会看到4线串行接口的时序图。这张图看起来复杂其实就告诉我们几件事SCK空闲时是低电平CPOL0数据在第一个边沿采样CPHA0也就是SPI模式0。D/CX线决定传输的是命令低电平还是数据高电平。我在STM32CubeMX里配置SPI时特别注意了这几个参数hspi1.Init.CLKPhase SPI_PHASE_1EDGE; // CPHA0 hspi1.Init.CLKPolarity SPI_POLARITY_LOW; // CPOL0 hspi1.Init.BaudRatePrescaler SPI_BAUDRATEPRESCALER_4; // 时钟分频 hspi1.Init.FirstBit SPI_FIRSTBIT_MSB; // 高位先行2.2 编写基础通信函数根据时序图我们需要两个基本函数发送命令和发送数据。这里有个坑要注意ST7789的SPI接口不支持全双工必须用只发送模式。void ST7789_WriteCommand(uint8_t cmd) { DC_CMD(); // D/CX拉低 HAL_SPI_Transmit(hspi1, cmd, 1, HAL_MAX_DELAY); } void ST7789_WriteData(uint8_t data) { DC_DATA(); // D/CX拉高 HAL_SPI_Transmit(hspi1, data, 1, HAL_MAX_DELAY); }实测发现连续发送数据时如果用单字节模式会很慢。后来我改成了批量发送版本速度提升了5倍不止void ST7789_WriteDataBulk(uint8_t *data, uint32_t len) { DC_DATA(); HAL_SPI_Transmit(hspi1, data, len, HAL_MAX_DELAY); }3. 关键寄存器配置显示方向与色彩模式3.1 显示方向控制0x36寄存器这个寄存器控制着屏幕的显示方向手册里叫Memory Data Access Control。我花了半天才搞明白各个位的含义MY垂直翻转1上下颠倒MX水平翻转1左右颠倒MV行列交换1横屏模式RGB色彩顺序0RGB1BGR我最常用的配置是0x00正常方向和0xA0横屏模式。测试时发现有些屏的默认方向不一样可能需要调整。比如我手头的一块屏就需要设置MX1才能正常显示。// 正常方向 ST7789_WriteCommand(0x36); ST7789_WriteData(0x00); // 横屏模式 ST7789_WriteCommand(0x36); ST7789_WriteData(0xA0);3.2 色彩模式设置0x3A寄存器ST7789支持多种色彩格式我们最常用的是RGB56516位/像素。这个通过0x3A寄存器设置ST7789_WriteCommand(0x3A); ST7789_WriteData(0x05); // RGB565这里有个坑有些屏的驱动IC虽然标称是ST7789但可能用了兼容芯片色彩格式可能是0x55或0x66。如果显示颜色不对可以试试这几个值。4. 完整初始化流程与显示测试4.1 初始化步骤详解根据手册和实际测试完整的初始化流程应该是这样的硬件复位拉低RESET至少10ms发送0x01软件复位等待120ms延时设置0x36寄存器显示方向设置0x3A寄存器色彩格式发送0x11退出睡眠模式等待120ms延时发送0x29开启显示我把它封装成了一个函数void ST7789_Init(void) { // 硬件复位 RESET_LOW(); HAL_Delay(20); RESET_HIGH(); HAL_Delay(120); // 软件复位 ST7789_WriteCommand(0x01); HAL_Delay(120); // 设置显示方向 ST7789_WriteCommand(0x36); ST7789_WriteData(0x00); // 设置色彩格式 ST7789_WriteCommand(0x3A); ST7789_WriteData(0x05); // 退出睡眠模式 ST7789_WriteCommand(0x11); HAL_Delay(120); // 开启显示 ST7789_WriteCommand(0x29); }4.2 实现基本显示功能显示数据是通过0x2C命令写入的。需要先设置显示区域0x2A和0x2B命令然后连续写入像素数据。void ST7789_SetWindow(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { ST7789_WriteCommand(0x2A); ST7789_WriteData(x1 8); ST7789_WriteData(x1 0xFF); ST7789_WriteData(x2 8); ST7789_WriteData(x2 0xFF); ST7789_WriteCommand(0x2B); ST7789_WriteData(y1 8); ST7789_WriteData(y1 0xFF); ST7789_WriteData(y2 8); ST7789_WriteData(y2 0xFF); ST7789_WriteCommand(0x2C); } void ST7789_FillScreen(uint16_t color) { uint8_t buff[240*2]; // 一行像素的缓冲区 for(int i0; isizeof(buff); i2) { buff[i] color 8; buff[i1] color 0xFF; } ST7789_SetWindow(0, 0, 239, 319); for(int y0; y320; y) { ST7789_WriteDataBulk(buff, sizeof(buff)); } }测试时可以用这些常用颜色#define COLOR_RED 0xF800 #define COLOR_GREEN 0x07E0 #define COLOR_BLUE 0x001F #define COLOR_WHITE 0xFFFF #define COLOR_BLACK 0x00005. 性能优化与常见问题排查5.1 DMA加速显示更新用HAL库的阻塞式传输刷新全屏要300ms左右太慢了。后来我改用DMA速度直接提升到50ms以内void ST7789_UpdateScreen(uint16_t *frameBuffer) { ST7789_SetWindow(0, 0, 239, 319); DC_DATA(); HAL_SPI_Transmit_DMA(hspi1, (uint8_t*)frameBuffer, 240*320*2); }注意帧缓冲区要4字节对齐否则DMA可能会出错。我在SRAM里定义了一个缓冲区__attribute__((aligned(4))) uint16_t frameBuffer[240][320];5.2 常见问题与解决方案屏幕全白或全黑检查背光电路和电源电压典型是3.3V显示错位或花屏确认SPI模式和时钟极性设置正确颜色不对检查0x3A寄存器的值尝试0x05、0x55、0x66显示方向不对调整0x36寄存器的MX/MY/MV位SPI通信失败用逻辑分析仪抓波形确认时序符合要求我遇到过最诡异的问题是屏幕偶尔会闪一下后来发现是电源不稳定在VCC和GND之间加了个100μF电容就解决了。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2423042.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!