stm32驱动SST25VF程序

发布者:橙子1234最新更新时间:2015-07-10 来源: 51hei关键字:stm32  SST25VF 手机看文章 扫描二维码
随时随地手机看文章
main.c:

#include "stm32f10x_lib.h"
#include "hw_conf.h"
#include"SST25V.h"

void delay(int d);

u8 Tx_Buffer[] = {0x72,0x62,0x02,0x78,0x60,0x96,0x86,0x79,0x85,0x24,0x36,0x48,0x56,0x68,0x70,0x75,0x88,0x24};
u8 Rx_Buffer[BufferSize];
u8 DataByte=0;

int main(void)
{
#ifdef DEBUG
  debug();
#endif

  Setup_System();    //系统启动
 
  SST25V_Init();    //Flash芯片初始化
 
  SST25V_ChipErase();   //擦除整个芯片空间
 
  DataByte = SST25V_ByteRead(0x000000);             //读取0x000000地址空间的数据信息
  DataByte = SST25V_ByteRead(0x000010);             //读取0x000000地址空间的数据信息
  DataByte = SST25V_ByteRead(0x000100);             //读取0x000100地址空间的数据信息
  DataByte = SST25V_ByteRead(0x001000);             //读取0x001000地址空间的数据信息
  DataByte = SST25V_ByteRead(0x010000);             //读取0x010000地址空间的数据信息
  DataByte = SST25V_ByteRead(0x100000);             //读取0x100000地址空间的数据信息
  DataByte = SST25V_ByteRead(0x600000);             //读取0x000000地址空间的数据信息
  DataByte = SST25V_ByteRead(0xF00000);             //读取0x600000地址空间的数据信息
  DataByte = SST25V_ByteRead(0xFFFFFF);             //读取0xFFFFFF地址空间的数据信息
 
 
 
  SST25V_AAI_WriteBytes(0x72, 0xFFF000,0x001000);   //向以0xFFF000为起始地址的数据空间写入0x001000个0x10--即向最后4KB空间写入0x10
 
  DataByte = SST25V_ByteRead(0x000000);             //读取0x000000地址空间的数据信息
  DataByte = SST25V_ByteRead(0x000001);             //读取0x000001地址空间的数据信息
  DataByte = SST25V_ByteRead(0x000002);             //读取0x000002地址空间的数据信息
  DataByte = SST25V_ByteRead(0xFFF000);             //读取0xFFF000地址空间的数据信息
  DataByte = SST25V_ByteRead(0xFFF0EE);             //读取0xFFF0EE地址空间的数据信息
  DataByte = SST25V_ByteRead(0xFFFEEE);             //读取0xFFFEEE地址空间的数据信息
  DataByte = SST25V_ByteRead(0xFFFFFF);             //读取0xFFFFFF地址空间的数据信息
 
 
 
  SST25V_SectorErase_4KByte(0xFFF000);              //擦除以0xFFF000为起始地址的4KB数据空间
 
  DataByte = SST25V_ByteRead(0x000000);             //读取0x000000地址空间的数据信息
 
  DataByte = SST25V_ByteRead(0xFFF000);             //读取0xFFF000地址空间的数据信息
  DataByte = SST25V_ByteRead(0x000001);             //读取0x000001地址空间的数据信息
  DataByte = SST25V_ByteRead(0x000002);             //读取0x000002地址空间的数据信息
  DataByte = SST25V_ByteRead(0xFFEEEE);             //读取0xFFEEEE地址空间的数据信息
  DataByte = SST25V_ByteRead(0xFFFFFF);             //读取0xFFFFFF地址空间的数据信息
 
 
 
  //SST25V_BufferWrite(Tx_Buffer,0xFFF000,16);      //将Tx_Buffer中的16个字节数据写入以0xFFF000为起始地址的数据空间
 
  SST25V_AAI_BufferProgram(Tx_Buffer,0xFFF000,16);  //采用AAI模式,将Tx_Buffer中的16个字节数据写入以0xFFF000为起始地址的数据空间
 
  SST25V_BufferRead(Rx_Buffer,0xFFF000,16);         //读出0xFFF000为起始地址的16字节数据,存放于Rx_Buffer中
 
  DataByte = SST25V_ByteRead(0xFFEEEE);             //读取0xFFEEEE地址空间的数据信息
 
  while (1)
  {
    if(Rx_Buffer[0]==0x72)
    {
      GPIO_WriteBit(GPIOC,GPIO_Pin_6,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_6)));
      delay(100);
    }
   
    if(Rx_Buffer[1]==0x62)
    {
      GPIO_WriteBit(GPIOC,GPIO_Pin_7,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_7)));
      delay(100);
    }
   
    if(Rx_Buffer[2]==0x02)
    {
      GPIO_WriteBit(GPIOC,GPIO_Pin_4,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_4)));
      delay(100);
    }
   
    if(Rx_Buffer[3]==0x78)
    {
      GPIO_WriteBit(GPIOC,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_5)));
      delay(100);
    }
   
  }
}
void delay(int d)
{
  int i = 0;
  for ( ;d;--d)
  for (i = 0;i<10000;i++);
}

 

