找回密码
 立即注册
楼主: 浦江一水

基于AI8051U_V1.2实验箱_学习实验之驱动TFT彩屏显示全屏图片(QSPI_DMA_P2P)(已优化)

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:292
  • 最近打卡:2026-07-01 23:24:32
已绑定手机

9

主题

122

回帖

838

积分

高级会员

积分
838
发表于 2025-10-15 10:54:31 | 显示全部楼层
或者说只显示其中的一张,        然后通过一个循环函数一张张的显示

                        for(n=0;n<3;n++)
                        {
                                DispPic(n);
                        //        WaitKey();
                                Delay(500);
                        }
               
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:292
  • 最近打卡:2026-07-01 23:24:32
已绑定手机

9

主题

122

回帖

838

积分

高级会员

积分
838
发表于 2025-10-15 11:33:05 | 显示全部楼层
在主函数中做了这样修改
    while (1)
    {
                        Test_Color();
                       
                        for(i=0;i<13;i++)
                 {
                        QSPI2TFT_Start(i);
                         delay_ms(5000);
                         i++;
           }
//        if (f100ms)
//        {
//            f100ms = 0;
//            QSPI2TFT_Start();           //每隔100ms自动显示下一幅图片
//        }
    }


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

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

//    dwOffset = Fat.dwAddress[nIndex++]; //获取当前图片的偏移地址
                dwOffset = Fat.dwAddress[nIndex]; //获取当前图片的偏移地址
    nCount = 0;                         //初始化图片数据装载次数
   

这样修改后,图片只显示了2张,刷完第一张后就直接停留在了第二张图片,然后就刷不动了,不知道是啥原因
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:292
  • 最近打卡:2026-07-01 23:24:32
已绑定手机

9

主题

122

回帖

838

积分

高级会员

积分
838
发表于 2025-10-15 12:41:33 | 显示全部楼层
弄成功了,刚才声明的时候漏掉了参数。
重新替换后,就实现了刷图效果。
//void QSPI2TFT_Start();
void QSPI2TFT_Start(BYTE nIndex);  

点评

很不错! 融汇贯通,灵活运用.  详情 回复 发表于 2025-10-20 11:05
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:887
  • 最近打卡:2026-07-05 07:21:25

31

主题

428

回帖

4672

积分

荣誉版主

积分
4672
发表于 2025-10-20 11:05:16 | 显示全部楼层
toms*** 发表于 2025-10-15 12:41
弄成功了,刚才声明的时候漏掉了参数。
重新替换后,就实现了刷图效果。
//void QSPI2TFT_Start();

很不错! 融汇贯通,灵活运用.
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:202
  • 最近打卡:2026-07-04 17:28:31
已绑定手机

25

主题

2662

回帖

3411

积分

论坛元老

积分
3411
发表于 2026-6-10 12:51:33 | 显示全部楼层
浦江老师:
您好!
   我尝试把您的程序移植到TFT st7789 240*240 的屏



也是用STC 的AI8051U 试验箱  骨架搭起来了(借用了STC 的AICube 工具)

现在菜单的后2项可以用(读W25Q128没问题)----UART1

