STM32----8----SPI(下)与FLASH通信

STM32----8----SPI(下)与FLASH通信 
文章发表于:2011-05-09 15:04 
[attach]150356[/attach]STM32----8----SPI(下)与FLASH通信 

----------------------------------------------------------------------------------------------------------------------------------------- 关于W25X16  SPI型FLASH的手册在附件中,这里主要是W25X16的驱动程序的书写,通过配合STM32主机的SPI模式,读写FLASH 

w25x16.h 

#ifndef __W25X16_H 

#define __W25X16_H        

#include "stm32f10x_lib.h" 

/****************************************************************************   

-W25X16的宏定义   

-片选信号CS

-PA2的宏定义 

****************************************************************************/

 #define SPI_FLASH_CS_PORT              GPIOA 

#define SPI_FLASH_CS_CLK               RCC_APB2Periph_GPIOA   

#define SPI_FLASH_CS_PIN               GPIO_Pin_2 

#define Set_SPI_FLASH_CS  {GPIO_SetBits(SPI_FLASH_CS_PORT,SPI_FLASH_CS_PIN);} 

#define Clr_SPI_FLASH_CS  {GPIO_ResetBits(SPI_FLASH_CS_PORT,SPI_FLASH_CS_PIN);}        //W25X16读写 

#define FLASH_ID 0XEF14 

/*********************************************  

- W25X16的操作指令表,STM32通过向W25X16   

发送以下指令就可以对W25X16进行以下的操作 

*********************************************/ 

#define W25X_WriteEnable  0x06  

#define W25X_WriteDisable  0x04  

#define W25X_ReadStatusReg  0x05  

#define W25X_WriteStatusReg  0x01  

#define W25X_ReadData   0x03  

#define W25X_FastReadData  0x0B  

#define W25X_FastReadDual  0x3B  

#define W25X_PageProgram  0x02  

#define W25X_BlockErase   0xD8

#define W25X_SectorErase  0x20  

容量为

4M

字节

,

共有

64

Block, 

1024

Sector 

,16384

Page 

 - W25X64

容量为

8M

字节

,

共有

128

Block,2048

Sector 

,32768

Page 

***************************************************************************/ 

void 

SPI_Flash_Init(void) 

 SPIx_Init();     

//

初始化

SPI 

}  

 

/***************************************************************************

 

    

功能描述:读

w25x16 

Flash

状态寄存器的函数

 

    

隶属模块:

w25x16 

Flash

操作

 

  - 

函数属性:外部,使用户使用

 

  - 

参数说明:无

 

  - 

返回说明:返回

w25x16 

Flash

的当前状态

 

 ------------------------------------------------------ 

 |  

7   

6   

5   

4   

3   

2   

1   

0      

 | SPR   

RV  

TB 

BP2 

BP1 

BP0 

WEL 

BUSY     

 | SPR:

默认

0,

状态寄存器保护位

,

配合

WP

使用

    

 | TB,BP2,BP1,BP0:FLASH

区域写保护设置

     

 | WEL:

写使能锁定

          

 | BUSY:

忙标记位

(1,

;0,

空闲

)       

 | 

默认

:0x00           

 | 

只有

SPR,TB,BP2,BP1,BP0(bit 

7,5,4,3,2)

可以写

!!!  

|

 

 ----------------------------------------------------- 

 - 

操作说明:

CS

电平先拉低、

STM32

利用

SPI

发送读

FLASH

状态寄存器命令、

STM32

读取数据、

CS

高,发送的命令被采集

 

    

如果

CS

不拉高,则

FLASH

的状态会不断发送出来。根据读出的字节就可以判断当前的

FLASH 

    

的工作准状态。

 

***************************************************************************/ 

u8 

SPI_Flash_ReadSR(void)   

 

{  

 

 u8 

byte=0;   

 

 Clr_SPI_FLASH_CS;                            

//

使能器件

   

 

 SPIx_ReadWriteByte(W25X_ReadStatusReg);    

//

发送读取状态寄存器命令

    

 

 byte=SPIx_ReadWriteByte(0Xff);             

//

读取一个字节

  

 

 Set_SPI_FLASH_CS;                            

//

取消片选

     

 

 return 

byte;   

 

}

 NumByteToWrite-=pageremain;     

//

减去已经写入了的字节数

 

   if(NumByteToWrite>256) 

    pageremain=256; 

//

一次可以写入

256

个字节

 

   else 

 

    pageremain=NumByteToWrite; 

   