SST25VF.c:

#include "stm32f10x_lib.h"
#include "SST25V.h"

void SST25V_Init(void)   //Flash芯片初始化
{
  SST25V_CS_HIGH();                   //片选CS#管脚置高--不选中芯片
  SST25V_WP_HIGH();                   //保护WP#管脚置高--BPL的状态决定是否允许写状态寄存器
  SST25V_HOLD_HIGH();                 //保持HOLD#管脚置高
  SST25V_WriteStatusRegister(0x02);   //给状态寄存器写入数据02
  SST25V_DBSY();                      //禁止AAI模式时,SO脚输出忙状态
}

u8 SST25V_ByteRead(u32 ReadAddr)     //从ReadAddr地址读取一个字节数据
{
  u8 Temp = 0;
  SST25V_CS_LOW();                                  //片选端置低--选中芯片
  SPI_Flash_SendByte(Read_Data);                    //发送读取数据命令
  SPI_Flash_SendByte((ReadAddr & 0xFF0000) >> 16);  //发送24位的读取数据地址
  SPI_Flash_SendByte((ReadAddr& 0xFF00) >> 8);
  SPI_Flash_SendByte(ReadAddr & 0xFF);
 
  Temp = SPI_Flash_ReceiveByte();                   //接收读取到的数据
  SST25V_CS_HIGH();                                 //片选CS#管脚置高--不选中芯片
  return Temp;                                      //返回读取到的数据
}

void SST25V_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)//从ReadAddr地址开始读取NumByteToRead个字节数据
{
  SST25V_CS_LOW();                                  //片选端置低--选中芯片
  SPI_Flash_SendByte(Read_Data);                    //发送读取数据命令
  SPI_Flash_SendByte((ReadAddr & 0xFF0000) >> 16);  //发送24位的读取数据起始地址
  SPI_Flash_SendByte((ReadAddr& 0xFF00) >> 8);
  SPI_Flash_SendByte(ReadAddr & 0xFF);

  while(NumByteToRead--)                  //判断是否完成读取NumByteToRead个字节数据
  {
    *pBuffer = SPI_Flash_ReceiveByte();   //接受读取到的数据,并存储于pBuffer中
    pBuffer++;                            //pBuffer指针自增1
  }
  SST25V_CS_HIGH();                       //片选CS#管脚置高--不选中芯片
}

u8 SST25V_HighSpeedByteRead(u32 ReadAddr)  //从ReadAddr高速读取一个字节数据
{
  u32 Temp = 0;
  SST25V_CS_LOW();                                   //片选端置低--选中芯片
  SPI_Flash_SendByte(HighSpeedReadData);             //发送快速读取数据命令
  SPI_Flash_SendByte((ReadAddr & 0xFF0000) >> 16);   //发送24位的读取数据地址
  SPI_Flash_SendByte((ReadAddr& 0xFF00) >> 8);
  SPI_Flash_SendByte(ReadAddr & 0xFF);
  SPI_Flash_SendByte(Dummy_Byte);                    //发送虚拟字节数据
  Temp = SPI_Flash_ReceiveByte();                    //接收读取到的数据
  SST25V_CS_HIGH();                                  //片选CS#管脚置高--不选中芯片
  return Temp;                                       //返回读取到的数据
}

void SST25V_HighSpeedBufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)//从ReadAddr开始高速读取NumByteToRead个字节数据,并存储于pBuffer中
{
  SST25V_CS_LOW();                                   //片选端置低--选中芯片
  SPI_Flash_SendByte(HighSpeedReadData);             //发送快速读取数据命令
  SPI_Flash_SendByte((ReadAddr & 0xFF0000) >> 16);   //发送24位的读取数据起始地址
  SPI_Flash_SendByte((ReadAddr& 0xFF00) >> 8);
  SPI_Flash_SendByte(ReadAddr & 0xFF);
  SPI_Flash_SendByte(Dummy_Byte);                    //发送虚拟字节数据

  while(NumByteToRead--)                             //判断是否完成读取NumByteToRead个字节数据
  {
    *pBuffer = SPI_Flash_ReceiveByte();              //接受读取到的数据,并存储于pBuffer中
    pBuffer++;                                       //pBuffer指针自增1
  }
  SST25V_CS_HIGH();                                  //片选CS#管脚置高--不选中芯片
}

u8 SPI_Flash_SendByte(u8 byte)   //SPI发送数据
{
  while(SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);     //等待SPI1的Tx buffer为空
  SPI_SendData(SPI1, byte);                                  //发送数据字节byte

  while(SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET);    //等待SPI1完成数据接收
  return SPI_ReceiveData(SPI1);                              //返回读取到的数据
}

u8 SPI_Flash_ReceiveByte(void)    //SPI接收数据
{
  return (SPI_Flash_SendByte(Dummy_Byte));    //发送虚拟字节,提供接收数据时钟
}