但是最关键的浏览图片  QSPI P2P SPI 就死活不工作,不知道卡死在哪里?
  1. //开始装载图片函数
  2. void QSPI2TFT_Start()
  3. {
  4.                 if (fLoading)                       //如果正在装载图片,则退出
  5.         return;
  6.     if (nIndex >= Fat.dwCount)          //如果图片索引达到最大值
  7.         nIndex = 0;                     //则从第一幅图片开始循环
  8.     dwOffset = Fat.dwAddress[nIndex++]; //获取当前图片的偏移地址
  9.     nCount = 0;                         //初始化图片数据装载次数
  10.         //TFT_ShowStart()中彻底删除 LCD_CS_PIN = 0,让 DMA 硬件全权管理 CS:       
  11.         LCD_Set_Address(0,0,LCD_WIDTH-1,LCD_HEIGHT-1); //TFT准备接收,TFT彩屏确定显示位置
  12.                 
  13.         // W25Q128 + Fast Read Quad I/O (0x6B) QSPI的典型配置一次性,不反复
  14. // ====== 一、先配置 QSPI 外设本身 ======
  15.         // ====== 1. 等待 QSPI就绪 ======
  16.         while (QSPI_CheckBusy());                   //检测忙状态
  17. /*        
  18.         // ====== 2. 设置基本参数 ======
  19.         QSPI_SetReadMode();                     // 读模式
  20.         QSPI_SetClockDivider(4);                // 分频系数,例如4分频(40MHz→10MHz)
  21.                                                                                         // 建议先设小分频(快一点),稳定后再调
  22.         QSPI_SetDataLength(DMA_AMT_LEN - 1);    // 单次传输字节数 - 1
  23.         QSPI_SetAddressSize(3);                 // W25Q128地址是24位(3字节),所以填3
  24.         QSPI_SetDummyCycles(8);                 // 0x6B指令需要8个dummy clock       
  25.         // ====== 3. 配置指令 ======
  26.         QSPI_SetInstruction(0x6B);              // Fast Read Quad I/O
  27.         QSPI_InstructionSingMode();             // 指令用单线模式发送(这是 W25Q128的要求)
  28.         // ====== 4. 配置地址 ======
  29.         QSPI_SetAddress(dwOffset);              // 要读取的起始地址
  30.         QSPI_AddressSingMode();                 // 地址用单线模式发送
  31.         // ====== 5. 配置数据 ======
  32.         QSPI_DataQuadMode();                    // 数据用四线模式接收
  33.         // ====== 6. 配置其他 ======
  34.         QSPI_NoAlternate();                     // 无交替字节(大多数情况不需要)
  35.        
  36. // ======  二、再设 P2P 路由(推荐放这里) ======
  37.     DMA_P2P_CR1 = P2P_SRC_QSPIRX | P2P_DEST_SPITX;  // 0x85       
  38. // ====== 三、 然后配 QSPI DMA(源端) ======       
  39.         // --- QSPI DMA 配置---
  40.         DMA_QSPI_CFG = 0xa0;
  41.     DMA_QSPI_STA = 0x00;
  42.     DMA_QSPI_AMT = DMA_AMT_LEN - 1;
  43.     DMA_QSPI_AMTH = (DMA_AMT_LEN - 1) >> 8;
  44. // ====== 四、 再配 SPI DMA(目标端) ======       
  45.         // --- SPI DMA(必须先就绪) ---
  46.         DMA_SPI_CFG &= ~0x40;   // ★ 关掉 ACT_TX!P2P模式下数据来自路由,不是 XRAM40
  47.     DMA_SPI_AMT = DMA_AMT_LEN - 1;
  48.     DMA_SPI_AMTH = (DMA_AMT_LEN - 1) >> 8;
  49.        
  50. // ====== 五、 最后按顺序启动 ======
  51.         DMA_SPI_CR = 0xC1;   //目标 SPI DMA 先就绪,等待接收
  52.         // 0x81 = ENSPI(1) | CLRFIFO(1),B6(TRIG_M)=0 只使能 + 清 FIFO,不触发
  53.         DMA_QSPI_CR = 0xa1;     // ★ 源 QSPI DMA 使能 + 触发 + 清 FIFO 源启动,开始读 Flash并推送
  54.                             // 0xC1 = EN(1) | TRIG(1) | CLRFIFO(1) C1
  55. */
  56.         QSPI_SetReadMode();                 //读模式
  57.         QSPI_SetClockDivider(30);                              //设置QSPI时钟为系统时钟(速度匹配)
  58.         QSPI_SetDataLength(DMA_AMT_LEN-1);  //设置数据长度
  59.         QSPI_SetAddressSize(2);             //设置地址宽度为24位(2+1字节)
  60.         QSPI_SetDummyCycles(8);             //设置DUMMY时钟
  61.         QSPI_NoInstruction();               //设置无指令模式(防止误触发)
  62.         QSPI_NoAddress();                   //设置无地址模式(防止误触发)
  63.         QSPI_NoAlternate();                 //无间隔字节
  64.         QSPI_DataQuadMode();                //设置数据为四线模式
  65.         QSPI_SetInstruction(0x6B);          //设置指令
  66.         QSPI_InstructionSingMode();         //设置指令为单线模式
  67.         QSPI_NoAddress();                   //设置无地址模式(防止误触发)
  68.         QSPI_SetAddress(dwOffset);          //设置地址
  69.         QSPI_AddressSingMode();             //设置地址为单线模式
  70.         DMA_P2P_CR1 = 0x85;                 //P2P_SRC_QSPIRX(0x80) | P2P_DEST_SPITX(0x05);
  71.         DMA_QSPI_CFG = 0xa0;                //QSPI_DMA中断使能+DMA读取操作使能
  72.         DMA_QSPI_STA = 0x00;                //清除DMA状态
  73.         DMA_QSPI_AMTH = (DMA_AMT_LEN-1) >> 8;
  74.         DMA_QSPI_AMT = (DMA_AMT_LEN-1);     //设置DMA数据长度
  75.         DMA_SPI_CR = 0xc1;//0xc1 = 1100 0001(二进制)使能 SPI_DMA 功能 触发 SPI_DMA 主机模式操作(开始传输)
  76.         //不触发从机模式 B4~B1 0000        保留 B0=1-- 清空 SPI_DMA 内置的 FIFO
  77.         DMA_QSPI_CR = 0xa1;                 //启动DMA并触发QSPI读操作
  78.        
  79.         fLoading = TRUE;
  80.        
  81.         P20 =0 ;
  82. // ====== 六、 等待完成 卡死在这里======   
  83.     while (!(DMA_QSPI_STA & 0x01));    // 轮询等待传输完成
  84.         P21=0;
  85. //    // --- 清理 ---
  86. //    DMA_QSPI_STA = 0x00;
  87. //    DMA_SPI_STA = 0x00;
  88.     fLoading = TRUE;
  89.        
  90. }
