找回密码
 立即注册
查看: 175|回复: 13

AICube 生成的系统,SPI初始化中不能直接位操作?

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

25

主题

2662

回帖

3411

积分

论坛元老

积分
3411
发表于 2026-6-20 18:52:34 | 显示全部楼层 |阅读模式
请教AICube 设置问题:


我在原来的项目中,SPI的初始化是用AICube自动生成:



    SPI_SwitchP3n();                    //选择SPI数据口: SS(P3.5), MOSI(P3.4), MISO(P3.3), SCLK(P3.2)
    SPI_SwapMosiMiso();                 //交换MISO和MOSI功能脚

    SPI_MasterMode();                   //设置SPI为主机模式
    SPI_IgnoreSS();                     //忽略SS脚
    SPI_DataMSB();                      //设置SPI数据顺序为MSB (高位在前)
    SPI_SetMode3();                     //设置SPI工作模式3 (CPOL=1, CPHA=1)
    SPI_SetClockDivider4();             //设置SPI时钟分频

  
//   SPI_Enable();                       //使能SPI功能

    DMA_SPI_AutoSS();                   //使能SPI DMA自动控制SS
    DMA_SPI_SetAutoSSP35();             //DMA自动控制SS (P3.5)
    DMA_SPI_SetAmount(SPI_DMASIZE - 1); //设置SPI DMA发送/接收字节数
    DMA_SPI_SetTxAddress(pu8SPIDMATxBuffer); //设置SPI DMA发送缓冲区地址
    DMA_SPI_SetInterval(SPI_DMAITV);    //设置SPI DMA发送/接收字节间隔时间(系统时钟)
    DMA_SPI_ClearFIFO();                //清空SPI DMA FIFO缓冲区
    DMA_SPI_ClearFlag();                //清除SPI DMA中断标志
    DMA_SPI_EnableTx();                 //使能发送数据
    DMA_SPI_DisableRx();                //禁止接收数据
    DMA_SPI_SetBusPriority(0);          //设置总线访问为最低优先级
    DMA_SPI_SetIntPriority(0);          //设置中断为最低优先级
    DMA_SPI_EnableInt();                //使能SPI DMA中断
    DMA_SPI_Enable();                   //使能SPI DMA功能
//  DMA_SPI_MasterTrigger();            //触发SPI主机DMA

    //<<AICUBE_USER_SPI_INITIAL_BEGIN>>
    // 在此添加用户初始化代码
    HSSPI_CFG  = SS_HOLD | SS_SETUP;    // 根据实际需求调整SS_HLD和SS_SETUP值
    HSSPI_CFG2 = SPI_IOSW | HSSPIEN | FIFOEN | SS_DACT;
       
       
    DMA_SPI_ITVH = 0; //SPI DMA 传输间隔时间寄存器
    DMA_SPI_ITVL = 9; // 8--9加大间隔,牺牲一点速度换稳定性8
    //DMA_SPI_CFG = DMA_SPIIE | SPI_ACT_TX;       // 去掉SPI_ACT_RX,只发不收
        SPI_Enable();                       //使能SPI功能
       
        fSPIDMABusy = 0; // 清除DMA传输忙标志
    //<<AICUBE_USER_SPI_INITIAL_END>>


现在系统运行后有卡死现象,有大侠是用寄存器方法初始化,程序如下:

SPI_S1= 1; //00: P1.4 P1.5 P1.6 P1.7, 01: P2.4 P2.5 P2.6 P2.7, 10: P4.0 P4.1 P4.2 P4.3, 11: P3.5 P3.4 P3.3 P3.2
  SPI_S0= 1; //SPI显示屏接口选择 11: P3.5 P3.4 P3.3 P3.2
  
  SSIG = 1;  //1: 忽略SS脚,由MSTR位决定主机还是从机    0: SS脚用于决定主机还是从机。
  SPEN = 1;  //1: 允许SPI, 0:禁止SPI,所有SPI管脚均为普通IO
  DORD = 0;  //1:LSB先发, 0:MSB先发(高位在前)
  MSTR = 1;  //1:设为主机  0:设为从机
  CPOL = 1;  //1: 空闲时SCLK为高电平,0:空闲时SCLK为低电平
  CPHA = 1;  //1: 数据在SCLK前沿驱动,后沿采样. 0: 数据在SCLK前沿采样,后沿驱动.
  SPCTL = (SPCTL & ~3) | 3; //SPI 时钟频率选择,0:4T,1:8T,2:16T,3:2T
  HSCLKDIV   = 1;//HSCLKDIV主时钟分频
  SPI_CLKDIV = 1;//SPI_CLKDIV主时钟分频

如果我直接替换,编译就报错:

compiling uart.c...
compiling spi.c...
Sources\spi.c(41): error C100: '=': left operand must be l-value
Sources\spi.c(42): error C100: '=': left operand must be l-value
Sources\spi.c(43): error C100: '=': left operand must be l-value
Sources\spi.c(44): error C100: '=': left operand must be l-value
Sources\spi.c(45): error C100: '=': left operand must be l-value
Sources\spi.c(46): error C100: '=': left operand must be l-value
compiling qspi.c...
Target not created.

换成直接操作寄存器:


        SPCTL = 0xDF;        // SSIG=1, SPEN=1, DORD=0, MSTR=1, CPOL=1, CPHA=1, SPR1=1, SPR0=1
        HSCLKDIV = 1;        // 主时钟分频
        SPI_CLKDIV = 1;      // SPI时钟分频
       
        SPSTAT = 0xC0;  // 同时清除 SPIF 和 WCOL,干净利落


可以编译,但烧录后TFT直接黑屏,用原来AiCube生成的不会黑屏,是运行几次后卡死

有大侠知道为什么不能在AIcube 生成的系统中直接位操作,换成寄存器操作能过编译,但也是直接黑屏呢?

回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:393
  • 最近打卡:2026-07-04 17:13:30

83

主题

7888

回帖

1万

积分

超级版主

积分
16827
发表于 2026-6-20 22:15:51 | 显示全部楼层
什么型号的? 32位的可以位寻址。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:299
  • 最近打卡:2026-07-04 00:01:55
已绑定手机

66

主题

808

回帖

3037

积分

论坛元老

DIY玩家

积分
3037
发表于 2026-6-20 23:05:30 | 显示全部楼层
梁*** 发表于 2026-6-20 22:15
什么型号的? 32位的可以位寻址。

部分寄存器可位操作

点评

我是指寄存器地址非0或8结尾的,32位的可以位操作,8位的不能。  详情 回复 发表于 2026-6-21 15:07
永怀这学徒心
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:453
  • 最近打卡:2026-07-03 08:57:36

830

主题

1万

回帖

2万

积分

管理员

积分
23929
发表于 2026-6-21 12:21:19 | 显示全部楼层
截图202606211220008853.jpg
截图202606211220389979.jpg
截图202606211221157851.jpg



回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:393
  • 最近打卡:2026-07-04 17:13:30

83

主题

7888

回帖

1万

积分

超级版主

积分
16827
发表于 2026-6-21 15:07:03 | 显示全部楼层
狂热*** 发表于 2026-6-20 23:05
部分寄存器可位操作

我是指寄存器地址非0或8结尾的,32位的可以位操作,8位的不能。
回复

使用道具 举报 送花

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

25

主题

2662

回帖

3411

积分

论坛元老

积分
3411
发表于 2026-6-21 18:11:35 | 显示全部楼层

感谢!感谢!我慢慢研究一下!
回复

使用道具 举报 送花

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

25

主题

2662

回帖

3411

积分

论坛元老

积分
3411
发表于 2026-6-21 18:12:15 | 显示全部楼层
梁*** 发表于 2026-6-21 15:07
我是指寄存器地址非0或8结尾的,32位的可以位操作,8位的不能。

哦哦,我没有注意的这个差别!感谢感谢!
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:453
  • 最近打卡:2026-07-03 08:57:36

830

主题

1万

回帖

2万

积分

管理员

积分
23929
发表于 2026-6-21 19:57:09 | 显示全部楼层

截图202606211950362446.jpg

截图202606211950169431.jpg


截图202606211955407485.jpg

截图202606211956277860.jpg

截图202606211957061244.jpg
回复

使用道具 举报 送花

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

25

主题

2662

回帖

3411

积分

论坛元老

积分
3411
发表于 2026-6-22 17:32:28 | 显示全部楼层

对,感谢神农鼎大侠的指导!

      
     神农鼎大侠及STC的各位工程师,我现在使用了一段时间的AICube ,有点依赖了,这段时间在折腾TFT彩屏,主要是玩一下桥接:

用QSPI从W25q128 读出图片数据,P2P桥接后直接用SPI给TFT_ILIst7789 240*240

图片直接用冲哥的13张猫和老鼠的图片,然后把浦江一水老师的LCM桥接直接稍作修改,放到SPI桥接上

开始的架子是用AiCube搞的,现在是程序可以跑起来,但是不能精确控制,程序现在一离开主菜单,执行浏览图片后

再回到主菜单就跑飞啦!

  尝试在原来的基础上修改打磨,没什么进展,位操作编译也遇到报错.................

重新来,直接操作寄存器,就一切顺利,尝试把位操作换成操作寄存器,编译OK,但是系统直接黑屏...........

当然本身桥接对时序要求很高,精细控制的话,AICube 的使用上我只是照猫画虎,自然问题多多

我把整个系统都放上来,方便的时候看看怎样设置AiCube 才和顺畅运行的程序一一对应?

