|
楼主 |
发表于 2022-5-4 09:45:26
|
显示全部楼层
本帖最后由 WUJIANLING 于 2022-5-4 09:46 编辑
这个地方不会填,我愿意是要发指令,指定无指令、无地址、无交叉、无空周期,只传输数据,麻烦看一下
QSPI_Send_CMD(0,NULL,0XF0,4);//????????
void QSPI_Send_CMD(u8 cmd,u32 addr,u8 mode,u8 dmcycle)
{
u32 tempreg=0;
u8 status;
if(QSPI_Wait_Flag(1<<5,0,0XFFFF)==0) //等待BUSY空闲
{
tempreg=0<<31; //禁止DDR模式
tempreg|=0<<28; //每次都发送指令
tempreg|=0<<26; //间接写模式
tempreg|=((u32)mode>>6)<<24; //设置数据模式
tempreg|=(u32)dmcycle<<18; //设置空指令周期数
tempreg|=((u32)(mode>>4)&0X03)<<12; //设置地址长度
tempreg|=((u32)(mode>>2)&0X03)<<10; //设置地址模式
tempreg|=((u32)(mode>>0)&0X03)<<8; //设置指令模式
tempreg|=cmd; //设置指令
QUADSPI->CCR=tempreg; //设置CCR寄存器
if(mode&0X0C) //有指令+地址要发送
{
QUADSPI->AR=addr; //设置地址寄存器
}
if((mode&0XC0)==0) //无数据传输,等待指令发送完成
{
status=QSPI_Wait_Flag(1<<1,1,0XFFFF);//等待TCF,即传输完成
if(status==0)
{
QUADSPI->FCR|=1<<1; //清除TCF标志位
}
}
}
}
//QSPI发送指定长度的数据
//buf:发送数据缓冲区首地址
//datalen:要传输的数据长度
//返回值:0,正常
//其他,错误代码
u8 QSPI_Transmit(u8* buf,u32 datalen)
{
u32 tempreg=QUADSPI->CCR;
u32 addrreg=QUADSPI->AR;
u8 status;
vu32 *data_reg=&QUADSPI->DR;
QUADSPI->DLR=datalen-1; //设置数据传输长度
tempreg&=~(3<<26); //清除FMODE原来的设置
tempreg|=0<<26; //设置FMODE为间接写入模式
QUADSPI->FCR|=1<<1; //清除TCF标志位
QUADSPI->CCR=tempreg; //回写CCR寄存器
while(datalen)
{
status=QSPI_Wait_Flag(1<<2,1,0XFFFF);//等到FTF
if(status!=0) //等待成功
{
break;
}
*(vu8 *)data_reg=*buf++;
datalen--;
}
if(status==0)
{
QUADSPI->CR|=1<<2; //终止传输
status=QSPI_Wait_Flag(1<<1,1,0XFFFF); //等待TCF,即数据传输完成
if(status==0)
{
QUADSPI->FCR|=1<<1; //清除TCF标志位
status=QSPI_Wait_Flag(1<<5,0,0XFFFF); //等待BUSY位清零
}
}
return status;
}
//初始化 QSPI 接口
//返回值:0,成功; 1,失败;
u8 QSPI_Init(void)
{
u32 tempreg=0;
RCC->AHB4ENR|=0B11111; //使能PORTABCDE时钟
RCC->AHB3ENR|=1<<14; //QSPI时钟使能
GPIO_Set(GPIOA,1<<1, GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU); //PA1复用功能输出 BK1-IO3
GPIO_Set(GPIOB,1<<2, GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU); //PB2复用功能输出 CLK
GPIO_Set(GPIOB,1<<10, GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU); //PB10复用功能输出 BK1-NCS
GPIO_Set(GPIOC,1<<10, GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU); //PC10复用功能输出 BK1-IO1
GPIO_Set(GPIOD,1<<11, GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU); //PD11复用功能输出 BK1-IO0
GPIO_Set(GPIOE,1<<2, GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU); //PE2 复用功能输出 BK1-IO2
GPIO_Set(GPIOE,0XF<<7,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU); //PE7~10复用功能输出 BK2-IO0-IO3
GPIO_AF_Set(GPIOA,1,9); //PA1,AF9
GPIO_AF_Set(GPIOB,2,9); //PB2,AF9
GPIO_AF_Set(GPIOB,10,9); //PB10,AF9
GPIO_AF_Set(GPIOC,10,9); //PC10,AF9
GPIO_AF_Set(GPIOD,11,9); //PD10,AF9
GPIO_AF_Set(GPIOE,2,9); //PE2,AF9
GPIO_AF_Set(GPIOE,7,10); //PE7,AF10
GPIO_AF_Set(GPIOE,8,10); //PE8,AF10
GPIO_AF_Set(GPIOE,9,10); //PE9,AF10
GPIO_AF_Set(GPIOE,10,10); //PE10,AF10
RCC->AHB3RSTR|=1<<14; //复位QSPI
RCC->AHB3RSTR&=~(1<<14); //停止复位QSPI
if(QSPI_Wait_Flag(1<<5,0,0XFFFF)==0)//等待BUSY空闲
{
//QSPI时钟默认来自rcc_hclk3(由RCC_D1CCIPR的QSPISEL[1:0]选择)
tempreg=(2-1)<<24; //设置QSPI时钟为AHB时钟的1/2,即200M/2=100Mhz,10ns
tempreg|=(4-1)<<8; //设置FIFO阈值为4个字节(最大为31,表示32个字节)
tempreg|=0<<7; //选择FLASH1
tempreg|=1<<6; //双闪存模式
tempreg|=1<<4; //采样移位半个周期(DDR模式下,必须设置为0)
QUADSPI->CR=tempreg; //设置CR寄存器
tempreg=(8-1)<<16; //设置FLASH大小为2^8=256
tempreg|=(5-1)<<8; //片选高电平时间为5个时钟(10*5=50ns),即手册里面的tSHSL参数
tempreg|=1<<0; //Mode3,空闲时CLK为高电平
QUADSPI->DCR=tempreg; //设置DCR寄存器
QUADSPI->CR|=1<<0; //使能QSPI
}
else return 1;
return 0;
}
int main(void)
{
.....
QSPI_Init();
GPIO_Set(GPIOD,PIN3|PIN4|PIN5|PIN6|PIN7|PIN8|PIN9,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_LOW,GPIO_PUPD_PU);//PD3-PD7 行信号 PD8为LAT PD9-OE
QSPI_Send_CMD(0,NULL,0XF0,4);//????????
while(1)
{
for(int DisplayRowNumber=0;DisplayRowNumber<16;DisplayRowNumber++) //16扫
{
OE_SETH; //息屏
DispLine(DisplayRowNumber);
QSPI_Transmit(DisplayArea+DisplayRowNumber*256,256);//送一行数据
LAT_SETL; //低电平锁存
LAT_SETH; //高电平并出
OE_SETL; //亮屏
delay_us(20);
}
}
} |
|