stm32 W25Q64.docx
- 文档编号:8557441
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:11
- 大小:18.05KB
stm32 W25Q64.docx
《stm32 W25Q64.docx》由会员分享,可在线阅读,更多相关《stm32 W25Q64.docx(11页珍藏版)》请在冰豆网上搜索。
stm32W25Q64
.C文件
#include"flash.h"
#include"spi.h"
#include"delay.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK战舰STM32开发板
//W25Q64代码
//正点原子@ALIENTEK
//技术论坛:
//修改日期
//版本:
V1.0
//版权所有,XX。
//Copyright(C)广州市星翼电子科技有限公司2009-2019
//Allrightsreserved
//flash写入只能把1写成0,所以写入前应该先擦除
//////////////////////////////////////////////////////////////////////////////////
u16SPI_FLASH_TYPE=W25Q64;//默认就是25Q64
//W25Q64一共8M容量
//分为128个快,每块大小为64K字节
//每块又可以分为16个扇区,每个扇区4K字节
//每次擦除最少一个扇区,也就是4K字节
//25Q64一共有2048个扇区
//初始化SPIFLASH的IO口
voidSPI_Flash_Init(void){GPIO_InitTypeDefGPIO_InitStructure;
RCC_APB2PeriphClockCmd(
RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOG,
ENABLE);//PORTB时钟使能
//W25Q64的片选
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;//PB12推挽
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_12);}//读取SPI_FLASH的状态寄存器
//BIT
//SPRRVTBBP2BP1BP0WELBUSY
//SPR:
默认0,状态寄存器保护位,配合WP使用
//TB,BP2,BP1,BP0:
FLASH区域写保护设置
//WEL:
写使能锁定
//BUSY:
忙标记位(1,忙;0,空闲)
//默认:
0x00
u8SPI_Flash_ReadSR(void){u8byte=0;}//写SPI_FLASH状态寄存器
//只有SPR,TB,BP2,BP1,BP0(bit7,5,4,3,2)可以写!
!
!
voidSPI_FLASH_Write_SR(u8sr){SPI_FLASH_CS=0;//使能器件
}SPI2_ReadWriteByte(W25X_WriteStatusReg);//发送写取状态寄存器命令
SPI2_ReadWriteByte(sr);//写入一个字节
SPI_FLASH_CS=1;//取消片选
SPI_FLASH_CS=0;//使能器件
SPI2_ReadWriteByte(W25X_ReadStatusReg);//发送读取状态寄存器命令
byte=SPI2_ReadWriteByte(0Xff);//读取一个字节
SPI_FLASH_CS=1;//取消片选
returnbyte;
SPI2_Init();//初始化SPI
SPI2_SetSpeed(SPI_BaudRatePrescaler_2);//设置为18M时钟,高速模式
SPI_FLASH_TYPE=SPI_Flash_ReadID();//读取FLASHI
D.
//SD卡片选信号
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;//PD2推挽
GPIO_Init(GPIOD,&GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
//
2.4G无线片选信号
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;//PG7推挽
GPIO_Init(GPIOG,&GPIO_InitStructure);
GPIO_SetBits(GPIOG,GPIO_Pin_7);
//SPI_FLASH写使能
//将WEL置位
voidSPI_FLASH_Write_Enable(void){SPI_FLASH_CS=0;//使能器件
SPI2_ReadWriteByte(W25X_WriteEnable);//发送写使能
SPI_FLASH_CS=1;//取消片选}//SPI_FLASH写禁止
//将WEL清零
voidSPI_FLASH_Write_Disable(void){SPI_FLASH_CS=0;//使能器件
SPI2_ReadWriteByte(W25X_WriteDisable);//发送写禁止指令
SPI_FLASH_CS=1;//取消片选}//读取芯片IDW25X16的ID:
0XEF14
u16SPI_Flash_ReadID(void){u16Temp=0;
SPI_FLASH_CS=0;
SPI2_ReadWriteByte(0x90);//发送读取ID命令
SPI2_ReadWriteByte(0x00);
SPI2_ReadWriteByte(0x00);
SPI2_ReadWriteByte(0x00);
Temp|=SPI2_ReadWriteByte(0xFF)<<8;
Temp|=SPI2_ReadWriteByte(0xFF);
SPI_FLASH_CS=1;
returnTemp;}//读取SPIFLASH
//在指定地址开始读取指定xx的数据
//pBuffer:
数据存储区
//ReadAddr:
开始读取的地址(24bit)
//NumByteToRead:
要读取的字节数(最大65535)
//2^10=10241K=1024字节
//8M最大能读到2^23也就是24位
voidSPI_Flash_Read(u8*pBuffer,u32ReadAddr,u16NumByteToRead){u16i;
SPI_FLASH_CS=0;//使能器件
SPI2_ReadWriteByte(W25X_ReadData);//发送读取命令
SPI2_ReadWriteByte((u8)((ReadAddr)>>16));//发送24bit地址
SPI2_ReadWriteByte((u8)((ReadAddr)>>8));
SPI2_ReadWriteByte((u8)ReadAddr);
for(i=0;i //在指定地址开始写入最大256字节的数据 //pBuffer: 数据存储区 //WriteAddr: 开始写入的地址(24bit) //NumByteToWrite: 要写入的字节数(最大256),该数不应该超过该页的剩余字节数! ! ! voidSPI_Flash_Write_Page(u8*pBuffer,u32WriteAddr,u16NumByteToWrite){u16i; SPI_FLASH_Write_Enable();//SETWEL SPI_FLASH_CS=0;//使能器件 SPI2_ReadWriteByte(W25X_PageProgram);//发送写页命令 SPI2_ReadWriteByte((u8)((WriteAddr)>>16));//发送24bit地址 SPI2_ReadWriteByte((u8)((WriteAddr)>>8)); SPI2_ReadWriteByte((u8)WriteAddr); for(i=0;i SPI2_ReadWriteByte(pBuffer[i]);//循环写数 }SPI_FLASH_CS=1;//取消片选 SPI_Flash_Wait_Busy();//等待写入结束 //无检验写SPIFLASH //必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败! //具有自动换页功能 //在指定地址开始写入指定长度的数据,但是要确保地址不越界! //pBuffer: 数据存储区 //WriteAddr: 开始写入的地址(24bit) //NumByteToWrite: 要写入的字节数(最大65535) //每页256个字节 voidSPI_Flash_Write_NoCheck(u8*pBuffer,u32WriteAddr,u16NumByteToWrite){u16YeSengYu; YeSengYu=256-WriteAddr%256;//单页剩余的字节数 if(NumByteToWrite<=YeSengYu) YeSengYu=NumByteToWrite;//不大于256个字节 while (1){SPI_Flash_Write_Page(pBuffer,WriteAddr,YeSengYu); if(NumByteToWrite==YeSengYu) break;//写入结束了 else//NumByteToWrite>YeSengYu{}pBuffer+=YeSengYu; WriteAddr+=YeSengYu; NumByteToWrite-=YeSengYu; if(NumByteToWrite>256) YeSengYu=256;//一次可以写入256个字节 else YeSengYu=NumByteToWrite;//不够256个字节了 //减去已经写入了的字节数}}//写SPIFLASH //在指定地址开始写入指定xx的数据 //该函数带擦除操作! //pBuffer: 数据存储区 //WriteAddr: 开始写入的地址(24bit) //NumByteToWrite: 要写入的字节数(最大65535) u8SPI_FLASH_BUF[4096]; voidSPI_Flash_Write(u8*pBuffer,u32WriteAddr,u16NumByteToWrite){u32secpos; u16secoff; u16secremain; u16i; secpos=WriteAddr/4096;//扇区地址0~2047forw25x64 secoff=WriteAddr%4096;//在扇区内的偏移 secremain=4096-secoff;//扇区剩余空间大小 if(NumByteToWrite<=secremain) secremain=NumByteToWrite;//不大于4096个字节 while (1){SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);//读出整个扇区的内容for(i=0;i =0XFF) break;//需要擦除}if(i for(i=0;i SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);//写入整个扇区SPI_FLASH_BUF[i+secoff]=pBuffer[i];}else SPI_Flash_Write_NoCheck(pBuffer,WriteAddr,secremain);//写已经擦除了的,直接写入扇区剩余区间. if(NumByteToWrite==secremain) break;//写入结束了 else//写入未结束{secpos++;//扇区地址增1 secoff=0;//偏移位置为0 pBuffer+=secremain;//指针偏移 WriteAddr+=secremain;//写地址偏移 NumByteToWrite-=secremain;//字节数递减 }if(NumByteToWrite>4096) secremain=4096;//下一个扇区还是写不完 else secremain=NumByteToWrite;//下一个扇区可以写完了 }} //擦除整个芯片 //整片擦除时间: //W25X16: 25s //W25X32: 40s //W25X64: 40s //等待时间超长... voidSPI_Flash_Erase_Chip(void){SPI_FLASH_Write_Enable();//SETWEL SPI_Flash_Wait_Busy(); SPI_FLASH_CS=0;//使能器件 SPI2_ReadWriteByte(W25X_ChipErase);//发送片擦除命令 SPI_FLASH_CS=1;//取消片选 SPI_Flash_Wait_Busy();//等待芯片擦除结束}//擦除一个扇区 //Dst_Addr: 扇区地址0~511forw25x16 //Dst_Addr: 扇区地址0~2047forw25x64 //擦除一个xx的最少时间: 150ms voidSPI_Flash_Erase_Sector(u32Dst_Addr){Dst_Addr*=4096; SPI_FLASH_Write_Enable();//SETWEL SPI_Flash_Wait_Busy(); SPI_FLASH_CS=0;//使能器件 SPI2_ReadWriteByte(W25X_SectorErase);//发送扇区擦除指令 SPI2_ReadWriteByte((u8)((Dst_Addr)>>16));//发送24bit地址 SPI2_ReadWriteByte((u8)((Dst_Addr)>>8)); SPI2_ReadWriteByte((u8)Dst_Addr); SPI_FLASH_CS=1;//取消片选 SPI_Flash_Wait_Busy();}//等待空闲//等待擦除完成 voidSPI_Flash_Wait_Busy(void){}while((SPI_Flash_ReadSR()&0x01)==0x01);//等待BUSY位清空 //进入掉电模式 voidSPI_Flash_PowerDown(void){SPI_FLASH_CS=0;//使能器件 SPI2_ReadWriteByte(W25X_PowerDown);//发送掉电命令 SPI_FLASH_CS=1;//取消片选 delay_us (3);}//唤醒 voidSPI_Flash_WAKEUP(void){SPI_FLASH_CS=0;//使能器件 SPI_FLASH_CS=1;//取消片选 //等待TRES1 delay_us (3);}.H文件 #ifndef__FLASH_H #define__FLASH_H #include"sys.h" ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK战舰STM32开发板 //W25Q64代码 //正点原子@ALIENTEK //技术论坛: //修改日期 //版本: V1.0 //版权所有,XX。 //Copyright(C)广州市星翼电子科技有限公司2009-2019 //Allrightsreserved ////////////////////////////////////////////////////////////////////////////////// //W25X系列/Q系列芯片列表 //W25Q80ID0XEF13 //W25Q16ID0XEF14 //W25Q32ID0XEF15 //W25Q32ID0XEF16 #defineW25Q800XEF13 #defineW25Q160XEF14 #defineW25Q320XEF15 #defineW25Q640XEF16 externu16SPI_FLASH_TYPE;//定义我们使用的flash芯片型号 #defineSPI_FLASH_CSPBout (12)//选中FLASH //////////////////////////////////////////////////////////////////////////// //指令表 #defineW25X_WriteEnable #defineW25X_WriteDisable #defineW25X_ReadStatusReg #defineW25X_WriteStatusReg #defineW25X_ReadData #defineW25X_FastReadData #defineW25X_FastReadDual #defineW25X_PageProgram #defineW25X_BlockErase #defineW25X_SectorErase #defineW25X_ChipErase0x06 0x04 0x05 0x01 0x0B//写使能 //写失能 //读状态寄存器 //写状态寄存器 0x03 ////读数据 0x3B 0x02 0xD8 0x20 0xC7 0xB9 0xAB 0xAB #defineW25X_PowerDown #defineW25X_ReleasePowerDown//掉电 //唤醒 #defineW25X_DeviceID #defineW25X_ManufactDeviceID0x90 #defineW25X_JedecDeviceID voidSPI_Flash_Init(void);0x9F u16SPI_Flash_ReadID(void);//读取FLASHID u8SPI_Flash_ReadSR(void);//读取状态寄存器 voidSPI_FLASH_Write_SR(u8sr);//写状态寄存器 voidSPI_FLASH_Write_Enable(void);//写使能 voidSPI_FLASH_Write_Disable(void);//写保护 voidSPI_Flash_Write_NoCheck(u8*pBuffer,u32WriteAddr,u16NumByteToWrite); voidSPI_Flash_Read(u8*pBuffer,u32ReadAddr,u16NumByteToRead);//读取flashvoidSPI_Flash_Write(u8*pBuffer,u32WriteAddr,u16NumByteToWrite);//写入flash voidSPI_Flash_Erase_Chip(void);//整片擦除 voidSPI_Flash_Erase_Sector(u32Dst_Addr);//扇区擦除 voidSPI_Flash_Wait_Busy(void);//等待空闲 voidSPI_Flash_PowerDown(void);//进入掉电模式 voidSPI_Flash_WAKEUP(void); #endif//唤醒
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- stm32 W25Q64