//

不够

256

个字节了

 

  } 

 }     

 

}  

 

/***************************************************************************

 

    

功能描述:

写扇区

w25x16 

Flash

操作函数,

在指定地址开始写入指定长度的数据,

该函数带擦除操作

    

隶属模块:

w25x16 

Flash

操作

 

  - 

函数属性:外部,使用户使用

 

  - 

参数说明:

pBuffer:

数据存储区

 

    WriteAddr:

开始写的地址

(24bit) 

    NumByteToWrite:

要写入的字节数

(

最大

65535) 

  

  - 

返回说明:无

 

 - 

操作说明:

 

  - 

256bytes

为一个

Page

,每

4Kbytes

为一个

Sector

,每

16

个扇区为

1

Block 

  - W25X16

容量为

2M

字节

,

共有

32

Block, 

512

Sector  

8192

Page 

  - W25X32

容量为

4M

字节

,

共有

64

Block, 

1024

Sector 

,16384

Page 

  - W25X64

容量为

8M

字节

,

共有

128

Block,2048

Sector 

,32768

Page 

***************************************************************************/  

     

 

u8 

SPI_FLASH_BUF[4096]; 

void 

SPI_Flash_Write(u8* 

pBuffer,u32 

WriteAddr,u16 

NumByteToWrite)   

 

 

 u32 

secpos; 

 u16 

secoff; 

 u16 

secremain;    

 

  u16 

i;    

 

 secpos=WriteAddr/4096;//

扇区地址

 

0~511 

for 

w25x16 

 secoff=WriteAddr%4096;//

在扇区内的偏移

 

 secremain=4096-secoff;//

扇区剩余空间大小

   

 

 if(NumByteToWrite<=secremain) 

  secremain=NumByteToWrite;//

不大于

4096

个字节

 

 while(1) 

 

 {  

  SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);//

读出整个扇区的内容

NumByteToWrite-=pageremain;     //减去已经写入了的字节数    if(NumByteToWrite>256) 
    pageremain=256; //一次可以写入256个字节    else  
    pageremain=NumByteToWrite;    //不够256个字节了   }  }      }   
/*************************************************************************** 
    - 功能描述:写扇区w25x16 Flash操作函数,在指定地址开始写入指定长度的数据,该函数带擦除操作!     - 隶属模块:w25x16 Flash操作   - 函数属性:外部,使用户使用   - 参数说明:pBuffer:数据存储区     WriteAddr:开始写的地址(24bit) 
    NumByteToWrite:要写入的字节数(最大65535)     - 返回说明:无  - 操作说明: 
  - 每256bytes为一个Page,每4Kbytes为一个Sector,每16个扇区为1个Block   - W25X16容量为2M字节,共有32个Block, 512个Sector  , 8192个Page   - W25X32容量为4M字节,共有64个Block, 1024个Sector ,16384个Page   - W25X64容量为8M字节,共有128个Block,2048个Sector ,32768个Page 
***************************************************************************/        u8 SPI_FLASH_BUF[4096]; 

   if(SPI_FLASH_BUF[secoff+i]!=0XFF)     break;//需要擦除        } 
  if(i<secremain)//需要擦除   { 
   SPI_Flash_Erase_Sector(secpos);//擦除这个扇区    for(i=0;i<secremain;i++)    //复制    { 
    SPI_FLASH_BUF[i+secoff]=pBuffer[i];       } 
   SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);//写入整个扇区     }   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 Flash擦除整个芯片操作函数     - 隶属模块:w25x16 Flash操作   - 函数属性:外部,使用户使用   - 参数说明:无

 - 返回说明:无 
 - 操作说明:W25X16:25s W25X32:40s W25X64:40s 等待时间超长...  擦除完以后,所有字节数据为0XFF 
  (1)因为要擦除FLASH芯片,所以要发送写使能命令   (2)读状态寄存器状态,通过BUSY位判断指令是否写完。   (3)片选拉低,选中FLASH   (4)发送擦除芯片命令   (5)片选拉高,指令发送完成 
  (6)检查BUSY位,等待芯片擦除结束 
