【智嵌 STM32F407开发板(增强型)试用体验】+SST25 FLASH操作

  • apleilx
  • LV5工程师
  • |      2018-05-14 15:16:05
  • 浏览量 1732
  • 回复:0
评估板板载了一颗16Mbits的SST25VF016B来记录数据,去官网找了下资料,看样子快要停产了,不过Flash的操作方法有相似之处。 下面是芯片操作程序,分SPI和FLASH命令两部分。 SPI操作:参考原子的SPI驱动改写。
/*****************************************************************************//*!

* @brief   Spi 3 init .

*               

* @param   none

*

* @return  none

*

* @ Pass/ Fail criteria: none

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



void SPI3_Init(void) {

    u16 tempreg = 0;

    GPIO_InitTypeDef GPIO_InitStruct;

    

    __HAL_RCC_SPI3_CLK_ENABLE();

    __HAL_RCC_SPI3_FORCE_RESET();

    // SPI IO

    GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    __HAL_RCC_SPI3_RELEASE_RESET();

    //SPI - SS IO  PG10

    GPIO_InitStruct.Pin = GPIO_PIN_10;

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

    

    //这里只针对SPI口初始化

    RCC->APB2RSTR |= 1 << 20; //复位SPI3

    RCC->APB2RSTR &= ~(1 << 20); //停止复位SPI3

    tempreg |= 0 << 10; //全双工模式	

    tempreg |= 1 << 9; //软件nss管理

    tempreg |= 1 << 8;

    tempreg |= 1 << 2; //SPI主机  

    tempreg |= 0 << 11; //8位数据格式	

    tempreg |= 1 << 1; //空闲模式下SCK为1 CPOL=1 

    tempreg |= 1 << 0; //数据采样从第2个时间边沿开始,CPHA=1  

    //对SPI3属于APB2的外设.时钟频率最大为84Mhz频率.

    tempreg |= 7 << 3; //Fsck=Fpclk1/256

    tempreg |= 0 << 7; //MSB First  

    tempreg |= 1 << 6; //SPI启动 

    SPI3->CR1 = tempreg; //设置CR1  

    SPI3->I2SCFGR &= ~(1 << 11); //选择SPI模式

    PGout(10) = 0;

    SPI3_ReadWriteByte(0xff); //启动传输	

    PGout(10) = 1;

}



/*****************************************************************************//*!

* @brief   spi3 speed set.

*               

* @param   none

*

* @return  none

*

* @ Pass/ Fail criteria: none

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

void SPI3_SetSpeed(u8 SpeedSet) {

    SpeedSet &= 0X07; //限制范围

    SPI3->CR1 &= 0XFFC7;

    SPI3->CR1 |= SpeedSet << 3; //设置SPI3速度  

    SPI3->CR1 |= 1 << 6; //SPI设备使能	  

}



/*****************************************************************************//*!

* @brief   spi3 write and read.

*               

* @param   none

*

* @return  none

*

* @ Pass/ Fail criteria: none

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

u8 SPI3_ReadWriteByte(u8 TxData) {

    while ((SPI3->SR & 1 << 1) == 0); //等待发送区空 

    SPI3->DR = TxData; //发送一个byte  

    while ((SPI3->SR & 1 << 0) == 0); //等待接收完一个byte  

    return SPI3->DR; //返回收到的数据				    

}
Flash操作
/* ------------------------------------------------------------------------*

 *

 * ------------------------------------------------------------------------*/

#include "sst25_cmd.h"

#include "spi.h"

#include "pincfg.h"

     

uint8_t scs;



#define SST25Cs(x)    x?(PGout(10)=1):(PGout(10)=0)

#define SpiRw(x)     SPI3_ReadWriteByte(x)

#define SpiDmaRw(x,y,z)



// command list

#define SST25CMD_Read_Data                                 0x03

#define SST25CMD_Fast_Read                                 0x0B

#define SST25CMD_Sector_Erase                              0x20

#define SST25CMD_Block_Erase_32K                           0x52

#define SST25CMD_Block_Erase_64K                           0xD8

#define SST25CMD_Chip_Erase                                0x60

#define SST25CMD_Byte_Program                              0x02

#define SST25CMD_AddrInc_Program                           0xAD

#define SST25CMD_Read_Status                               0x05



#define SST25CMD_SRWrite Enable                            0x50

#define SST25CMD_Write_Status                              0x01 //写入的空间保护位具有掉电记忆功能

#define SST25CMD_Write_Enable                              0x06

#define SST25CMD_Write_Disable                             0x04



#define SST25CMD_Read_ID                                   0x90

#define SST25CMD_Read_JEDEC_ID                             0x9F



#define SST25CMD_So_Enable                                 0x70

#define SST25CMD_So_Disable                                0x80



typedef union {

    uint32_t Val;

    struct {

        uint8_t LB;

        uint8_t HB;

        uint8_t UB;

        uint8_t MB;

    }byte;

} UINT32_VAL;





void SST25Wait(uint8_t Cnt)

{

    while(Cnt --){};

}



