|
发表于 2020-10-22 08:58:49
|
显示全部楼层
/*
* Erase Sector in Flash Memory
* Parameter: adr: Sector Address
* Return Value: 0 - OK, 1 - Failed
*/
int EraseSector (unsigned long adr)
{
W25QXX_Erase_Sector(adr - base_adr);
return (0); /* Finished without Errors */
}
//擦除一个扇区
//Dst_Addr:扇区地址 根据实际容量设置
//擦除一个扇区的最少时间:150ms
void W25QXX_Erase_Sector(u32 Dst_Addr)
{
//printf("fe:%x\r\n",Dst_Addr); //监视falsh擦除情况,测试用
//Dst_Addr*=4096;
W25QXX_Write_Enable(); //SET WEL
W25QXX_Wait_Busy();
QSPI_Send_CMD(W25X_SectorErase,Dst_Addr,(0<<6)|(3<<4)|(3<<2)|(3<<0),0);//QPI,写扇区擦除指令,地址为0,无数据_32位地址_4线传输地址_4线传输指令,无空周期,0个字节数据
W25QXX_Wait_Busy(); //等待擦除完成
}
u8 QSPI_Init(void)
{
u32 tempreg=0;
RCC->AHB1ENR|=1<<1; //使能PORTB时钟
RCC->AHB1ENR|=1<<5; //使能PORTF时钟
RCC->AHB3ENR|=1<<1; //QSPI时钟使能
GPIO_Set(GPIOB,1<<2,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PB2复用功能输出
GPIO_Set(GPIOB,1<<6,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PB6复用功能输出
GPIO_Set(GPIOF,0XF<<6,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PF6~9复用功能输出
GPIO_AF_Set(GPIOB,2,9); //PB2,AF9
GPIO_AF_Set(GPIOB,6,10); //PB6,AF10
GPIO_AF_Set(GPIOF,6,9); //PF6,AF9
GPIO_AF_Set(GPIOF,7,9); //PF7,AF9
GPIO_AF_Set(GPIOF,8,10); //PF8,AF10
GPIO_AF_Set(GPIOF,9,10); //PF9,AF10
RCC->AHB3RSTR|=1<<1; //复位QSPI
RCC->AHB3RSTR&=~(1<<1); //停止复位QSPI
if(QSPI_Wait_Flag(1<<5,0,0XFFFF)==0)//等待BUSY空闲
{
tempreg=(3-1)<<24; //设置QSPI时钟为AHB时钟的1/3,即216M/3=72Mhz,13.8ns
tempreg|=(4-1)<<8; //设置FIFO阈值为4个字节(最大为31,表示32个字节)
tempreg|=0<<7; //选择FLASH1
tempreg|=0<<6; //禁止双闪存模式
tempreg|=1<<4; //采样移位半个周期(DDR模式下,必须设置为0)
QUADSPI->CR=tempreg; //设置CR寄存器
tempreg=(25-1)<<16; //设置FLASH大小为2^25=32MB
tempreg|=(4-1)<<8; //片选高电平时间为4个时钟(13.8*4=55.2ns),即手册里面的tSHSL参数
tempreg|=1<<0; //Mode3,空闲时CLK为高电平
QUADSPI->DCR=tempreg; //设置DCR寄存器
QUADSPI->CR|=1<<0; //使能QSPI
}else return 1;
return 0;
}
我用的STM32F769,使用的方式是这样的
|
|