void SST25V_ByteWrite(u8 Byte, u32 WriteAddr)   //写入一个数据字节
{
  SST25V_WriteEnable();                                //允许写入操作
  SST25V_CS_LOW();                                     //片选端置低--选中芯片
  SPI_Flash_SendByte(Byte_Program);                    //发送写数据命令
  SPI_Flash_SendByte((WriteAddr & 0xFF0000) >> 16);    //发送24位的写入数据地址
  SPI_Flash_SendByte((WriteAddr & 0xFF00) >> 8);
  SPI_Flash_SendByte(WriteAddr & 0xFF);
 
  SPI_Flash_SendByte(Byte);                            //发送要写入的数据
  SST25V_CS_HIGH();                                    //片选CS#管脚置高--不选中芯片
  SST25V_WaitForWriteEnd();                            //等待写操作完成
}

void SST25V_BufferWrite(u8 *pBuffer,u32 Addr,u16 BufferLength)//将pBuffer中的BufferLength个字节数据写入到以Addr为起始地址的区域
{
  while(BufferLength--)                   //判断是否完成写入NumByteToRead个字节数据
  {
    SST25V_ByteWrite(*pBuffer,Addr);     //把当前pBuffer对应的数据,写入当前Addr中
    pBuffer++;                           //数据指针自增1
    Addr++;                              //写入地址自增1
  }
}
[page]
void SST25V_WriteBytes(u8 Byte, u32 WriteAddr,u32 ByteLength)  //以WriteAddr为起始地址,写入ByteLength个数据Byte(写入的是同一个数据Byte)
{
    while(ByteLength--)                  //判断是否完成写入NumByteToRead个字节数据
  {
    SST25V_ByteWrite(Byte,WriteAddr);    //向WriteAddr中写入数据字节Byte
    WriteAddr++;                         //写入地址自增1
  }
}

void SST25V_AAI_WriteBytes(u8 Byte, u32 Addr,u32 ByteLength)//以Addr为起始地址,用AAI模式,写入ByteLength个数据Byte(写入的是同一个数据Byte)ByteLength必须为偶数
{
  u32 Length = 0;
  Length = (ByteLength/2)-1;                       //AAI模式每次写入两字节数据,因此ByteLength各字节,分成Length次写入
  SST25V_WriteEnable();                            //允许写入操作
  SST25V_CS_LOW();                                 //片选端置低--选中芯片
  SPI_Flash_SendByte(AAI_WordProgram);             //发送AAI模式写入命令
  SPI_Flash_SendByte((Addr & 0xFF0000) >> 16);     //发送24位的写入数据地址
  SPI_Flash_SendByte((Addr & 0xFF00) >> 8);
  SPI_Flash_SendByte(Addr & 0xFF);
  SPI_Flash_SendByte(Byte);                       //写入第一个字节数据
  SPI_Flash_SendByte(Byte);                       //写入第二个字节数据
  SST25V_CS_HIGH();                               //片选CS#管脚置高--不选中芯片
  SST25V_WaitForWriteEnd();                       //等待写操作完成
 
  while(Length--)                                 //判断是否完成Length次写入
  {
    SST25V_CS_LOW();                              //片选端置低--选中芯片
    SPI_Flash_SendByte(AAI_WordProgram);          //发送AAI模式写入命令
    SPI_Flash_SendByte(Byte);                     //写入第一个字节数据
    SPI_Flash_SendByte(Byte);                     //写入第二个字节数据
    SST25V_CS_HIGH();                             //片选CS#管脚置高--不选中芯片
    SST25V_WaitForWriteEnd();                     //等待写操作完成
  }
  SST25V_WriteDisable();                         //写入完成,退出AAI模式
}


void SST25V_AAI_BufferProgram(u8 *pBuffer,u32 Addr,u16 BufferLength)//用AAI模式将pBuffer中的BufferLength个字节数据写入到以Addr为起始地址的区域,ByteLength必须为偶数
{
  u16 Length = 0;
  Length = (BufferLength/2)-1;                     //AAI模式每次写入两字节数据,因此ByteLength各字节,分成Length次写入
 
  SST25V_WriteEnable();                           //允许写入操作
  SST25V_CS_LOW();                                //片选端置低--选中芯片
  SPI_Flash_SendByte(AAI_WordProgram);            //发送AAI模式写入数据命令
  SPI_Flash_SendByte((Addr & 0xFF0000) >> 16);    //发送24位的写入数据起始地址
  SPI_Flash_SendByte((Addr & 0xFF00) >> 8);
  SPI_Flash_SendByte(Addr & 0xFF);
 
  SPI_Flash_SendByte(*pBuffer);                  //写入数据
  pBuffer++;                                     //数据指针加1
  SPI_Flash_SendByte(*pBuffer);                  //写入数据
  pBuffer++;                                     //数据指针加1
 
  SST25V_CS_HIGH();                              //片选CS#管脚置高--不选中芯片
  SST25V_WaitForWriteEnd();                      //等待写操作完成
 
  while(Length--)      //判断是否完成Length次写入
  {
    SST25V_CS_LOW();                         //片选端置低--选中芯片
    SPI_Flash_SendByte(AAI_WordProgram);     //发送AAI模式写入数据命令
    SPI_Flash_SendByte(*pBuffer);            //写入数据
    pBuffer++;                               //数据指针加1
    SPI_Flash_SendByte(*pBuffer);            //写入数据
    pBuffer++;                               //数据指针加1
    SST25V_CS_HIGH();                        //片选CS#管脚置高--不选中芯片
    SST25V_WaitForWriteEnd();                //等待写操作完成
  }
  SST25V_WriteDisable();                     //写入完成,退出AAI模式
}