/*****************************************************************************//*!

* @brief   read status.

* @param   none

*

* @return  statues

*

* @ Pass/ Fail criteria: none

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

uint8_t SST25CmdStRead(void)

{

    uint8_t St;

    

    SST25Cs(0); 

    SpiRw( SST25CMD_Read_Status);

    St = SpiRw( 0xFF);

    SST25Cs(1); 

    

    return St;

}



void SST25CmdStWrite(uint8_t St){



    while(SST25Busy()){}

    

    while( SST25Q_ST_WRITE_EN != (SST25CmdStRead()&SST25Q_ST_WRITE_EN))

    SST25CmdWriteEn();

    

    SST25Cs(0); 

    SpiRw( SST25CMD_Write_Status);

    St = SpiRw( St);

    SST25Cs(1); 

    

    NOP20();

    while(SST25Busy()){}

    

    while( SST25Q_ST_WRITE_EN == (SST25CmdStRead()&SST25Q_ST_WRITE_EN))

    SST25CmdWriteDis();



}



/*****************************************************************************//*!

* @brief   read busy statues.

*              

* @param   none

*

* @return  busy or not

*

* @ Pass/ Fail criteria: none

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

uint8_t  SST25Busy(void)

{

    uint8_t FlashSt;

    

    SST25Cs(0); 

    SpiRw( SST25CMD_Read_Status);

    FlashSt = SpiRw( 0xFF);

    SST25Cs(1); 

    

    return ((uint8_t)(FlashSt & SST25Q_ST_BUSY_MASK));

}



/*****************************************************************************//*!

* @brief   write enable.

*               

* @param   none

*

* @return  none

*

* @ Pass/ Fail criteria: none

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

void SST25CmdWriteEn(void)

{

    SST25Cs(0); 



    SpiRw( SST25CMD_Write_Enable);

   

    SST25Cs(1); 

}



/*****************************************************************************//*!

* @brief   write disable.

*               

* @param   none

*

* @return  none

*

* @ Pass/ Fail criteria: none

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

void SST25CmdWriteDis(void)

{

    SST25Cs(0); 



    SpiRw( SST25CMD_Write_Disable);

   

    SST25Cs(1); 

}



/*****************************************************************************//*!

* @brief   Erase aector.      

*               

* @param   addr:      data address in chip

*

* @return  none

*

* @ Pass/ Fail criteria: none

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

void SST25SectorErase(uint32_t addr)

{

    UINT32_VAL Par;

    

    //waiting for idle

    while(SST25Busy()){}

    

    while( SST25Q_ST_WRITE_EN != (SST25CmdStRead()&SST25Q_ST_WRITE_EN))

    SST25CmdWriteEn();

        

    SST25Cs(0);

    Par.Val = addr;   

    SpiRw( SST25CMD_Sector_Erase);

    SpiRw( Par.byte.UB);

    SpiRw( Par.byte.HB);

    SpiRw( Par.byte.LB); 

    SST25Cs(1);

    

    NOP20();

    while(SST25Busy()){}  

}



/*****************************************************************************//*!

* @brief   Erase block.     

*               

* @param   addr:      data address in chip

*

* @return  none

*

* @ Pass/ Fail criteria: none

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

void SST25BlockErase(uint32_t addr)

{

    UINT32_VAL Par;

    

    //waiting for idle

    while(SST25Busy()){}

    while( SST25Q_ST_WRITE_EN != (SST25CmdStRead()&SST25Q_ST_WRITE_EN))

    SST25CmdWriteEn();

        

    SST25Cs(0);

    Par.Val = addr;   

    SpiRw( SST25CMD_Block_Erase_32K);

    SpiRw( Par.byte.UB);

    SpiRw( Par.byte.HB);

    SpiRw( Par.byte.LB); 

    SST25Cs(1);

    

    NOP20();

    while(SST25Busy()){}

}



/*****************************************************************************//*!

* @brief   Erase chip.

*               

* @param   none

*

* @return  none

*

* @ Pass/ Fail criteria: none

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

void SST25ChipErase(void )

{

    while(SST25Busy()){}

    while( SST25Q_ST_WRITE_EN != (SST25CmdStRead()&SST25Q_ST_WRITE_EN))

    SST25CmdWriteEn();

        

    SST25Cs(0);  

    SpiRw( SST25CMD_Chip_Erase);

    SST25Cs(1);   

    

    NOP20();

    while(SST25Busy()){}

    

}



/*****************************************************************************//*!

* @brief   read data.

*               

* @param   addr          address in chip

*          len           length will be read

*          des           destination

*

* @return  none

*

* @ Pass/ Fail criteria: none

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

void SST25Read(uint32_t addr,uint32_t Len,uint8_t *Des)

{

    UINT32_VAL Par;

    

    //waiting for idle

    while(SST25Busy()){}

    //

    SST25Cs(0);

    Par.Val = addr;   

    SpiRw( SST25CMD_Read_Data);

    SpiRw( Par.byte.UB);

    SpiRw( Par.byte.HB);

    SpiRw( Par.byte.LB);

    while(Len--)

    {

        *Des++ = SpiRw( 0x55 );

    } 

    

    SST25Cs(1);

}



/*****************************************************************************//*!

* @brief   write data ,must be in same page.

*               

* @param   addr          address in chip

*          len           length will be read

*          des           source

*

* @return  none

*

* @ Pass/ Fail criteria: none

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

void SST25Write(uint32_t addr,uint32_t Len,uint8_t *Src)

{

    UINT32_VAL Par;

    

    //waiting for idle

    while(SST25Busy()){}



    Par.Val = addr;  

    while(Len--){

        SST25CmdWriteEn();

        NOP20();

        SST25Cs(0);

        SpiRw( SST25CMD_Byte_Program);

        SpiRw( Par.byte.UB);

        SpiRw( Par.byte.HB);

        SpiRw( Par.byte.LB);

        SpiRw( *Src++); 

        SST25Cs(1);

        Par.Val++;

        while(SST25Busy()){}

    }

    

    NOP20();

    while(SST25Busy()){}

    



}
  • 0
  • 收藏
  • 举报
  • 分享
我来回复

登录后可评论,请 登录注册

所有回答 数量:0
x
收藏成功!点击 我的收藏 查看收藏的全部帖子