复制代码
能否在不忙的时候指导一下?

点评

这位同学好! 你发此信息已经收到。将抽空学习研究一下,再回复你。  详情 回复 发表于 2026-6-11 10:40
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:202
  • 最近打卡:2026-07-04 17:28:31
已绑定手机

25

主题

2662

回帖

3411

积分

论坛元老

积分
3411
发表于 2026-6-10 12:54:49 | 显示全部楼层
对了,我把整个项目也发上来:

这种直接卡死在底层的错误,对我们水平很低的人来讲,就死翘翘!

因为SPI 和LCM 不同,我查了一下:

AI8051U 中,P2P 控制寄存器是DMA_P2P_CR1 DMA_P2P_CR2



所以 AI8051U 上 QSPI→P2P→SPI 的写法是:

// P2P1: QSPI接收(源) → SPI1发送(目标)


根据 P2P 源/目标枚举值(手册 34.16 节):

源外设 QSPI(接收) = 0x08
目标外设 SPI1(发送) = 0x05
即:

DMA_P2P_CR1 = (0x08 << 4) | 0x05;   // = 0x85
下面的部分没看懂:

AI8051U 的 P2P 注意事项(手册特别强调):
QSPI 到其他外设的 P2P 方式会影响 XRAM 数据,必须将 QSPI 的 XRAM 地址设到 32K 的后半段,且地址+数据长度不能超过 32K 范围。详见手册 "P2P使用注意事项"。



估计是写QSPI 的时候,QSPI 的 XRAM 地址设到 32K 的后半段,具体不会做........

反正是SPI_DMA初始化,以及 QSPI_DMA 的初始化,二者通过 P2P 桥接起来,不把这个“QSPI 的 XRAM 地址设到 32K 的后半段,具体不会做........”搞懂,估计是浏览不了图片d.............



截图202606101307495720.jpg

项目.zip

1.23 MB, 下载次数: 7

回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:202
  • 最近打卡:2026-07-04 17:28:31
已绑定手机

25

主题

2662

回帖

3411

积分

论坛元老

积分
3411
发表于 2026-6-10 13:19:50 | 显示全部楼层
汇报一下接口:
W25Q128  :QSPI_SwitchP4nP5n();                //选择QSPI数据口: NCS(P4.0), IO0(P4.1), IO1(P4.2), IO2(P5.2), IO3(P5.3), CLK(P4.3)

tFT_stILI7789 240*240 :

// ==================== 用户配置区液晶屏接线说明 ====================

sbit LCD_SCK_PIN = P3^2;  // 时钟线,接模块CLK引脚,接裸屏Pin9_SCL
sbit LCD_SDA_PIN = P3^3;  // 数据线 (MOSI),接模块DIN/MOSI引脚,接裸屏Pin8_SDA
sbit LCD_DC_PIN  = P1^1;  // 数据/命令选择 (DC),接模块D/C引脚,接裸屏Pin7_A0
sbit LCD_CS_PIN  = P3^5;  // 片选 (CS),接模块CE引脚,接裸屏Pin12_CS--SS
sbit LCD_RST_PIN = P4^7;  // 复位 (RST),接模块RST引脚,接裸屏Pin6_RES

KEY:
//键端口定义
sbit KEY1 = P2^4;
sbit KEY2 = P2^5;
sbit KEY3 = P2^6;
sbit KEY4 = P2^7;

LED :观察程序运行到何处
P20
P21
P22


其他什么示波器逻辑分析仪都没搞,试验箱没插针...........关键也不知道正常的波形是怎样的............
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:887
  • 最近打卡:2026-07-05 07:21:25

31

主题

428

回帖

4672

积分

荣誉版主

