spiflash stm32spiflash的编程.docx
- 文档编号:25926259
- 上传时间:2023-06-16
- 格式:DOCX
- 页数:12
- 大小:18.79KB
spiflash stm32spiflash的编程.docx
《spiflash stm32spiflash的编程.docx》由会员分享,可在线阅读,更多相关《spiflash stm32spiflash的编程.docx(12页珍藏版)》请在冰豆网上搜索。
spiflashstm32spiflash的编程
本帖最后由orange-208于2012-5-2810:
05编辑
voidSPI_Flash_Write(u8*pBuffer,u32WriteAddr,u16NumByteToWrite)
SPI_FLASH_Write_SR(0x02);//使能状态寄存器中的写存储器
SST25V_DBSY();
SPI_FLASH_Write_SR(0x02);//使能状态寄存器中的写存储器
SST25V_DBSY();
实验目的:
将数据写入外部FLASH中,然后再读出来显示在LCD上
实验平台:
基于STM32F103C8T6的彩屏开发板
FLASH:
SST25VF016B
flash_SST.c
#include"flash_SST.h"
#include"spi.h"
#include"delay.h"
//4Kbytes为一个Sector
//16个扇区为1个Block
//SST25VF016B
//容量为2M字节,共有32个Block(块),512个Sector(扇区)
//初始化SPIFLASH的IO口
//修改状态寄存器,允许芯片存储器被写
voidSPI_Flash_Init(void)
{
RCC->APB2ENR|=1<<2; //PORTA时钟使能
GPIOA->CRH&=0XFFFFFF0F;
GPIOA->CRH|=0X00000030; //PA9推挽
GPIOA->ODR|=1<<9; //PA9上拉
SPIx_Init(); //初始化SPI
SPI_FLASH_Write_SR(0x02); //使能状态寄存器中的写存储器
SST25V_DBSY();
}
//读取SPI_FLASH的状态寄存器
//BIT7 6 5 4 3 2 1 0
//SPR RV TBBP2BP1BP0WELBUSY
//SPR:
默认0,状态寄存器保护位,配合WP使用
//TB,BP2,BP1,BP0:
FLASH区域写保护设置
//WEL:
写使能锁定
//BUSY:
忙标记位(1,忙;0,空闲)
//默认:
0x00
u8SPI_Flash_ReadSR(void)
{
u8byte=0;
SPI_FLASH_CS=0; //使能器件
SPIx_ReadWriteByte(SST25_ReadStatusReg); //发送读取状态寄存器命令
byte=SPIx_ReadWriteByte(0Xff); //读取一个字节
SPI_FLASH_CS=1; //取消片选
returnbyte;
}
//写SPI_FLASH状态寄存器
//只有SPR,TB,BP2,BP1,BP0(bit7,5,4,3,2)可以写!
!
!
voidSPI_FLASH_Write_SR(u8sr)
{
SPI_FLASH_CS=0; //片选
SPIx_ReadWriteByte(SST25_EnableWriteStatusReg); //使能写状态寄存器命令
SPI_FLASH_CS=1; //取消片选
SPI_FLASH_CS=0; //片选
SPIx_ReadWriteByte(SST25_WriteStatusReg); //发送写取状态寄存器命令
SPIx_ReadWriteByte(sr); //写入一个字节
SPI_FLASH_CS=1; //取消片选
}
//SPI_FLASH写使能
//将WEL置位
voidSPI_FLASH_Write_Enable(void)
{
SPI_FLASH_CS=0; //使能器件
SPIx_ReadWriteByte(SST25_WriteEnable); //发送写使能
SPI_FLASH_CS=1; //取消片选
}
//SPI_FLASH写禁止
//将WEL清零
voidSPI_FLASH_Write_Disable(void)
{
SPI_FLASH_CS=0; //使能器件
SPIx_ReadWriteByte(SST25_WriteDisable); //发送写禁止指令
SPI_FLASH_CS=1; //取消片选
}
//读取芯片IDSST25VF016的是0XBF41
u16SPI_Flash_ReadID(void)
{
u16Temp=0;
SPI_FLASH_CS=0;
//发送读取ID命令
SPIx_ReadWriteByte(0x90);
//发送24位的地址
SPIx_ReadWriteByte(0x00);
SPIx_ReadWriteByte(0x00);
SPIx_ReadWriteByte(0x00);
//读取返回的16位值
Temp=SPIx_ReadWriteByte(0xFF)<<8; //高8位数据
Temp+=SPIx_ReadWriteByte(0xFF); //底八位数据
SPI_FLASH_CS=1;
returnTemp;
}
//读取SPIFLASH
//在指定地址开始读取指定长度的数据
//pBuffer:
数据存储区
//ReadAddr:
开始读取的地址(24bit)
//NumByteToRead:
要读取的字节数(最大65535即64k)
voidSPI_Flash_Read(u8*pBuffer,u32ReadAddr,u16NumByteToRead)
{
u16i;
SPI_FLASH_CS=0; //使能器件
SPIx_ReadWriteByte(SST25_ReadData); //发送读取命令
//发送24bit地址
SPIx_ReadWriteByte((u8)((ReadAddr)>>16));
SPIx_ReadWriteByte((u8)((ReadAddr)>>8));
SPIx_ReadWriteByte((u8)ReadAddr);
for(i=0;i { pBuffer=SPIx_ReadWriteByte(0XFF); //循环读数 } SPI_FLASH_CS=1; //取消片选 } //地址自动增加的写数据A voidAutoAddressIncrement_WordProgramA(u8Byte1,u8Byte2,u32Addr) { SPI_FLASH_Write_Enable(); SPI_FLASH_CS=0; SPIx_ReadWriteByte(SST25_AAI_WordProgram); //输入所要写数据的起始地址 SPIx_ReadWriteByte((Addr&0xFF0000)>>16); SPIx_ReadWriteByte((Addr&0xFF00)>>8); SPIx_ReadWriteByte(Addr&0xFF); //发送最初的两个数据 SPIx_ReadWriteByte(Byte1); SPIx_ReadWriteByte(Byte2); SPI_FLASH_CS=1; SPI_Flash_Wait_Busy(); } //地址自动增加的写数据B voidAutoAddressIncrement_WordProgramB(u8state,u8Byte1,u8Byte2) { SPI_FLASH_Write_Enable(); SPI_FLASH_CS=0; SPIx_ReadWriteByte(SST25_AAI_WordProgram); SPIx_ReadWriteByte(Byte1); SPIx_ReadWriteByte(Byte2); SPI_FLASH_CS=1; SPI_Flash_Wait_Busy(); if(state==1) { SPI_FLASH_Write_Disable(); } SPI_Flash_Wait_Busy(); } //结合AB构成的地址自动增加的连续数据的写入 //具有先擦除待写区域的功能 //pBuffer: 为待写数据组 //WriteAddr: 所写数据的起始地址 //NumByteToWrite: 所要写的数据的长度 voidSPI_Flash_Write(u8*pBuffer,u32WriteAddr,u16NumByteToWrite) { u16i,temp; u32secpos; u16secoff; u16secremain; //以下代码为擦除待写区域的代码 secpos=WriteAddr/4096; //扇区(4K)地址0~511for SST25VF016 secoff=WriteAddr@96; //在扇区内的偏移 secremain=4096-secoff; //扇区剩余空间大小 if(NumByteToWrite { temp=1; } else //剩余空间小于所存数据 { i=NumByteToWrite-secremain; //判断还占了几个扇区 if(i%96==0) temp=i/4096+1; else temp=i/4096+2; } for(i=0;i { SPI_Flash_Erase_Sector((secpos+i)*4096); //擦除将要写入数据的扇区 } //以下代码为将数据写入指定地址的代码 if(NumByteToWrite%2==0) { temp=NumByteToWrite/2-1; } else { temp=NumByteToWrite/2; } AutoAddressIncrement_WordProgramA(pBuffer[0],pBuffer[1],WriteAddr); //开始写数据 for(i=1;i { AutoAddressIncrement_WordProgramB(0,pBuffer[2*i],pBuffer[2*i+1]); } if(NumByteToWrite%2==0) { AutoAddressIncrement_WordProgramB(1,pBuffer[NumByteToWrite-2],pBuffer[NumByteToWrite-1]); //结束写数据 } else { AutoAddressIncrement_WordProgramB(1,pBuffer[NumByteToWrite-1],0); //结束写数据 } //写入1Byte数据 //pBuffer: 待写的数据 //WriteAddr: 待写数据的地址 voidFlash_WriteByte(u8*pBuffer,u32WriteAddr) { u32secpos; secpos=WriteAddr/4096; //扇区地址0~511forw25x16 4096=4k SPI_Flash_Erase_Sector(secpos); //擦除这个扇区 SPI_FLASH_Write_Enable(); //SETWEL SPI_FLASH_CS=0; //使能器件 SPIx_ReadWriteByte(SST25_ByteProgram); //发送写页命令 //发送24bit地址 SPIx_ReadWriteByte((u8)((WriteAddr)>>16)); SPIx_ReadWriteByte((u8)((WriteAddr)>>8)); SPIx_ReadWriteByte((u8)WriteAddr); //发送待写的数据 SPIx_ReadWriteByte(pBuffer[0]); SPI_FLASH_CS=1; SPI_Flash_Wait_Busy(); //等待写完成 } //擦除整个芯片 //整片擦除时间: //W25X16: 25s //W25X32: 40s //W25X64: 40s //等待时间超长... voidSPI_Flash_Erase_Chip(void) { SPI_FLASH_Write_Enable(); //SETWEL SPI_Flash_Wait_Busy(); SPI_FLASH_CS=0; //使能器件 SPIx_ReadWriteByte(SST25_ChipErase); //发送片擦除命令 SPI_FLASH_CS=1; //取消片选 SPI_Flash_Wait_Busy(); //等待芯片擦除结束 } //擦除一个扇区 //Dst_Addr: 扇区地址0~511forw25x16 //擦除一个山区的最少时间: 150ms voidSPI_Flash_Erase_Sector(u32Dst_Addr) { SPI_FLASH_Write_Enable(); //SETWEL SPI_Flash_Wait_Busy(); SPI_FLASH_CS=0; //使能器件 SPIx_ReadWriteByte(SST25_4KByte_BlockERASE); //发送扇区擦除指令 SPIx_ReadWriteByte((u8)((Dst_Addr)>>16)); //发送24bit地址 SPIx_ReadWriteByte((u8)((Dst_Addr)>>8)); SPIx_ReadWriteByte((u8)Dst_Addr); SPI_FLASH_CS=1; //取消片选 SPI_Flash_Wait_Busy(); //等待擦除完成 } //等待空闲 voidSPI_Flash_Wait_Busy(void) { while((SPI_Flash_ReadSR()&0x01)==0x01); //等待BUSY位清空 } voidSST25V_EBSY(void) { SPI_FLASH_CS=0; SPIx_ReadWriteByte(SST25_EBSY); SPI_FLASH_CS=1; } voidSST25V_DBSY(void) { SPI_FLASH_CS=0; SPIx_ReadWriteByte(SST25_DBSY); SPI_FLASH_CS=1; } Flash.h #ifndef__FLASH_SST_H #define__FLASH_SST_H #include"sys.h" #define SPI_FLASH_CSPAout(9) //选中FLASH #defineFLASH_ID0XBF41 //SST25VF016读写 //指令表 #defineSST25_ReadData 0x03 #defineSST25_FastReadData 0x0B #defineSST25_4KByte_BlockERASE 0x20 #defineSST25_32KByte_BlockErase 0x52 #defineSST25_64KByte_BlockErase 0xD8 #defineSST25_ChipErase 0xC7 #defineSST25_ByteProgram 0x02 #defineSST25_AAI_WordProgram 0xAD #defineSST25_ReadStatusReg 0x05 #defineSST25_EnableWriteStatusReg 0x50 #defineSST25_WriteStatusReg 0x01 #defineSST25_WriteEnable 0x06 #defineSST25_WriteDisable 0x04 #defineSST25_ManufactDeviceID 0x90 #defineSST25_JedecDeviceID 0x9F #defineSST25_EBSY 0x70 #defineSST25_DBSY 0x80 voidSPI_Flash_Init(void); u16 SPI_Flash_ReadID(void); //读取FLASHID u8 SPI_Flash_ReadSR(void); //读取状态寄存器 voidSPI_FLASH_Write_SR(u8sr); //写状态寄存器 voidSPI_FLASH_Write_Enable(void); //写使能 voidSPI_FLASH_Write_Disable(void); //写保护 voidSPI_Flash_Read(u8*pBuffer,u32ReadAddr,u16NumByteToRead); //读取flash voidSPI_Flash_Erase_Chip(void); //整片擦除 voidSPI_Flash_Erase_Se
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- spiflash stm32 spiflash的编程 编程
![提示](https://static.bdocx.com/images/bang_tan.gif)