168|4

435

帖子

3

TA的资源

纯净的硅(高级)

楼主
 

【FRDM-MCXN947】TFT-LCD显示屏测试 [复制链接]

本帖最后由 TL-LED 于 2024-12-22 22:50 编辑

使用FLEXIO接口测试TFT-LCD显示屏,驱动芯片使用SSD1963。

 

一、硬件接口部分

 

1.1、使用板子上的LCD接口

 

1.2、SSD1963接口框图

1.3、SSD1963数据格式

SSD1963与显示屏之间数据接口的连接定义

 

1.4、显示屏接口

我的显示屏是18位总线,在配置SSD1963时,选择18位数据。

 

二、引脚配置

 

2.1、配置显示屏接口

 

2.2、配置外设

 

三、程序部分

 

3.1、mculcd.c

#include "main.h"



/*******************************************************************************
 * Prototypes
 ******************************************************************************/
void BOARD_InitSmartDMA(void);
static void DEMO_InitFlexioMcuLcd(void);
static void DEMO_InitPanel(void);
static void DEMO_StartPanel(void);
static status_t DEMO_LcdWriteCommand(void *dbiXferHandle, uint32_t command);
static status_t DEMO_LcdWriteData(void *dbiXferHandle, void *data, uint32_t len_byte);
static status_t DEMO_LcdWriteMemory(void *dbiXferHandle, uint32_t command, const void *data, uint32_t len_byte);

/*******************************************************************************
 * Variables
 ******************************************************************************/
/* The functions used to drive the panel. */
static dbi_xfer_ops_t s_flexioDbiOps = {
    .writeCommand          = DEMO_LcdWriteCommand,
    .writeData             = DEMO_LcdWriteData,
    .writeMemory           = DEMO_LcdWriteMemory,
    .readMemory            = NULL, /* Don't need read in this project. */
    .setMemoryDoneCallback = NULL, /* This used for upper layer to register callback.
                                      If the writeMemory is a non-blocking(or async)
                                      function, when write finished, the registered
                                      callback function will be called.
                                      In this project, to be simple, DEMO_LcdWriteMemory
                                      blocks to wait the write done, it is not async
                                      implementation, so don't need to set callback.
                                    */
};

static ssd1963_handle_t lcdHandle;
static flexio_mculcd_smartdma_handle_t s_flexioLcdHandle;
static demo_pixel_t s_lcdBuffer[DEMO_BUFFER_HEIGHT][DEMO_BUFFER_WIDTH];
static volatile bool s_transferDone = false;


void FLEXIO_TransferCallback(FLEXIO_MCULCD_Type *,flexio_mculcd_smartdma_handle_t *,status_t ,void *)							
{
    s_transferDone = true;
}

void BOARD_SetResetPin(bool set)
{
    GPIO_PinWrite(DEMO_SSD1963_RST_GPIO, DEMO_SSD1963_RST_PIN, (uint8_t)set);
}

void BOARD_InitSmartDMA(void)
{
    RESET_ClearPeripheralReset(kMUX_RST_SHIFT_RSTn);

    INPUTMUX_Init(INPUTMUX0);
    INPUTMUX_AttachSignal(INPUTMUX0, 0, kINPUTMUX_FlexioToSmartDma);

    /* Turnoff clock to inputmux to save power. Clock is only needed to make changes */
    INPUTMUX_Deinit(INPUTMUX0);

    SMARTDMA_InitWithoutFirmware();

    NVIC_EnableIRQ(SMARTDMA_IRQn);
    NVIC_SetPriority(SMARTDMA_IRQn, 3);
}

static status_t DEMO_LcdWriteCommand(void *dbiXferHandle, uint32_t command)
{
    /* dbiXferHandle is actually s_flexioLcdHandle, set by SSD1963_Init 4th parameter. */
    flexio_mculcd_smartdma_handle_t *flexioLcdHandle = (flexio_mculcd_smartdma_handle_t *)dbiXferHandle;

    /* Here use blocking way to send command, because command is short. */
    FLEXIO_MCULCD_Type *flexioLCD = flexioLcdHandle->base; /* flexioLcdDev */

    FLEXIO_MCULCD_StartTransfer(flexioLCD);
    FLEXIO_MCULCD_WriteCommandBlocking(flexioLCD, command);
    FLEXIO_MCULCD_StopTransfer(flexioLCD);

    return kStatus_Success;
}