void SST25V_AAI_WordProgram(u8 Byte1, u8 Byte2, u32 Addr)//在AAI模式下,以Addr为起始地址,分别写入Byte1和Byte2,必须和SST25V_AAI_WordsProgram()函数配套使用
{
  SST25V_WriteEnable();                              //允许写入操作
  SST25V_CS_LOW();                                   //片选端置低--选中芯片
  SPI_Flash_SendByte(AAI_WordProgram);               //发送AAI模式写入数据命令
  SPI_Flash_SendByte((Addr & 0xFF0000) >> 16);       //发送24位的写入数据起始地址
  SPI_Flash_SendByte((Addr & 0xFF00) >> 8);
  SPI_Flash_SendByte(Addr & 0xFF);

  SPI_Flash_SendByte(Byte1);                        //写入数据Byte1
  SPI_Flash_SendByte(Byte2);                        //写入数据Byte2
 
  SST25V_CS_HIGH();                                 //片选CS#管脚置高--不选中芯片
  SST25V_WaitForWriteEnd();                         //等待写操作完成
}

void SST25V_AAI_WordsProgram(u8 state,u8 Byte1, u8 Byte2) //在AAI模式下,继续写入Byte1和Byte2,必须和SST25V_AAI_WordProgram()函数配套使用,state==1退出AAI模式
{
  SST25V_CS_LOW();                        //片选端置低--选中芯片
  SPI_Flash_SendByte(AAI_WordProgram);    //继续发送AAI模式写入数据命令

  SPI_Flash_SendByte(Byte1);              //写入数据Byte1
  SPI_Flash_SendByte(Byte2);              //写入数据Byte2

  SST25V_CS_HIGH();                       //片选CS#管脚置高--不选中芯片
  SST25V_WaitForWriteEnd();               //等待写操作完成
 
  if(state==1)                            //state==1时,退出AAI模式
  {
    SST25V_WriteDisable();
  }
}

void SST25V_SectorErase_4KByte(u32 Addr)    //擦除4KB数据空间,Addr是擦除起始地址
{
  SST25V_WriteEnable();                           //允许写入操作
  SST25V_CS_LOW();                                //片选端置低--选中芯片
  SPI_Flash_SendByte(SectorErace_4KB);            //发送擦除4KB数据空间命令
  SPI_Flash_SendByte((Addr & 0xFF0000) >> 16);    //发送24位的擦除起始地址
  SPI_Flash_SendByte((Addr & 0xFF00) >> 8);
  SPI_Flash_SendByte(Addr & 0xFF);
 
  SST25V_CS_HIGH();                               //片选CS#管脚置高--不选中芯片
  SST25V_WaitForWriteEnd();                       //等待擦除操作完成
}

void SST25V_BlockErase_32KByte(u32 Addr)         //擦除32KB数据空间,Addr是擦除起始地址
{
  SST25V_WriteEnable();                          //允许写入操作
  SST25V_CS_LOW();                               //片选端置低--选中芯片
  SPI_Flash_SendByte(BlockErace_32KB);           //发送擦除32KB数据空间命令
  SPI_Flash_SendByte((Addr & 0xFF0000) >> 16);   //发送24位的擦除起始地址
  SPI_Flash_SendByte((Addr & 0xFF00) >> 8);
  SPI_Flash_SendByte(Addr & 0xFF);
 
  SST25V_CS_HIGH();                              //片选CS#管脚置高--不选中芯片
  SST25V_WaitForWriteEnd();                      //等待擦除操作完成
}

void SST25V_BlockErase_64KByte(u32 Addr)         //擦除64KB数据空间,Addr是擦除起始地址
{
  SST25V_WriteEnable();                          //允许写入操作
  SST25V_CS_LOW();                               //片选端置低--选中芯片
  SPI_Flash_SendByte(BlockErace_64KB);           //发送擦除64KB数据空间命令
  SPI_Flash_SendByte((Addr & 0xFF0000) >> 16);   //发送24位的擦除起始地址
  SPI_Flash_SendByte((Addr & 0xFF00) >> 8);
  SPI_Flash_SendByte(Addr & 0xFF);
 
  SST25V_CS_HIGH();                              //片选CS#管脚置高--不选中芯片
  SST25V_WaitForWriteEnd();                      //等待擦除操作完成
}

void SST25V_ChipErase(void)            //擦除整个芯片数据空间
{
  SST25V_WriteEnable();                //允许写入操作
  SST25V_CS_LOW();                     //片选端置低--选中芯片
  SPI_Flash_SendByte(ChipErace);       //发送擦除整个芯片空间命令
  SST25V_CS_HIGH();                    //片选CS#管脚置高--不选中芯片
  SST25V_WaitForWriteEnd();            //等待擦除操作完成
}

