我们自动生成的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>>
}
复制代码
和浦江一水老师的这段:
void SPI_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 ,但是我删除后也是黑屏 ,我把实验现象也放上来:
Your browser does not support video tags.