积分
4672
发表于 2026-6-11 10:40:10 | 显示全部楼层
wuzhe*** 发表于 2026-6-10 12:51
浦江老师:
您好!
   我尝试把您的程序移植到TFT st7789 240*240 的屏

这位同学好! 你发此信息已经收到。将抽空学习研究一下,再回复你。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:202
  • 最近打卡:2026-07-04 17:28:31
已绑定手机

25

主题

2662

回帖

3411

积分

论坛元老

积分
3411
发表于 2026-6-11 21:37:42 | 显示全部楼层
浦江*** 发表于 2026-6-11 10:40
这位同学好! 你发此信息已经收到。将抽空学习研究一下,再回复你。

感谢浦江老师,不着急,我也是纯粹玩,只是感觉这种情况的时序要求很高,十分不会控制,您在冲哥的QQ群里么?
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:202
  • 最近打卡:2026-07-04 17:28:31
已绑定手机

25

主题

2662

回帖

3411

积分

论坛元老

积分
3411
发表于 2026-6-13 11:07:00 | 显示全部楼层
浦江老师:您好!

  和您汇报一下,我把您的程序,改写到SPI 串口TFT ILIst7789 240*240 的屛上

实验环境还是咋们的AI8051U试验箱,现在有点进展,能够浏览图片和播放动画,菜单3,菜单4 也OK

但是也存在问题:

1 图片上有细小亮点,感觉是读取或者传输中有错

2 系统稳定性很差,例如功能1浏览图片,第一次执行本功能正常,退出后没有执行任何操作,接着再一次执行1浏览图片,有时候OK,有时候就黑屏死机,我怀疑就是和


图片上有不规则的细小亮点(感觉P2P过程读或者传有错) 有关


3 根因一:QSPI P2P 会破坏 XRAM 数据(官方已确认)
这是 Ai8051U 已知硬件局限性(摘自论坛帖,2025/7/8 官方回复):
"目前测试发现 Ai8051U QSPI 到其他外设的 P2P 方式 DMA 会影响 XRAM 的数据。必须将 QSPI 存储接收数据的 XRAM 起始地址设置到 32KXRAM 的后面部分。"
解释:P2P 名义上"不经过 XRAM",但硬件内部仍然有一块 DMA 缓冲区映射到 XRAM 空间。如果你没显式设置 DMA_QSPI_RXAH/RXAL,它的默认值是 0x8000(对应 XRAM 地址 0),那么从地址 0 开始、长度为 DMA_AMT_LEN 的一片 XRAM 都会被覆盖!

但是我查看了:ACTIVE MEMORY CLASSES OF MODULE:.\Objects\QSPI-TFT_DMA_P2P_ILI7789_UART1(Ai8051U键盘_动画成功)(TFT_7789)
BASE START END USED MEMORY CLASS
000000H 000000H 0007FFH 000545H EDATA
000000H 000000H 0007FFH HDATA
FF0000H FF0000H FFFFFFH 007021H CODE
000000H FF0000H FFFFFFH 002568H HCONST
000020H.0 000020H.0 00002FH.7 000002H.2 BIT
010000H 010000H 01FFFFH 000600H XDATA
FF0000H FF0000H FFFFFFH 000004H CONST
000000H 000000H 00007FH 000008H DATA

解读 .map 文件
关键的几行:
BASE        START       END        USED      MEMORY CLASS
==========================================================
000000H     000000H    0007FFH     000545H   EDATA       内部 2K RAM,用了 545H 字节
010000H     010000H    01FFFFH     000600H   XDATA       内部 32K XRAM,只用了 600H 字节
翻译成大白话:
EDATA0x0000~0x07FF2K 内部直接寻址 RAM):用了 545H = 1349 字节
XDATA(在 C251 中映射到 0x010000~0x01FFFF,即内部 32K XRAM):只用了 600H = 1536 字节
C251 XDATA 地址 0x010000~0x01FFFF,对应到内部 XRAM 的物理偏移就是 0x0000~0x7FFF32K)。
关键结论:你目前没有冲突
项目    地址范围
你的 XDATA 变量    0x010000 ~0x0105FF(物理偏移 0x0000~0x05FF
你设置的 DMA 缓冲区(RXAH=0x50               物理偏移 0x5000~0x7FFF(如果 DMA 长度 12K
两者不重叠!所以你现在的不规则亮点不是 DMA 缓冲区覆盖变量导致的。
我把现在的项目文件压缩打包传上来,请浦江老师指教:

项目.zip

1.23 MB, 下载次数: 6

回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-7-5 08:10 , Processed in 0.077426 second(s), 83 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表