***************************************************************************/ void SPI_Flash_Erase_Chip(void)    {                                              
    SPI_FLASH_Write_Enable();                  //SET WEL      SPI_Flash_Wait_Busy();    
   Clr_SPI_FLASH_CS;                            //使能器件    
    SPIx_ReadWriteByte(W25X_ChipErase);        //发送片擦除命令    Set_SPI_FLASH_CS;                            //取消片选              SPI_Flash_Wait_Busy();          //等待芯片擦除结束 }    
/***************************************************************************     - 功能描述:w25x16 Flash擦除一个扇区操作函数     - 隶属模块:w25x16 Flash操作   - 函数属性:外部,使用户使用 
  - 参数说明:Dst_Addr:扇区地址 0~511 for w25x16   - 返回说明:无 
 - 操作说明:擦除一个山区的最少时间:150msXFF 
  - 每256bytes为一个Page,每4Kbytes为一个Sector,每16个扇区为1个Block   - W25X16容量为2M字节,共有32个Block, 512个Sector  , 8192个Page   - W25X32容量为4M字节,共有64个Block, 1024个Sector ,16384个Page   - W25X64容量为8M字节,共有128个Block,2048个Sector ,32768个Page   (1)发送写使能命令 
  (2)等待发送完成,通过检测状态寄存器的最低位是否为0   (3)CS拉低,选中芯片   (4)发送擦除命令   (5)CS拉高,取消片选 
  (6)等待擦除结束,如果结束BUSY会为0 

***************************************************************************/

void SPI_Flash_Erase_Sector(u32 Dst_Addr)    {    
 Dst_Addr*=4096; 
    SPI_FLASH_Write_Enable();                  //SET WEL        SPI_Flash_Wait_Busy();    
   Clr_SPI_FLASH_CS;                            //使能器件    
    SPIx_ReadWriteByte(W25X_SectorErase);      //发送扇区擦除指令      SPIx_ReadWriteByte((u8)((Dst_Addr)>>16));  //发送24bit地址         SPIx_ReadWriteByte((u8)((Dst_Addr)>>8));        SPIx_ReadWriteByte((u8)Dst_Addr);   
 Set_SPI_FLASH_CS;                            //取消片选                 SPI_Flash_Wait_Busy();          //等待擦除完成 }   
/***************************************************************************     - 功能描述:w25x16 Flash等待空闲操作函数     - 隶属模块:w25x16 Flash操作   - 函数属性:外部,使用户使用   - 参数说明:无   - 返回说明:无 
 - 操作说明:就是检查FLASH的最低位是否为1 

***************************************************************************/ void SPI_Flash_Wait_Busy(void)   

 {    

 while ((SPI_Flash_ReadSR()&0x01)==0x01);   // 等待BUSY位清空 }   
/***************************************************************************     - 功能描述:w25x16 Flash掉电模式操作函数     - 隶属模块:w25x16 Flash操作   - 函数属性:外部,使用户使用   - 参数说明:无   - 返回说明:无  - 操作说明: 
  (1)CS拉低,选中芯片。 
  (2)STM32发送W25X_PowerDown指令   (3)CS拉高,取消芯片。   (4)延时TPD个延时 

***************************************************************************/  void SPI_Flash_PowerDown(void) 

 

  

 Clr_SPI_FLASH_CS;                            

//

使能器件

   

 

    

SPIx_ReadWriteByte(W25X_PowerDown);        

//

发送掉电命令

  

 

 Set_SPI_FLASH_CS;                            

//

取消片选

     

       

 

    

delay_us(3);                               

//

等待

TPD  

 

}   

 

/***************************************************************************

 

    

功能描述:

w25x16 

Flash

唤醒操作函数

 

    

隶属模块:

w25x16 

Flash

操作

 

  - 

函数属性:外部,使用户使用

 

  - 

参数说明:无

 

  - 

返回说明:无

 

 - 

操作说明:

 

  

1

CS

拉低,选中芯片。

 

  

2

STM32

发送

 

W25X_ReleasePowerDown

指令

 

  

3

CS

拉高,取消芯片。

 

  

4

)延时

tres

个延时

 

***************************************************************************/ 

 

void 

SPI_Flash_WAKEUP(void)   

 

{  

 

  

 Clr_SPI_FLASH_CS;                            

//

使能器件

   

 

    

SPIx_ReadWriteByte(W25X_ReleasePowerDown);   

//  

send 

W25X_PowerDown 

command 

0xAB    

 

 Set_SPI_FLASH_CS;                            

//

取消片选

     

       

 

    

delay_us(3);                               

//

等待

TRES1 

}   

 

  

有了以上的驱动函数,

STM32

SPI

模式下就可以和

W25X16

进行通信了


猜你喜欢

转载自blog.csdn.net/errorhai/article/details/79449300