u8 SST25V_ReadStatusRegister(void)    //读取状态寄存器
{
  u8 StatusRegister = 0;
  SST25V_CS_LOW();                            //片选端置低--选中芯片
  SPI_Flash_SendByte(ReadStatusRegister);     //发送读取状态寄存器命令
  StatusRegister = SPI_Flash_ReceiveByte();   //接收状态寄存器数据
  SST25V_CS_HIGH();                           //片选CS#管脚置高--不选中芯片
  return StatusRegister;                      //返回读取到的状态寄存器数据
}

void SST25V_WriteEnable(void)          //允许对芯片写入操作
{
  SST25V_CS_LOW();                     //片选端置低--选中芯片
  SPI_Flash_SendByte(WriteEnable);     //发送允许写入操作命令
  SST25V_CS_HIGH();                    //片选CS#管脚置高--不选中芯片
}

void SST25V_WriteDisable(void)         //禁止对芯片写入操作
{
  SST25V_CS_LOW();                     //片选端置低--选中芯片
  SPI_Flash_SendByte(WriteDisable);    //发送禁止写入操作命令
  SST25V_CS_HIGH();                    //片选CS#管脚置高--不选中芯片
}

void SST25V_EnableWriteStatusRegister(void)        //允许改写状态寄存器
{
  SST25V_CS_LOW();                                 //片选端置低--选中芯片
  SPI_Flash_SendByte(EnableWriteStatusRegister);   //发送允许改写状态寄存器命令
  SST25V_CS_HIGH();                                //片选CS#管脚置高--不选中芯片
}

void SST25V_WriteStatusRegister(u8 Byte)      //改写状态寄存器,向状态寄存器写入数据Byte
{
  SST25V_EnableWriteStatusRegister();         //允许改写状态寄存器
  SST25V_CS_LOW();                            //片选端置低--选中芯片
  SPI_Flash_SendByte(WriteStatusRegister);    //发送改写状态寄存器命令
  SPI_Flash_SendByte(Byte);                   //向状态寄存器写入数据Byte
  SST25V_CS_HIGH();                           //片选CS#管脚置高--不选中芯片
}

void SST25V_WaitForWriteEnd(void)     //等待写入操作完成
{
  u8 FLASH_Status = 0;
  SST25V_CS_LOW();                                 //片选端置低--选中芯片
  do
  {
    FLASH_Status = SST25V_ReadStatusRegister();    //获取状态寄存器值

  } while((FLASH_Status & 0x01) == SET);           //判断芯片是否处于忙碌状态,忙则继续读取状态寄存器的值

  SST25V_CS_HIGH();                                //片选CS#管脚置高--不选中芯片
}

u32 SST25V_ReadJedecID(void)       //读取JEDEC ID
{
  u32 JEDECID = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
  SST25V_CS_LOW();                                   //片选端置低--选中芯片
  SPI_Flash_SendByte(ReadJedec_ID);                  //发送读取JEDEC ID命令
  Temp0 = SPI_Flash_ReceiveByte();                   //接收第一字节数据
  Temp1 = SPI_Flash_ReceiveByte();                   //接收第二字节数据
  Temp2 = SPI_Flash_ReceiveByte();                   //接收第三字节数据
  SST25V_CS_HIGH();                                  //片选CS#管脚置高--不选中芯片
  JEDECID = (Temp0 << 16) | (Temp1 << 8) | Temp2;    //还原JEDEC ID
  return JEDECID;                                    //返回JEDEC ID
}

u16 SST25V_ReadManuID_DeviceID(u32 ReadManu_DeviceID_Addr) //读取ManufacturerID和DeviceID,ReadManu_DeviceID_Addr的状态决定第一个字节是DeviceID还是ManufacturerID
{
  u16 ManuID_DeviceID = 0;              //存储16位的ID数据
  u8 ManufacturerID = 0,  DeviceID = 0;
  SST25V_CS_LOW();                      //片选端置低--选中芯片
  SPI_Flash_SendByte(ReadDeviceID);     //发送读取设备ID信息命令
 
  SPI_Flash_SendByte((ReadManu_DeviceID_Addr & 0xFF0000) >> 16);   //发送24位的地址字节,该地址为0和1,分别决定先输出的是ManufacturerID还是DeviceID
  SPI_Flash_SendByte((ReadManu_DeviceID_Addr & 0xFF00) >> 8);
  SPI_Flash_SendByte(ReadManu_DeviceID_Addr & 0xFF);
 
  if(ReadManu_DeviceID_Addr==1)   //先输出DeviceID
  {
    DeviceID = SPI_Flash_ReceiveByte();         //接收DeviceID
    ManufacturerID = SPI_Flash_ReceiveByte();   //接收ManufacturerID
  }
  else   //先输出ManufacturerID
  {
    ManufacturerID = SPI_Flash_ReceiveByte();   //接收ManufacturerID
    DeviceID = SPI_Flash_ReceiveByte();         //接收DeviceID
  }
 
  ManuID_DeviceID = ((ManufacturerID<<8) | DeviceID);   //保存为16位的数据,高字节为ManufacturerID,低字节为DeviceID
  SST25V_CS_HIGH();                                     //片选CS#管脚置高--不选中芯片
 
  return ManuID_DeviceID;                               //返回16位的ManuID_DeviceID,高字节为ManufacturerID,低字节为DeviceID
}