static status_t DEMO_LcdWriteData(void *dbiXferHandle, void *data, uint32_t len_byte)
{
    /* dbiXferHandle is actually s_flexioLcdHandle, set by SSD1963_Init 4th parameter. */
    flexio_mculcd_smartdma_handle_t *flexioLcdHandle = (flexio_mculcd_smartdma_handle_t *)dbiXferHandle;

    /*
     * Here use blocking way to write data, this function is generally
     * used to send command parameter, the data length is short.
     */
    FLEXIO_MCULCD_Type *flexioLCD = flexioLcdHandle->base; /* flexioLcdDev */

    FLEXIO_MCULCD_StartTransfer(flexioLCD);
    FLEXIO_MCULCD_WriteDataArrayBlocking(flexioLCD, data, len_byte);
    FLEXIO_MCULCD_StopTransfer(flexioLCD);

    return kStatus_Success;
}

static status_t DEMO_LcdWriteMemory(void *dbiXferHandle, uint32_t command, const void *data, uint32_t len_byte)
{
    status_t status;

    /* dbiXferHandle is actually s_flexioLcdHandle, set by SSD1963_Init 4th parameter. */
    flexio_mculcd_smartdma_handle_t *flexioLcdHandle = (flexio_mculcd_smartdma_handle_t *)dbiXferHandle;

    FLEXIO_MCULCD_Type *flexioLCD = flexioLcdHandle->base; /* flexioLcdDev */

    flexio_mculcd_transfer_t xfer = {
        .command             = command,
        .mode                = kFLEXIO_MCULCD_WriteArray,
        .dataAddrOrSameValue = (uint32_t)data,
        .dataSize            = len_byte,
    };

    s_transferDone = false;
    status         = FLEXIO_MCULCD_TransferSMARTDMA(flexioLCD, flexioLcdHandle, &xfer);

    if (kStatus_Success != status)
    {
        PRINTF("Write Memory Failed\r\n");
        while (1)
        {
        }
    }
    else
    {
        /* Wait for transfer done. */
        while (!s_transferDone)
        {
        }
    }

    return status;
}

static void DEMO_InitFlexioMcuLcd(void)
{
    status_t status;

    flexio_mculcd_config_t flexioMcuLcdConfig;
    flexio_mculcd_smartdma_config_t flexioEzhConfig = {
        .inputPixelFormat = kFLEXIO_MCULCD_RGB565,
        .outputPixelFormat = kFLEXIO_MCULCD_RGB565,
    };

    /* Initialize the flexio MCU LCD. */
    /*
     * flexioMcuLcdConfig.enable = true;
     * flexioMcuLcdConfig.enableInDoze = false;
     * flexioMcuLcdConfig.enableInDebug = true;
     * flexioMcuLcdConfig.enableFastAccess = true;
     * flexioMcuLcdConfig.baudRate_Bps = 96000000U;
     */
//    FLEXIO_MCULCD_GetDefaultConfig(&flexioMcuLcdConfig);
//    flexioMcuLcdConfig.baudRate_Bps = DEMO_FLEXIO_BAUDRATE_BPS;

//    status = FLEXIO_MCULCD_Init(&flexioLcdDev, &flexioMcuLcdConfig, DEMO_FLEXIO_CLOCK_FREQ);

//    if (kStatus_Success != status)
//    {
//        PRINTF("FlexIO MCULCD init failed\r\n");
//        while (1)
//            ;
//    }

    /* Init SMARTDMA. */
 //   BOARD_InitSmartDMA();    

//    /* Create FLEXIO_MCULCD SMARTDMA handle. */
//    status = FLEXIO_MCULCD_TransferCreateHandleSMARTDMA(&flexioLcdDev, &s_flexioLcdHandle, &flexioEzhConfig,
//                                                      DEMO_FLEXIO_TransferCallback, NULL);
//		status = FLEXIO_MCULCD_TransferCreateHandleSMARTDMA(&FLEXIO0_peripheralConfig, &ss_flexioLcdHandle, &FLEXIO0_smartdma_config,
//                                                      FLEXIO_TransferCallback, NULL);
//    if (kStatus_Success != status)
//    {
//        PRINTF("FlexIO MCULCD handle creation failed\r\n");
//        while (1)
//            ;
//    }
}

static void DEMO_InitPanel(void)
{
    status_t status;

    const ssd1963_config_t ssd1963Config = {
        .pclkFreq_Hz = DEMO_SSD1963_PCLK_FREQ,
#if SSD1963_DATA_WITDH == 16
        .pixelInterface = kSSD1963_PixelInterface16Bit565,
#else
        .pixelInterface = kSSD1963_PixelInterface8BitBGR888,
#endif
        .panelDataWidth = kSSD1963_PanelData18Bit,
        .polarityFlags  = DEMO_SSD1963_POLARITY_FLAG,
        .panelWidth     = DEMO_PANEL_WIDTH,
        .panelHeight    = DEMO_PANEL_HEIGHT,
        .hsw            = DEMO_SSD1963_HSW,
        .hfp            = DEMO_SSD1963_HFP,
        .hbp            = DEMO_SSD1963_HBP,
        .vsw            = DEMO_SSD1963_VSW,
        .vfp            = DEMO_SSD1963_VFP,
        .vbp            = DEMO_SSD1963_VBP
    };

    /* Reset the SSD1963 LCD controller. */
    BOARD_SetResetPin(false);
    SDK_DelayAtLeastUs(1, SystemCoreClock); /* Delay 10ns. */
    BOARD_SetResetPin(true);
    SDK_DelayAtLeastUs(5000, SystemCoreClock); /* Delay 5ms. */

    status = SSD1963_Init(&lcdHandle, &ssd1963Config, &s_flexioDbiOps, &ss_flexioLcdHandle, DEMO_SSD1963_XTAL_FREQ);

    if (kStatus_Success != status)
    {
        PRINTF("Panel initialization failed\r\n");
        while (1)
        {
        }
    }
}

void DEMO_StartPanel(void)
{
    SSD1963_StartDisplay(&lcdHandle);
    SSD1963_SetBackLight(&lcdHandle, 255);
}

/*
 * Draw one window with pixel array, and delay some time after draw done.
 */
void DEMO_DrawWindow(uint16_t startX,
                            uint16_t startY,
                            uint16_t endX,
                            uint16_t endY,
                            const uint8_t *data,
                            uint32_t dataLen,
                            uint32_t delayMsAfterDraw)
{
    SSD1963_SelectArea(&lcdHandle, startX, startY, endX, endY);
    SSD1963_WriteMemory(&lcdHandle, data, dataLen);

    if (delayMsAfterDraw > 0)
    {
        SDK_DelayAtLeastUs(delayMsAfterDraw * 1000, SystemCoreClock);
    }
}

/*
 * Draw multiple windows with specified color, can delay some time each window draw finished.
 * In this example, the whole screen is devided in to 4 windows, this function fills the
 * windows one by one.
 */
void DEMO_DrawMultiWindows(demo_pixel_t color, uint32_t intervalMs)
{
    /* Fill buffer with pixel. */
    for (uint32_t y = 0; y < DEMO_BUFFER_HEIGHT; y++)
    {
        for (uint32_t x = 0; x < DEMO_BUFFER_WIDTH; x++)
        {
            s_lcdBuffer[y][x] = color;
        }
    }

    /* Region 0. */
    DEMO_DrawWindow(0, 0, DEMO_BUFFER_WIDTH - 1, DEMO_BUFFER_HEIGHT - 1, (const uint8_t *)s_lcdBuffer,
                    sizeof(s_lcdBuffer), intervalMs);

    /* Region 1. */
    DEMO_DrawWindow(DEMO_BUFFER_WIDTH, 0, 2 * DEMO_BUFFER_WIDTH - 1, DEMO_BUFFER_HEIGHT - 1,
                    (const uint8_t *)s_lcdBuffer, sizeof(s_lcdBuffer), intervalMs);

    /* Region 2. */
    DEMO_DrawWindow(0, DEMO_BUFFER_HEIGHT, DEMO_BUFFER_WIDTH - 1, 2 * DEMO_BUFFER_HEIGHT - 1,
                    (const uint8_t *)s_lcdBuffer, sizeof(s_lcdBuffer), intervalMs);

    /* Region 3. */
    DEMO_DrawWindow(DEMO_BUFFER_WIDTH, DEMO_BUFFER_HEIGHT, 2 * DEMO_BUFFER_WIDTH - 1, 2 * DEMO_BUFFER_HEIGHT - 1,
                    (const uint8_t *)s_lcdBuffer, sizeof(s_lcdBuffer), intervalMs);
}


void init_mculcd(void)
{
	BOARD_InitBootPeripherals();
	BOARD_InitSmartDMA();
	DEMO_InitPanel();
	DEMO_DrawMultiWindows(DEMO_COLOR_BLACK, 0);

	DEMO_StartPanel();
}

 

3.2、mculcd.h

#ifndef __MCULCD_H
#define __MCULCD_H

#define DEMO_PANEL_WIDTH  640U
#define DEMO_PANEL_HEIGHT 480U

/* Macros for the LCD controller. */
#define DEMO_SSD1963_XTAL_FREQ     10000000U
#define DEMO_SSD1963_PCLK_FREQ     25000000U
#define DEMO_SSD1963_HSW           1U
#define DEMO_SSD1963_HFP           116U
#define DEMO_SSD1963_HBP           44U
#define DEMO_SSD1963_VSW           1U
#define DEMO_SSD1963_VFP           10U
#define DEMO_SSD1963_VBP           34U
#define DEMO_SSD1963_POLARITY_FLAG 0U
#define DEMO_SSD1963_RST_GPIO      GPIO4
#define DEMO_SSD1963_RST_PIN       7
#define DEMO_SSD1963_CS_GPIO       GPIO0
#define DEMO_SSD1963_CS_PIN        12
#define DEMO_SSD1963_RS_GPIO       GPIO0
#define DEMO_SSD1963_RS_PIN        7

#define DEMO_FLEXIO              FLEXIO0
#define DEMO_FLEXIO_CLOCK_FREQ   CLOCK_GetFlexioClkFreq()
#define DEMO_FLEXIO_BAUDRATE_BPS 160000000U /* 16-bit data bus, baud rate on each pin is 1MHz. */

/* Macros for FlexIO shifter, timer, and pins. */
#define DEMO_FLEXIO_WR_PIN           1
#define DEMO_FLEXIO_RD_PIN           0
#define DEMO_FLEXIO_DATA_PIN_START   16
#define DEMO_FLEXIO_TX_START_SHIFTER 0
#define DEMO_FLEXIO_RX_START_SHIFTER 0
#define DEMO_FLEXIO_TX_END_SHIFTER   7
#define DEMO_FLEXIO_RX_END_SHIFTER   7
#define DEMO_FLEXIO_TIMER            0

/* Macros for DMA */
#define DEMO_EDMA                  DMA0
#define DEMO_FLEXIO_TX_DMA_CHANNEL 0
#define DEMO_FLEXIO_TX_DMA_REQUEST kDma0RequestMuxFlexIO0ShiftRegister0Request


/* Buffer of the LCD send data. */
#define DEMO_BUFFER_WIDTH  (DEMO_PANEL_WIDTH / 2U)
#define DEMO_BUFFER_HEIGHT (DEMO_PANEL_HEIGHT / 2U)

/* Color for RGB565 */
typedef uint16_t demo_pixel_t;
#define DEMO_COLOR_RED   0xF800U
#define DEMO_COLOR_GREEN 0x07E0U
#define DEMO_COLOR_BLUE  0x001FU
#define DEMO_COLOR_WHITE 0xFFFFU
#define DEMO_COLOR_BLACK 0x0000U

void init_mculcd(void);

void DEMO_DrawWindow(uint16_t startX,
                            uint16_t startY,
                            uint16_t endX,
                            uint16_t endY,
                            const uint8_t *data,
                            uint32_t dataLen,
                            uint32_t delayMsAfterDraw);
														
void DEMO_DrawMultiWindows(demo_pixel_t color, uint32_t intervalMs);
               
#endif


 

3.3、main.c

#include "main.h"

int main(void)
{
	uint8_t i;
	uint8_t colorIdx                = 0;
	const demo_pixel_t colorTable[] = {
			DEMO_COLOR_RED,
			DEMO_COLOR_GREEN,
			DEMO_COLOR_BLUE,
			DEMO_COLOR_WHITE,
	};

  CLOCK_EnableClock(kCLOCK_Gpio0);
	BOARD_InitDEBUG_UARTPins();
	BOARD_PowerMode_OD();
	BOARD_InitBootPins();
	BOARD_InitBootClocks();
	BOARD_InitDebugConsole();

	SysTick_Init();
	init_led();
	init_key();		
	init_mculcd();

	while (1)
	{
		DEMO_DrawMultiWindows(colorTable[colorIdx], 500);

		colorIdx++;
		if (colorIdx >= ARRAY_SIZE(colorTable))
		{
				colorIdx = 0U;
		}
		led_red_tog();
	}
}

 

3.4、 源代码

n947_prj_20241222_2.rar (5.77 MB, 下载次数: 0)

 

四、运行结果

 

下载程序到开发板,显示屏显示如下

lvgl

 

 

 

此帖出自NXP MCU论坛

最新回复

这个要是有那个官方的模块效果会不会更好,省的配置了   详情 回复 发表于 前天 22:53
点赞 关注(1)
 

回复
举报

2927

帖子

4

TA的资源

五彩晶圆(中级)

沙发
 

感觉楼主的速度有点慢,是不是楼主程序有延时。

此帖出自NXP MCU论坛

点评

小窗口循环显示有延时  详情 回复 发表于 4 天前
 
 
 

回复

435

帖子

3

TA的资源

纯净的硅(高级)

板凳
 
bigbat 发表于 2024-12-23 09:40 感觉楼主的速度有点慢,是不是楼主程序有延时。

小窗口循环显示有延时

此帖出自NXP MCU论坛
 
 
 

回复

7001

帖子

2

TA的资源

版主

4
 

刷新颜色看起来还行,没有撕裂和卡顿。

此帖出自NXP MCU论坛
 
 
 

回复

6291

帖子

10

TA的资源

版主

5
 

这个要是有那个官方的模块效果会不会更好,省的配置了

此帖出自NXP MCU论坛
 
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 

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

开源项目 更多>>
    随便看看
    查找数据手册?

    EEWorld Datasheet 技术支持

    相关文章 更多>>
    关闭
    站长推荐上一条 1/3 下一条

     
    EEWorld订阅号

     
    EEWorld服务号

     
    汽车开发圈

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表