实验环境:ai8051U 试验箱+7789彩屏(8脚!240*240,不能买7脚的!不能买7脚的!不能买7脚的!会有屛闪+细小亮点问题无法解决)

2个文件中,“项目“是遇到问题的使用AiCube 的,是用串口来操作 Flash 另外一个是浦江一水老师直接操作寄存器的,用来作为标准,要

修改的是“项目“,主要目的是学习如何在AiCube中精密控制寄存器和进行位操作 如何解决位操作编译时候的报错?这些问题目前在大学教

材中是没有答案的,本身这样的桥接技术也是这2年才铺开,所以吸引了我来折腾(TFT的屛也买了5块),也专门打了PCB,无论是LCM环境

(STC32G144K246)和SPI屛实验环境在2种具有桥接功能的芯片(Ai8051U有试验箱,STC32G144K246要自己搞PCB)都搞好了,可以慢慢

透彻的研究,因为AiCube 是解放生产力的好工具,可以大幅降低使用难度,值得好好研究通它的使用方法...........

在职到时候忙,现在有时间可以好好看看怎样设置才是最好的,普中的板子我也操作了一遍,感觉只是入门级别,还不够,但是目前也没有渠道

能找到更多的AiCube相关资料,感觉用这个实验,可以说明STC的2个32位芯片强大的功能和软件AiCube 的方便,本来这是高职院校实验师晋升

高级实验师的绝好论文项目,我自己因为已经退休意义不大,不过先把“项目”调顺畅,打磨好,一定有用到的时候............




QSPI-TFT_DMA_P2P_ST7798_CDC.rar

1.18 MB, 下载次数: 8

项目.zip

2.24 MB, 下载次数: 9

回复

使用道具 举报 送花

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

25

主题

2662

回帖

3411

积分

论坛元老

积分
3411
发表于 2026-6-22 17:52:56 | 显示全部楼层
我们自动生成的SPI初始化:



  1. void SPI_Init(void)
  2. {
  3.         
  4.         SPI_SwitchP3n();                    //选择SPI数据口: SS(P3.5), MOSI(P3.4), MISO(P3.3), SCLK(P3.2)
  5.     SPI_SwapMosiMiso();                 //交换MISO和MOSI功能脚
  6.     SPI_MasterMode();                   //设置SPI为主机模式
  7.     SPI_IgnoreSS();                     //忽略SS脚
  8.     SPI_DataMSB();                      //设置SPI数据顺序为MSB (高位在前)
  9.     SPI_SetMode3();                     //设置SPI工作模式3 (CPOL=1, CPHA=1)
  10.     SPI_SetClockDivider4();             //设置SPI时钟分频
  11.   
  12. //   SPI_Enable();                       //使能SPI功能
  13.     DMA_SPI_AutoSS();                   //使能SPI DMA自动控制SS
  14.     DMA_SPI_SetAutoSSP35();             //DMA自动控制SS (P3.5)
  15.     DMA_SPI_SetAmount(SPI_DMASIZE - 1); //设置SPI DMA发送/接收字节数
  16.     DMA_SPI_SetTxAddress(pu8SPIDMATxBuffer); //设置SPI DMA发送缓冲区地址
  17.     DMA_SPI_SetInterval(SPI_DMAITV);    //设置SPI DMA发送/接收字节间隔时间(系统时钟)
  18.     DMA_SPI_ClearFIFO();                //清空SPI DMA FIFO缓冲区
  19.     DMA_SPI_ClearFlag();                //清除SPI DMA中断标志
  20.     DMA_SPI_EnableTx();                 //使能发送数据
  21.     DMA_SPI_DisableRx();                //禁止接收数据
  22.     DMA_SPI_SetBusPriority(0);          //设置总线访问为最低优先级
  23.     DMA_SPI_SetIntPriority(0);          //设置中断为最低优先级
  24.     DMA_SPI_EnableInt();                //使能SPI DMA中断
  25.     DMA_SPI_Enable();                   //使能SPI DMA功能
  26. //  DMA_SPI_MasterTrigger();            //触发SPI主机DMA
  27.     //<<AICUBE_USER_SPI_INITIAL_BEGIN>>
  28.     // 在此添加用户初始化代码
  29.     HSSPI_CFG  = SS_HOLD | SS_SETUP;    // 根据实际需求调整SS_HLD和SS_SETUP值
  30.     HSSPI_CFG2 = SPI_IOSW | HSSPIEN | FIFOEN | SS_DACT;
  31.         
  32.         
  33.     DMA_SPI_ITVH = 0; //SPI DMA 传输间隔时间寄存器
  34.     DMA_SPI_ITVL = 9; // 8--9加大间隔,牺牲一点速度换稳定性8
  35.     //DMA_SPI_CFG = DMA_SPIIE | SPI_ACT_TX;       // 去掉SPI_ACT_RX,只发不收
  36.         SPI_Enable();                       //使能SPI功能
  37.         
  38.         fSPIDMABusy = 0; // 清除DMA传输忙标志
  39.     //<<AICUBE_USER_SPI_INITIAL_END>>
  40.         
  41. }