void SST25V_EBSY()    //允许AAI模式期间,SO脚输出忙状态
{
  SST25V_CS_LOW();            //片选端置低--选中芯片
  SPI_Flash_SendByte(EBSY);   //发送允许AAI模式期间,SO脚输出忙状态命令
  SST25V_CS_HIGH();           //片选CS#管脚置高--不选中芯片
}

void SST25V_DBSY()            //禁止AAI模式期间,SO脚输出忙状态
{
  SST25V_CS_LOW();            //片选端置低--选中芯片
  SPI_Flash_SendByte(DBSY);   //发送禁止AAI模式期间,SO脚输出忙状态命令
  SST25V_CS_HIGH();           //片选CS#管脚置高--不选中芯片
}

 [page]

SST25VF.h:

#include "stm32f10x_lib.h"
#ifndef __SST25V_H
#define __SST25V_H

#define BufferSize                    (countof(Tx_Buffer)-1)
#define countof(a)                    (sizeof(a) / sizeof(*(a)))
#define SST25V_PageSize               256
#define Dummy_Byte                    0xA5

#define SST25V_CS_LOW()               GPIO_ResetBits(GPIOA, GPIO_Pin_4)
#define SST25V_CS_HIGH()              GPIO_SetBits(GPIOA, GPIO_Pin_4)

#define SST25V_WP_LOW()               GPIO_ResetBits(GPIOC, GPIO_Pin_0)
#define SST25V_WP_HIGH()              GPIO_SetBits(GPIOC, GPIO_Pin_0)

#define SST25V_HOLD_LOW()             GPIO_ResetBits(GPIOC, GPIO_Pin_1)
#define SST25V_HOLD_HIGH()            GPIO_SetBits(GPIOC, GPIO_Pin_1)

#define Read_Data                     0x03       //读取存储器数据
#define HighSpeedReadData             0x0B       //快速读取存储器数据
#define SectorErace_4KB               0x20       //扇区擦除
#define BlockErace_32KB               0x52       //32KB块擦除
#define BlockErace_64KB               0xD8       //64KB块擦除
#define ChipErace                     0xC7       //片擦除

#define Byte_Program                  0x02       //页面编程--写数据
#define AAI_WordProgram               0xAD
#define ReadStatusRegister            0x05       //读状态寄存器
#define EnableWriteStatusRegister     0x50
#define WriteStatusRegister           0x01       //写状态寄存器

#define WriteEnable                   0x06       //写使能,设置状态寄存器
#define WriteDisable                  0x04       //写禁止
#define ReadDeviceID                  0xAB       //获取设备ID信息

#define ReadJedec_ID                  0x9F       //JEDEC的ID信息

#define EBSY                          0X70       //允许AAI模式期间,SO脚输出忙状态命令
#define DBSY                          0X80       //禁止AAI模式期间,SO脚输出忙状态命令

 
void SST25V_Init(void);   //Flash芯片初始化

u8 SST25V_ByteRead(u32 ReadAddr);   //从ReadAddr地址读取一个字节数据

void SST25V_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead);  //从ReadAddr地址开始读取NumByteToRead个字节数据

u8 SST25V_HighSpeedByteRead(u32 ReadAddr);  //从ReadAddr高速读取一个字节数据

void SST25V_HighSpeedBufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead);//从ReadAddr开始高速读取NumByteToRead个字节数据,并存储于pBuffer中

u8 SPI_Flash_SendByte(u8 byte);   //SPI发送数据

u8 SPI_Flash_ReceiveByte(void);    //SPI接收数据

void SST25V_ByteWrite(u8 Byte, u32 WriteAddr);   //写入一个数据字节

void SST25V_BufferWrite(u8 *pBuffer,u32 Addr,u16 BufferLength);//将pBuffer中的BufferLength个字节数据写入到以Addr为起始地址的区域

void SST25V_WriteBytes(u8 Byte, u32 WriteAddr,u32 ByteLength);  //以WriteAddr为起始地址,写入ByteLength个数据Byte(写入的是同一个数据Byte)

void SST25V_AAI_WriteBytes(u8 Byte, u32 Addr,u32 ByteLength);  //以Addr为起始地址,用AAI模式,写入ByteLength个数据Byte(写入的是同一个数据Byte)ByteLength必须为偶数

void SST25V_AAI_BufferProgram(u8 *pBuffer,u32 Addr,u16 BufferLength);  //用AAI模式将pBuffer中的BufferLength个字节数据写入到以Addr为起始地址的区域,ByteLength必须为偶数

