芯启元 发表于 2026-7-3 15:46:32

63-QSPI-TFT_DMA_P2P外设到外设_显示视频级动画效果程序-ILI9341,STC32G144K246实验

63-QSPI-TFT_DMA_P2P外设到外设_显示视频级动画效果程序-ILI9341,STC32G144K246实验箱演示程序
主程序main.C代码如下(汇编版本在附件中):


/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/* --- BBS: www.STCAIMCU.com-----------------------------------------*/
/*---------------------------------------------------------------------*/

/*************功能说明    **************

本例程基于STC32G144K246为主控芯片的实验箱进行编写测试。

使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。

edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。

QSPI DMA + LCM DMA驱动液晶屏程序

按住P3.3后上电,芯片进入FLASH下载模式,使用6.94P以后版本的ISP下载软件中的“串行Flash编程器”

工具将多幅图片下载到实验箱的Flash中,然后重新上电(P3.3不要按),即可进入动画显示模式

显示时QSPI 读取Flash图片数据,通过P2P DMA直接发送数据到LCM显示图片。

QSPI读取Flash与LCM显示DMA的数据长度设置51200字节。

16bit I8080模式, P0,P2口接数据线

sbit    LCM_CS      =   P9^3;
sbit    LCM_RS      =   P4^5;
sbit    LCM_WR      =   P4^2;
sbit    LCM_RD      =   P4^4;
sbit    LCM_RST   =   P5^1;

QSPI Flash 接口:
sbit    CS          =   P7^5;
sbit    SDI_IO0   =   P7^0;
sbit    SDO_IO1   =   P7^2;
sbit    SCK         =   P7^1;
sbit    WP_IO2      =   P7^3;
sbit    HLD_IO3   =   P7^4;

下载时, 选择时钟 48MHz (频率定义参数在config.h修改).

本实验使用3.2寸320*240的并口彩屏

******************************************/

#include "config.h"
#include "qspi.h"
#include "w25qxx.h"
#include "lcm.h"
#include "tft.h"
#include "usbcdc.h"
#include "timer.h"

#define IMG_SIZE            (320UL * 240 * 2)
#define DMA_AMT_LEN         (51200UL)
#define DMA_CNT             (IMG_SIZE / DMA_AMT_LEN)

void QSPI2TFT_Start();
void QSPI2TFT_Next();

typedef struct
{
    char strSign;
    DWORD dwCount;
    DWORD dwAddress;
} FAT;

FAT   Fat;                            //文件分配表
DWORD   dwOffset;                     //图片数据的偏移地址
int   nIndex;                         //图片索引
int   nCount;                         //图片数据装载次数
BOOL    fLoading;                     //装载数据标志

void main()
{
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 1; //避免 DMA 与 CPU 同时访问 xdata 时产生总线冲突

    P3PU |= 0x08;   //使能P3.3内部上拉电阻
   
    TIMER0_Init();
    QSPI_Init();
    LCM_Init();
    TFT_Init();
   
    EA = 1;

    W25Q_Enable_QE();                   //使能QSPI FLASH的4线读写模式
   
    if (!P33)                           //按住P3.3复位,进入图片数据下载模式
    {
      CDC_Init();
      CDC_WaitStable();                   //等待USB-CDC配置完成
      while (1)
      {
            CDC_Process();            //CDC接口处理图片数据
      }
    }
   
    W25Q_FastRead_6B(0, (BYTE *)&Fat, 256);   //从FLASH第一页读取FAT
   
    nIndex = 0;                         //从第一幅图片开始显示
    while (1)
    {
      if (f100ms)
      {
            f100ms = 0;
            
            QSPI2TFT_Start();         //每隔100ms自动显示下一幅图片
      }
    }
}

void QSPI_DMA_Isr() interrupt DMA_QSPI_VECTOR
{
    DMA_QSPI_STA = 0x00;
    QSPI2TFT_Next();                  //DMA传输下一包数据
}

void QSPI2TFT_Start()
{
    if (fLoading)                     //如果正在装载图片,则退出
      return;

    if (nIndex >= Fat.dwCount)          //如果图片索引达到最大值
      nIndex = 0;                     //则从第一幅图片开始循环

    dwOffset = Fat.dwAddress; //获取当前图片的偏移地址
    nCount = 0;                         //初始化图片数据装载次数
   
    while (QSPI_CheckBusy());         //检测忙状态
    QSPI_SetReadMode();               //读模式
    QSPI_SetDataLength(DMA_AMT_LEN-1);//设置数据长度
    QSPI_SetAddressSize(2);             //设置地址宽度为24位(2+1字节)
    QSPI_SetDummyCycles(8);             //设置DUMMY时钟
    QSPI_NoInstruction();               //设置无指令模式(防止误触发)
    QSPI_NoAddress();                   //设置无地址模式(防止误触发)
    QSPI_AlternateQuadMode();         //设置间隔字节
    QSPI_DataQuadMode();                //设置数据为四线模式
    QSPI_SetInstruction(0x6B);          //设置指令
    QSPI_InstructionSingMode();         //设置指令为单线模式
    QSPI_NoAddress();                   //设置无地址模式(防止误触发)
    QSPI_SetAddress(dwOffset);          //设置地址
    QSPI_AddressSingMode();             //设置地址为单线模式
               
    TFT_ShowStart();                  //开始TFT彩屏显示

    DMA_P2P1_SRC = P2P_SRC_QSPIRX;
    DMA_P2P1_DEST = P2P_DEST_LCMTX;
    DMA_QSPI_CFG = 0xa0;                //使能DMA读取操作
    DMA_QSPI_STA = 0x00;                //清除DMA状态
    DMA_QSPI_AMT = (DMA_AMT_LEN-1);   //设置DMA数据长度
    DMA_QSPI_AMTH = (DMA_AMT_LEN-1) >> 8;

    DMA_LCM_CR = 0xa0;
    DMA_QSPI_CR = 0xa1;               //启动DMA并触发QSPI读操作
   
    P47 = 0;
   
    fLoading = TRUE;
}

void QSPI2TFT_Next()
{
    dwOffset += DMA_AMT_LEN;            //更新偏移地址
    nCount++;                           //装载次数+1
   
    if (nCount < DMA_CNT)               //判断图片数据装载次数
    {
      QSPI_NoAddress();               //设置无地址模式(防止误触发)
      QSPI_SetAddress(dwOffset);      //设置地址
      QSPI_AddressSingMode();         //设置地址为单线模式
      
      DMA_QSPI_CR = 0xa1;             //启动DMA并触发QSPI读操作
    }
    else
    {
      P47 = 1;

      fLoading = FALSE;               //图片数据装载完成
      DMA_QSPI_CR = 0x00;             //停止QSPI_DMA
      DMA_QSPI_CFG = 0x00;
      DMA_LCM_CR = 0x00;
      
      TFT_ShowEnd();                  //结束TFT彩屏显示数据输入
    }
}

void delay_ms(WORD ms)
{
    WORD i;
   
    do
    {
      i = FOSC / 6000;
      while(--i);
    } while(--ms);
}




页: [1]
查看完整版本: 63-QSPI-TFT_DMA_P2P外设到外设_显示视频级动画效果程序-ILI9341,STC32G144K246实验