复制代码

和浦江一水老师的这段:
  1. void  SPI_Init(void)
  2. {
  3.   SPI_S1= 1; //00: P1.4 P1.5 P1.6 P1.7, 01: P2.4 P2.5 P2.6 P2.7, 10: P4.0 P4.1 P4.2 P4.3, 11: P3.5 P3.4 P3.3 P3.2
  4.   SPI_S0= 1; //SPI显示屏接口选择 11: P3.5 P3.4 P3.3 P3.2
  5.   SSIG = 1;  //1: 忽略SS脚,由MSTR位决定主机还是从机    0: SS脚用于决定主机还是从机。
  6.   SPEN = 1;  //1: 允许SPI, 0:禁止SPI,所有SPI管脚均为普通IO
  7.   DORD = 0;  //1:LSB先发, 0:MSB先发(高位在前)
  8.   MSTR = 1;  //1:设为主机  0:设为从机
  9.   CPOL = 1;  //1: 空闲时SCLK为高电平,0:空闲时SCLK为低电平
  10.   CPHA = 1;  //1: 数据在SCLK前沿驱动,后沿采样. 0: 数据在SCLK前沿采样,后沿驱动.
  11.   SPCTL = (SPCTL & ~3) | 3; //SPI 时钟频率选择,0:4T,1:8T,2:16T,3:2T
  12.   HSCLKDIV   = 1;//HSCLKDIV主时钟分频
  13.   SPI_CLKDIV = 1;//SPI_CLKDIV主时钟分频
  14.   //高速I/O时钟(HSIOCK)经 HSCLKDIV 分频->高速外设时钟(HSCLK)->经 SPI_CLKDIV分频->SPI实际工作时钟(SPI_CLK)
  15.   //SPSTAT = 0xC1; //状态寄存器清0 SPIF和WCOL标志(写1)
  16.   SPIF = 1;      //清SPIF标志(设置SPI传输完成标志)
  17.   WCOL = 1;      //清WCOL标志(是 SPI 写冲突标志清零)
  18.   HSSPI_CFG2 = 0x40; //(HSSPI_CFG2^6=1) 交换MOSI MISO, P3.3是MOSI
  19.   P3M1 &= ~0x0C;   //P3.3(MOSI) P3.2(SCLK)设置成推挽输出
  20.   P3M0 |=  0x0C;
  21.   P3SR &= ~0x0C;   //P3.3(MOSI) P3.2(SCLK)设置成高速模式
  22.   P3PU |=  0x30;   //SPI接口使能上拉电阻
  23.   P1PU |=  0x02;   //P11接口使能上拉电阻
  24.   P4PU |=  0x80;   //P47接口使能上拉电阻
  25.   HSSPI_CFG = 0;   //禁止高速(QSPI_DMA不需要高速)
  26.   //P_SW1 = (P_SW1 & ~0x0C) | ((SPI_IO<<2) & 0x0C);  //切换IO
  27.   DMA_SPI_ITVH = 0;  //间隔为0,DMA_SPI_ITVH 和 DMA_SPI_ITVL 是 AI8051U 中专门
  28.   DMA_SPI_ITVL = 0;  //用于控制 SPI DMA 数据包之间间隔时间的寄存器
  29. }
复制代码
基本对应,但是在AICube中不能直接位操作,编译报错,改成对寄存器操作(其实是一样的)


SPCTL = 0xDF;        // SSIG=1, SPEN=1, DORD=0, MSTR=1, CPOL=1, CPHA=1, SPR1=1, SPR0=1
        HSCLKDIV = 1;        // 主时钟分频
        SPI_CLKDIV = 1;      // SPI时钟分频
      
        SPSTAT = 0xC0;  // 同时清除 SPIF 和 WCOL,干净利落


可以通过编译,但烧录后TFT直接黑屏,不知道哪里有冲突,而用原来AiCube生成的不会黑屏,是运行几次后卡死

其实这2句是没必要的:

HSSPI_CFG  = SS_HOLD | SS_SETUP;    // 根据实际需求调整SS_HLD和SS_SETUP值
HSSPI_CFG2 = SPI_IOSW | HSSPIEN | FIFOEN | SS_DACT;

因为我们没有用到高速SPI ,但是我删除后也是黑屏 ,我把实验现象也放上来:




实验现象.mp4

113.86 MB, 下载次数: 7

回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-7-5 07:47 , Processed in 0.086216 second(s), 88 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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