void SST25V_AAI_WordProgram(u8 Byte1, u8 Byte2, u32 Addr); //在AAI模式下,以Addr为起始地址,分别写入Byte1和Byte2,必须和SST25V_AAI_WordsProgram()函数配套使用

void SST25V_AAI_WordsProgram(u8 state,u8 Byte1, u8 Byte2); //在AAI模式下,继续写入Byte1和Byte2,必须和SST25V_AAI_WordProgram()函数配套使用,state==1退出AAI模式

void SST25V_SectorErase_4KByte(u32 Addr);    //擦除4KB数据空间,Addr是擦除起始地址

void SST25V_BlockErase_32KByte(u32 Addr);         //擦除32KB数据空间,Addr是擦除起始地址

void SST25V_BlockErase_64KByte(u32 Addr);         //擦除64KB数据空间,Addr是擦除起始地址

void SST25V_ChipErase(void);            //擦除整个芯片数据空间

u8 SST25V_ReadStatusRegister(void);    //读取状态寄存器

void SST25V_WriteEnable(void);          //允许对芯片写入操作

void SST25V_WriteDisable(void);         //禁止对芯片写入操作

void SST25V_EnableWriteStatusRegister(void);        //允许改写状态寄存器

void SST25V_WriteStatusRegister(u8 Byte);      //改写状态寄存器,向状态寄存器写入数据Byte

void SST25V_WaitForWriteEnd(void);     //等待写入操作完成

u32 SST25V_ReadJedecID(void);       //读取JEDEC ID

u16 SST25V_ReadManuID_DeviceID(u32 ReadManu_DeviceID_Addr); //读取ManufacturerID和DeviceID,ReadManu_DeviceID_Addr的状态决定第一个字节是DeviceID还是ManufacturerID

void SST25V_EBSY();    //允许AAI模式期间,SO脚输出忙状态

void SST25V_DBSY();            //禁止AAI模式期间,SO脚输出忙状态
#endif

 

hw_conf.c:

#include"stm32f10x_lib.h"
#include "hw_conf.h"
ErrorStatus HSEStartUpStatus;
void RCC_Configuration(void)
{
  RCC_DeInit();
  RCC_HSEConfig(RCC_HSE_ON);
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if(HSEStartUpStatus == SUCCESS)
  {
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    FLASH_SetLatency(FLASH_Latency_2);
    RCC_HCLKConfig(RCC_SYSCLK_Div1);
    RCC_PCLK2Config(RCC_HCLK_Div1);
    RCC_PCLK1Config(RCC_HCLK_Div2);
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    RCC_PLLCmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
}

void GPIO_Configuration(void)
{
  //PC4567分别接LED4,3,2,1,以便调试观察
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
 
  //PA5--SPI1_SCK    PA6--SPI1--MISO    PA7--SPI1--MOSI
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;  //Configure SPI1 pins: NSS, SCK, MISO and MOSI
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  //PA4--SPI1_NSS
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;  //Configure PA.4 as Output push-pull, used as Flash Chip select
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void SPI_configuration()  //SPI1 configuration
{
  SPI_InitTypeDef  SPI_InitStructure;
 
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;   //SPI设置为双线双向全双工
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                        //设置为主 SPI 
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                    //SPI发送接收 8 位帧结构
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                          //时钟悬空高
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                         //数据捕获于第二个时钟沿
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                            //内部 NSS 信号有 SSI位控制
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;   //波特率预分频值为 4
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                   //数据传输从 MSB 位开始
  SPI_InitStructure.SPI_CRCPolynomial = 7;                             //定义了用于 CRC值计算的多项式 7
  SPI_Init(SPI1, &SPI_InitStructure);
  SPI_Cmd(SPI1, ENABLE);                                               //Enable SPI1
}

void NVIC_Configuration(void)
{
#ifdef  VECT_TAB_RAM 
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  
#endif
}

void Setup_System(void)
{
 RCC_Configuration();
 GPIO_Configuration();
 SPI_configuration();
 NVIC_Configuration();
}

hw_conf.h:

#ifndef   _hw_conf_H_
#define   _hw_conf_H_

extern void Setup_System(void);

#endif
关键字:stm32  SST25VF 引用地址:stm32驱动SST25VF程序

上一篇:lpc2148点灯 去了n小时
下一篇:基于Boa-web服务器的远程机器人控制(网络篇)

推荐阅读最新更新时间:2024-03-16 14:24

CLion配置STM32开发环境
一、前言   上一篇文章介绍了VSCode配置STM32的开发环境,本文将介绍使用CLion配置STM32的开发环境,很多喜欢稚晖君的小伙伴,都知道稚晖君使用的是CLion开发STM32,并且稚晖君的知乎上也有介绍CLion配置STM32的开发环境的文章。我针对我的使用情况,对我遇到的一些问题做一下总结,并且展示解决的办法。本次介绍的也是HAL库开发。B话不多说,开干~ 二、软件及环境准备 1、CLion2021.3.3   官网下载地址: CLion: A Cross-Platform IDE for C and C++ by JetBrains ,CLion是收费软件,解决办法如下:   a、购买CLion正版授权,199美刀
[单片机]
stm32专题十八:详细分析SPI FLASH
这里使用的SPI FLASH型号为W25Q64,是一种NOR FLASH。容量为64M bit = 8M Byte(8M 字节),而AT24C02 EEPROM才只有256字节,存储容量简直不是一个量级,这个FLASH和stm32内部的FLASH性质一样,适合存储语音、文本和数据。 W25Q64BV阵列分为32,768个可编程页面,每页256字节。 一次最多可编程256个字节。 可以以16个组(4KB扇区擦除),128个组(32KB块擦除),256个组(64KB块擦除)或整个芯片(芯片擦除)的组擦除页面。 W25Q64BV分别具有2,048个可擦除扇区和128个可擦除块。 小的4KB扇区允许在需要数据和参数存储的应用中具有更大
[单片机]
<font color='red'>stm32</font>专题十八:详细分析SPI FLASH
stm32库应用】SD驱动移植(基于SDIO外设)
来处理下SD卡这个东西(后期还将做fatfs文件系统移植) 图1 SD接口图 图1 的接口图不是完全正确的,每个PIN上都必须接一个50K的上拉电阻; 在ST官方提供的库里面有很多意见做好的外设,LCD,EEPROM,等等,当然我们比较幸运,也包括SD卡,这次移植基于3.5的库 我们要移植的文件在这个STM32F10x_StdPeriph_Lib_V3.5.0UtilitiesSTM32_EVAL下: 图2 移植需要的文件 因为我的板子是stm32f103vet6跟STM3210E_EVAL比较相近,所以选这个; 图3 common目录 把stm32_eval_spi_sd.c / stm32_ev
[单片机]
【<font color='red'>stm32</font>库应用】SD驱动移植(基于SDIO外设)
STM32单片机串口通讯代码
简介:在STM32开发中,串口是我们最常用的接口。通过串口,我们很方便地把数据输出到电脑,方便我们进行程序调试。下面我们来看看STM32的串口通讯代码。 要实现串口通讯,我们要进行下面几个步骤: 首先:要打开GPIO口的时钟和串口模块时钟。在圆点博士小四轴中,我们用的是GPIOA和COM1模块。 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 其次:要指定GPIO口,即确定哪些IO是用于串口通讯的。记得使用GPIO_Mode_AF_PP模式
[单片机]
单片机之STM32 中的 assert_param 函数
我们在学STM32的时候函数assert_param出现的几率非常大,上网搜索一下,网上一般解释断言机制,做为程序开发调试阶段时使用。下面我就谈一下我对这些应用的看法,学习东西抱着知其然也要知其所以然。 4 断言机制函数assert_param 我们在分析库函数的时候,几乎每一个函数的原型有这个函数assert_param();下面以assert_param(IS_GPIO_ALL_PERIPH(GPIOx));为例说一下我的理解,函数的参数IS_GPIO_ALL_PERIPH(GPIOx),我们可以寻找到原型 #define IS_GPIO_ALL_PERIPH(PERIPH) (((*(uint32_t*)&(PERIPH))
[单片机]
单片机之<font color='red'>STM32</font> 中的 assert_param 函数
学习笔记之 STM32单片机
1、 AHB系统总线分为APB1(36MHz)和APB2(72MHz),其中2 1,意思是APB2接高速设备 2、 Stm32f10x.h相当于reg52.h(里面有基本的位操作定义),另一个为stm32f10x_conf.h专门控制外围器件的配置,也就是开关头文件的作用 3、 HSE Osc(High Speed External Oscillator)高速外部晶振,一般为8MHz,HSI RC(High Speed InternalRC)高速内部RC,8MHz 4、 LSE Osc(Low Speed External Oscillator)低速外部晶振,一般为32.768KHz,LSI RC(Low Speed Intern
[单片机]
STM32自学笔记——复用重映射
端口复用 什么事端口复用: STM32有很多的内置外设,这些外设的外部引脚都是与GPIO复用的。也就是说,一个GPIO如果可以复用为内置外设的功能引脚,那么当这个GPIO作为内置外设使用的时候,就叫做复用。 如何使用: 1.使能GPIO时钟 2.使能复用功能的时钟 3.依据数据手册设置GPIO口数据 eg. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//①IO时钟使能RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//②外设时钟使能//③初始化IO为对应的模式GPIO_InitStructure.GPIO_P
[单片机]
STM32外部中断执行过程
一、MCU中断程序执行过程 以MCU裸机程序框架为例,MCU 的主函数是个死循环: 主函数: main(void) { While(1) { //主程序 } } 如果没有中断或异常产生会一直在while(1)里执行主程序代码。当中断产生后,当前执行的任务会被打断,程序跳转到中断处理函数执行,执行完会返回之前的主程序断点处继续执行。 中断处理函数: void IRQ_handler(void) { //中断处理程序 //清除中断标志,否则会不停的进入中断处理程序。 } 在中断处理函数中不要做复杂费时的事情,中断内做的事情尽可能少。 二、中断使用实例 STM32的IO都可以配置成外部中断,但不是同时都可以配成外部中断。需要遵循如下
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved