STM32:FSMC驱动TFTLCD(ST7789)

最近项目使用STM32F407驱动tft彩屏,屏幕的内部驱动芯片为ST7789V,这个IC网上资料不多。

废话不说,直接上完整驱动代码。

1.代码

/*
*************************************************************************************************
*
*    模块名称 : TFT液晶显示器驱动模块
*    文件名称 : lcd_drv.h
*    版    本 : V1.0
*    说    明 : 头文件.
*               lcddrv_FillColorPre函数设置LCD显示区域,之后把数据赋予LCDDRV_RAM即可绘图此区域.
*               其他绘图函数都可通过lcddrv_FillColorPre和予LCDDRV_RAM构成
***************************************************************************************************
*/

#ifndef __LCD_DRV_H
#define __LCD_DRV_H

#include "stm32f4xx.h"

#define ST7789_REG        *(__IO u16 *)(((uint32_t)0x60000000))
#define ST7789_RAM        *(__IO u16 *)(((uint32_t)0x60000000) + (1 << 17)) //A16 右移1位

/*******************供bsp调用的接口API**********************/
//背景光控制 
#define BRIGHT_MAX        100
#define BRIGHT_MIN        0
#define BRIGHT_DEFAULT    BRIGHT_MAX

#define LCD_WIDTH   320  // 显示屏宽度像素 
#define LCD_HEIGHT  240  // 显示屏高度像素 
#define LCDDRV_RAM  ST7789_RAM      //显示GRAM接收地址

extern void lcddrv_Init(void);      //初始化函数
extern void lcddrv_FillColorPre(u16 X, u16 Y, u16 Width , u16 Height);
extern void lcddrv_SetBackLight(u8 bright);//设置背光
extern void lcddrv_DispOn(void);    //打开显示
extern void lcddrv_DispOff(void);   //关闭显示

#endif

/***************************** (END OF FILE) *********************************/
#include "stm32f4xx.h"
#include <stdio.h>
#include <string.h>
#include "delay.h"
#include "lcd_drv.h"

#define lcddelay_ms(n) delay_ms(n)
#define LCD_RST_PIN  PFout(15)

//ST7789寄存器定义
#define  ST7789_CMD_RDDID 0x04  //读取ID
#define  ST7789_CMD_SLPIN 0x10
#define  ST7789_CMD_SLPOUT 0x11
#define  ST7789_CMD_DISPOFF 0x28
#define  ST7789_CMD_DISPON 0x29
#define  ST7789_CMD_CASETF 0x2A
#define  ST7789_CMD_RASETF 0x2B
#define  ST7789_CMD_RAMWR 0x2C  //开始写内存数据
#define  ST7789_CMD_PTLON 0x12  //部分显示模式
#define  ST7789_CMD_NORON 0x13  //普通模式
#define  ST7789_CMD_INVOFF 0x20 //关闭反显示
#define  ST7789_CMD_INVON 0x21  //打开反显示
#define  ST7789_CMD_PTLAR 0x30  //部分显示区域 由上下两个水平坐标

//写寄存器(CMD)
//regval:寄存器值
static void ST7789_WR_REG(vu16 regval)
{
    regval = regval;        
    ST7789_REG = regval;    
}
//写数据
//data:要写入的值
static void ST7789_WR_DATA(vu16 data)
{
    data = data;          
    ST7789_RAM = data;
}
//读LCD数据
//返回值:读到的值
static u16 ST7789_RD_DATA(void)
{
    vu16 ram;            
    ram = ST7789_RAM;
    return ram;
}

/*
*********************************************************************************************
*    函 数 名: ST7789_ReadID
*    功能说明: 读取LCD驱动芯片ID
*    形    参:  无
*    返 回 值: 无
*********************************************************************************************
*/
u16 ST7789_ReadID(void)
{
    u16 id = 0;
    ST7789_WR_REG(ST7789_CMD_RDDID);
    ST7789_RD_DATA();
    id = ST7789_RD_DATA();
    ST7789_RD_DATA();
    ST7789_RD_DATA() ;
    return id ;
}

/*
****************************************************************************************
*    函 数 名: ST7789_REG_Init
*    功能说明: 初始化LCD驱动芯片寄存器
*    形    参:  无
*    返 回 值: 无
****************************************************************************************
*/
static void ST7789_REG_Init(void)
{
    /* 初始化LCD,写LCD寄存器进行配置 */
    lcddelay_ms(10);
    ST7789_WR_REG(ST7789_CMD_SLPOUT);    //exit SLEEP mode
    lcddelay_ms(150);

    ST7789_WR_REG(0x00D0);  //PWCTRL1: Power Control 1
    ST7789_WR_DATA(0x00A4);
    ST7789_WR_DATA(0x81);

    ST7789_WR_REG(0x00BB);
    ST7789_WR_DATA(0x0030);  //VCOMS: VCOM setting

    ST7789_WR_REG(0x0036);  //memory data access control
    ST7789_WR_DATA(0x60);   //MADCTL: 方向等等

    ST7789_WR_REG(0x003A);  // Interface Pixel Format
    ST7789_WR_DATA(0x05);   //COLMOD: 16bit

    ST7789_WR_REG(0x00E0);
    ST7789_WR_DATA(0x00D0);
    ST7789_WR_DATA(0x0000);
    ST7789_WR_DATA(0x0002);
    ST7789_WR_DATA(0x0007);
    ST7789_WR_DATA(0x000B);
    ST7789_WR_DATA(0x001A);
    ST7789_WR_DATA(0x0031);
    ST7789_WR_DATA(0x0054);
    ST7789_WR_DATA(0x0040);
    ST7789_WR_DATA(0x0029);
    ST7789_WR_DATA(0x0012);
    ST7789_WR_DATA(0x0012);
    ST7789_WR_DATA(0x0012);
    ST7789_WR_DATA(0x0017);            

    ST7789_WR_REG(0x00E1);
    ST7789_WR_DATA(0x00D0);
    ST7789_WR_DATA(0x0000);
    ST7789_WR_DATA(0x0002);
    ST7789_WR_DATA(0x0007);
    ST7789_WR_DATA(0x0005);
    ST7789_WR_DATA(0x0025);
    ST7789_WR_DATA(0x002D);
    ST7789_WR_DATA(0x0044);
    ST7789_WR_DATA(0x0045);
    ST7789_WR_DATA(0x001C);
    ST7789_WR_DATA(0x0018);
    ST7789_WR_DATA(0x0016);
    ST7789_WR_DATA(0x001C);
    ST7789_WR_DATA(0x001D);            

    ST7789_WR_REG(0x21);//取反

    ST7789_WR_REG(ST7789_CMD_DISPON);// DISPALY ON
    lcddelay_ms(100);
}


/*
***************************************************************************************************
*    函 数 名: ST7789_Init
*    功能说明: 初始化LCD
*    形    参: 无
*    返 回 值: 0/1:失败/正确
***************************************************************************************************
*/
u8 ST7789_Init(void)
{
    //硬重启
    LCD_RST_PIN = 1 ;
    lcddelay_ms(3);
    LCD_RST_PIN = 0 ;
    lcddelay_ms(6);
    LCD_RST_PIN = 1 ;
    lcddelay_ms(150);

    if ( ST7789_ReadID() == 0x85 )
    {
        ST7789_REG_Init();    /* 初始化屏IC寄存器 */
        return 1;
    }
    return 0;
}

/*
*************************************************************************************************
*    函 数 名: STM_GPIOConfig
*    功能说明: 配置LCD控制口线,FSMC管脚设置
*    形    参: 无
*    返 回 值: 无
*************************************************************************************************
*/
/*
    LCD的 RS(DC) 引脚 接 PD11/FSMC_A16 (0命令,1数据)
    LCD的 CS 片选引脚 接 PD7/FSMC_NE1
    其他的 NWE, NOE, D15~D0 接对应的FSMC口线即可。
    接线如下:

    PD0/FSMC_D2
    PD1/FSMC_D3
    PD4/FSMC_NOE        --- 读控制信号,OE , N 即低有效 (读)
    PD5/FSMC_NWE        --- 写控制信号,WE  ,N 即低有效 (写)
    PD7/FSMC_NE1        --- 块选择,片选信号CS
    PD8/FSMC_D13
    PD9/FSMC_D14
    PD10/FSMC_D15
    PD11/FSMC_A16        --- 地址 RS DC (命令OR数据选择)
    PD14/FSMC_D0
    PD15/FSMC_D1

    PE7/FSMC_D4
    PE8/FSMC_D5
    PE9/FSMC_D6
    PE10/FSMC_D7
    PE11/FSMC_D8
    PE12/FSMC_D9
    PE13/FSMC_D10
    PE14/FSMC_D11
    PE15/FSMC_D12

    ----  TFT LCD接口其他信号 (非FSMC所使用)----

    PC13/LCD_PWM            --- LCD背光PWM控制 由背光控制函数进行配置初始化
    PF15/LCD_RST            --- 硬复位LCD
*/
static void STM_GPIOConfig(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* 使能 GPIO时钟 */
    RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | 
                            RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOF, ENABLE);

    /* 使能FSMC时钟 */
    RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);

    /* 设置 PD.00(D2), PD.01(D3), PD.04(NOE), PD.05(NWE), PD.08(D13), PD.09(D14),
     PD.10(D15), PD.14(D0), PD.15(D1) 为复用推挽输出 + PD11(DC), PD7(CS) */
    GPIO_InitStructure.GPIO_Pin = 
        GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 |
        GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOD, &GPIO_InitStructure);

    /* 设置 PE.07(D4), PE.08(D5), PE.09(D6), PE.10(D7), PE.11(D8), PE.12(D9), PE.13(D10),
    PE.14(D11), PE.15(D12) 为复用推挽输出 */
    GPIO_InitStructure.GPIO_Pin = 
        GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
        GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_Init(GPIOE, &GPIO_InitStructure);
    /*复用映射功能*/
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);

    GPIO_PinAFConfig(GPIOE, GPIO_PinSource4 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource5 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FSMC);

    /* 设置 PF15 (LCD/RST)) 为推挽输出 */
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
    GPIO_Init(GPIOF, &GPIO_InitStructure);
    GPIO_SetBits(GPIOF, GPIO_Pin_15);
    /* 设置 PF14 (LCD/EN)) 为推挽输出 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_Init(GPIOF, &GPIO_InitStructure);
    GPIO_SetBits(GPIOF, GPIO_Pin_14 );
    
    /* 设置  背光 为PWM */
    //在背光函数
}

/*
*************************************************************************************************
*    函 数 名: STM_FSMCConfig
*    功能说明: 配置FSMC并口访问时序
*    形    参: 无
*    返 回 值: 无
*************************************************************************************************
*/
static void STM_FSMCConfig(void)
{
    FSMC_NORSRAMInitTypeDef  fsmcinit;
    FSMC_NORSRAMTimingInitTypeDef  timingWrite;
    FSMC_NORSRAMTimingInitTypeDef  timingRead;
    // 写 时间配置 主要是 AddressSetupTime 与 DataSetupTime ,可修改更小。写就是LCD显示。
    timingWrite.FSMC_AddressSetupTime = 15;
    timingWrite.FSMC_AddressHoldTime = 0;
    timingWrite.FSMC_DataSetupTime = 20;
    timingWrite.FSMC_BusTurnAroundDuration = 0;
    timingWrite.FSMC_CLKDivision = 0;
    timingWrite.FSMC_DataLatency = 0;
    timingWrite.FSMC_AccessMode = FSMC_AccessMode_A;
    // 读 时间配置 主要是 AddressSetupTime 与 DataSetupTime 
    timingRead.FSMC_AddressSetupTime = 8;
    timingRead.FSMC_AddressHoldTime = 0;
    timingRead.FSMC_DataSetupTime = 9;
    timingRead.FSMC_BusTurnAroundDuration = 0;
    timingRead.FSMC_CLKDivision = 0;
    timingRead.FSMC_DataLatency = 0;
    timingRead.FSMC_AccessMode = FSMC_AccessMode_A;

    fsmcinit.FSMC_Bank = FSMC_Bank1_NORSRAM1;
    fsmcinit.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
    fsmcinit.FSMC_MemoryType = FSMC_MemoryType_SRAM;
    fsmcinit.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
    fsmcinit.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
    fsmcinit.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
    fsmcinit.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
    fsmcinit.FSMC_WrapMode = FSMC_WrapMode_Disable;
    fsmcinit.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
    fsmcinit.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
    fsmcinit.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
    fsmcinit.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; //读写不一致
    fsmcinit.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
    fsmcinit.FSMC_ReadWriteTimingStruct = &timingRead;
    fsmcinit.FSMC_WriteTimingStruct = &timingWrite;

    FSMC_NORSRAMInit(&fsmcinit);

    /* - BANK 1 (of NOR/SRAM Bank 1~4) is enabled */
    FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}

static void MCU_GpioFsmcInit( void )
{
    STM_GPIOConfig();
    STM_FSMCConfig();
}

/****************************供外部使用的函数****************************/

/*
*************************************************************************************************
*    函 数 名: lcddrv_SetBackLight
*    功能说明: 初始化控制LCD背光,配置为PWM模式。
*    形    参: _bright 亮度,0是灭,BRIGHT_MAX最亮
*    返 回 值: 无
**************************************************************************************************
*/
void lcddrv_SetBackLight(uint8_t _bright)
{

    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;

    //打开GPIOD的时钟  
    RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOD , ENABLE);

    if (_bright == 0)
    {
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOD, &GPIO_InitStructure);

        GPIO_ResetBits(GPIOD, GPIO_Pin_13);

       //关闭TIM4
        TIM_Cmd(TIM4, DISABLE);
        return;
    }
    else if (_bright == BRIGHT_MAX)   //最大亮度,直接推挽输出
    {
        // 配置背光GPIO为推挽输出模式 
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOD, &GPIO_InitStructure);

        GPIO_SetBits(GPIOD, GPIO_Pin_13);

        //关闭TIM4 
        TIM_Cmd(TIM4, DISABLE);
        return;
    }

    //配置背光GPIO为复用推挽输出模式 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4); //GPIO复用
    
    //使能TIM4的时钟  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    //TIM 配置: 产生1路PWM信号;
    //分频10K,再 /BRIGHT_MAX
    TIM_TimeBaseStructure.TIM_Period = BRIGHT_MAX - 1;   /* TIM_Period is  ARR Register */
    TIM_TimeBaseStructure.TIM_Prescaler = 7200 - 1;     //10k
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
    // PWM Channel2 
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = ((TIM_TimeBaseStructure.TIM_Period + 1) * _bright) / (BRIGHT_MAX);
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC2Init(TIM4, &TIM_OCInitStructure);
    TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);

    TIM_ARRPreloadConfig(TIM4, ENABLE);
    //使能 TIM4 定时器 
    TIM_Cmd(TIM4, ENABLE);
}

/*
*************************************************************************************************
*    函 数 名: lcddrv_DispOn
*    功能说明: 打开显示
*    形    参: 无
*    返 回 值: 无
*************************************************************************************************
*/
void lcddrv_DispOn(void)
{
    ST7789_WR_REG(ST7789_CMD_DISPON);
}

/*
*************************************************************************************************
*    函 数 名: lcddrv_DispOff
*    功能说明: 关闭显示
*    形    参: 无
*    返 回 值: 无
*************************************************************************************************
*/
void lcddrv_DispOff(void)
{
    ST7789_WR_REG(ST7789_CMD_DISPOFF);
}

/*
*************************************************************************************************
*    函 数 名: lcddrv_FillColorPre
*    功能说明:  设置将要显示的区域。使用此函数后,只需要顺序赋值给LCDDRV_RAM即可绘图此区域.
*    形    参: 无
*    返 回 值: 无
*************************************************************************************************
*/
void lcddrv_FillColorPre(u16 _usX, u16 _usY, u16 _usWidth , u16 _usHeight)
{
    //显示区域限制
    ST7789_WR_REG(ST7789_CMD_CASETF);
    ST7789_WR_DATA(_usX >> 8);
    ST7789_WR_DATA(_usX );
    ST7789_WR_DATA( (_usX + _usWidth - 1) >> 8);
    ST7789_WR_DATA( (_usX + _usWidth - 1) );

    ST7789_WR_REG(ST7789_CMD_RASETF );
    ST7789_WR_DATA(_usY >> 8);
    ST7789_WR_DATA(_usY );
    ST7789_WR_DATA( (_usY + _usHeight - 1) >> 8 );
    ST7789_WR_DATA( (_usY + _usHeight - 1) );
    //准备接收数据
    ST7789_REG = ST7789_CMD_RAMWR;
}

/*
*************************************************************************************************
*    函 数 名: lcddrv_Init
*    功能说明: LCD初始化函数
*    形    参:  _ 
*    返 回 值: 无
**************************************************************************************************
*/
void lcddrv_Init(void)
{
    MCU_GpioFsmcInit();
    lcddrv_SetBackLight(0);
    // FSMC重置后必须延迟
    if ( ST7789_Init() )
    {
        printf("LCD ok r\n");
    }else 
    {
        printf("LCD err \r\n");
    }
}

/****************************(END OF FILE)*****************************/

2.调试过程

这里说说调试过程遇到的坑。

1.一开始发现连背光都不能打开。示波器测电压发现一直低电平。排除软件问题,交给硬件工程师,发现是连锡了。

2.解决背光后,发现LCD还是黑乎乎的,不能显示;甚至连ST7789的ID都不能读取。折腾一阵子软件后,打开电路图,最后发现电源脚没有连接电源,只是对地加电容而已。交给硬件工程师,飞线测试,终于亮了。

3.LCD虽然亮了,但是显示花屏,只能在边缘显示,无法正常显示。以为是初始化寄存器没有搞对,一番折腾,还是不行;最后定下心来慢慢看代码,发现一个函数参数对调搞混了。修改完,OK。

使用FSMC扫屏还是挺快的,我使用的LCD为16位色深,320*240像素。全屏单色扫频看不出绘制过程。使用SD卡放置无压缩的RGB565图片(150KB),使用FATFS文件系统,全屏图片显示,需要100~180毫秒(SD类型不同读取速度有区别)。如果是8位色深的图片,体积少一半,可流畅显示。

 

  • 10
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
对于驱动 TFT LCDFSMC(Flexible Static Memory Controller)在 STM32F407 上的使用,你可以按照以下步骤进行操作: 1. 配置 FSMC 控制器:首先,你需要配置 FSMC 控制器以与 TFT LCD 进行通信。这涉及到配置控制线、地址线和数据线等。你可以参考 STM32F407 参考手册中的 FSMC 章节,了解如何正确配置 FSMC 控制器。 2. 配置 TFT LCD 控制器:根据 TFT LCD 的规格书或者供应商提供的资料,你需要了解 TFT LCD 的时序要求和控制信号定义。然后,根据这些信息配置 FSMC 控制器的时序参数,以确保与 TFT LCD 的正确通信。 3. 编写驱动代码:在配置完 FSMC 控制器和 TFT LCD 控制器后,你需要编写驱动代码来实现绘制图形、显示文本等功能。这通常涉及到像素点的读写、区域填充、字体显示等操作。你可以使用 C 语言或者汇编语言来编写这些代码。 4. 调试和优化:一旦你完成了驱动代码的编写,你需要通过调试和优化来确保驱动的正确性和性能。你可以使用逻辑分析仪或者示波器来观察信号波形,以确保与 TFT LCD 的通信正常。 需要注意的是,TFT LCD驱动方式和接口可能因不同的型号而有所不同,因此在开始驱动之前,最好详细阅读 TFT LCD 的规格书,并参考 STM32F407 参考手册中的相关章节进行配置。此外,也可以参考一些开源项目或者社区提供的代码和资料,以便更好地理解和实现 TFT LCD驱动

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值