AICube 生成的系统,SPI初始化中不能直接位操作?
请教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 生成的系统中直接位操作,换成寄存器操作能过编译,但也是直接黑屏呢?
什么型号的? 32位的可以位寻址。 梁工 发表于 2026-6-20 22:15
什么型号的? 32位的可以位寻址。
部分寄存器可位操作
狂热主宰 发表于 2026-6-20 23:05
部分寄存器可位操作
我是指寄存器地址非0或8结尾的,32位的可以位操作,8位的不能。 神农鼎 发表于 2026-6-21 12:21
感谢!感谢!我慢慢研究一下! 梁工 发表于 2026-6-21 15:07
我是指寄存器地址非0或8结尾的,32位的可以位操作,8位的不能。
哦哦,我没有注意的这个差别!感谢感谢!
神农鼎 发表于 2026-6-21 19:57
对,感谢神农鼎大侠的指导!
神农鼎大侠及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 的方便,本来这是高职院校实验师晋升
高级实验师的绝好论文项目,我自己因为已经退休意义不大,不过先把“项目”调顺畅,打磨好,一定有用到的时候............
我们自动生成的SPI初始化:
void SPI_Init(void)
{
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>>
}
和浦江一水老师的这段:
voidSPI_Init(void)
{
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主时钟分频
//高速I/O时钟(HSIOCK)经 HSCLKDIV 分频->高速外设时钟(HSCLK)->经 SPI_CLKDIV分频->SPI实际工作时钟(SPI_CLK)
//SPSTAT = 0xC1; //状态寄存器清0 SPIF和WCOL标志(写1)
SPIF = 1; //清SPIF标志(设置SPI传输完成标志)
WCOL = 1; //清WCOL标志(是 SPI 写冲突标志清零)
HSSPI_CFG2 = 0x40; //(HSSPI_CFG2^6=1) 交换MOSI MISO, P3.3是MOSI
P3M1 &= ~0x0C; //P3.3(MOSI) P3.2(SCLK)设置成推挽输出
P3M0 |=0x0C;
P3SR &= ~0x0C; //P3.3(MOSI) P3.2(SCLK)设置成高速模式
P3PU |=0x30; //SPI接口使能上拉电阻
P1PU |=0x02; //P11接口使能上拉电阻
P4PU |=0x80; //P47接口使能上拉电阻
HSSPI_CFG = 0; //禁止高速(QSPI_DMA不需要高速)
//P_SW1 = (P_SW1 & ~0x0C) | ((SPI_IO<<2) & 0x0C);//切换IO
DMA_SPI_ITVH = 0;//间隔为0,DMA_SPI_ITVH 和 DMA_SPI_ITVL 是 AI8051U 中专门
DMA_SPI_ITVL = 0;//用于控制 SPI DMA 数据包之间间隔时间的寄存器
}
基本对应,但是在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 ,但是我删除后也是黑屏 ,我把实验现象也放上来:
页:
[1]
2