SST25VF080B SPI接口FLASH STM32驱动

发布者:创意火舞最新更新时间:2016-10-04 来源: eefocus关键字:SST25VF080B  SPI接口  FLASH  STM32驱动 手机看文章 扫描二维码
随时随地手机看文章
所有的FLASHA 都一样只能从1变0,要想从0变1 只有擦除一个页扇, SST25VF080B 最小可以擦除4KB的页 速度也不错 50MHz 容量1MB 挺够用的 10万次的擦写寿命。最低2.7V 就可正常工作。
Flexible Erase Capability
– Uniform 4 KByte sectors
– Uniform 32 KByte overlay blocks
– Uniform 64 KByte overlay blocks
 先记下 这些个7788的命令
SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

SST25VF080B 的各种命令比较繁琐SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

Status Register这个设置写保护多点 我这里只用它的判忙BUSY

SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

一样先配置SPI与GPIO口 上图~~SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

在这也就是CE有用片选嘛~~

#define SST_SELECT()  GPIO_ResetBits(GPIOC, GPIO_Pin_13)       /* SST CS = L */ 
       #define SST_DESELECT()  GPIO_SetBits(GPIOC, GPIO_Pin_13)         /* SST CS = H */

 

/***********************************************
**函数名:FLASH_SPI_Config
**功能:初始化串行FLASH的SPI接口
**注意事项:串行FLASH使用了SPI1接口
***********************************************/
void FLASH_SPI_Config(void)
{
    SPI_InitTypeDef  SPI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC  |
            RCC_APB2Periph_AFIO |
            RCC_APB2Periph_SPI1,
            ENABLE);

    /* SCK, MISO and MOSI  A5=CLK,A6=MISO,A7=MOSI*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /*  PC.13 作片选*/
 GPIO_SetBits(GPIOC, GPIO_Pin_13); //预置为高
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    /* SPI1 configuration */
    SPI_Cmd(SPI1, DISABLE);             //必须先禁能,才能改变MODE
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //两线全双工
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;       //主
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;      //8位
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;        //CPOL=0 时钟悬空低
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;       //CPHA=0 数据捕获第1个
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;        //软件NSS
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;  //2分频=36M SST25VF说是50M没事
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;      //高位在前
    SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC7 我不解的是如果出错要如何处理
    
 SPI_Init(SPI1, &SPI_InitStructure);
 //SPI_SSOutputCmd(SPI1, ENABLE); //使能NSS脚可用 我这就一个SPI 器件
 SPI_Cmd(SPI1, ENABLE); 
 
}

 

/***************************************
**函数名:SPIByte
**功能:读写SPI总线
**注意事项:对于SPI来说,主机的读也需要先写,
**使用此函数,读的时候建议参数设置为0xff,写的时候则写参数.这里使用直接操作寄存器的办法实现SPI硬件层读写,是为了加快速写速度 在说LCD 的时候我用的就是库函数 比如

SPI_I2S_SendData  SPI_I2S_ReceiveData  SPI_I2S_GetFlagStatus
***************************************/
static u8 SPIByte(u8 byte)
{
 /*等待发送寄存器空*/
 while((SPI1->SR & SPI_I2S_FLAG_TXE)==RESET);
    /*发送一个字节*/
 SPI1->DR = byte;
 /* 等待接收寄存器有效*/
 while((SPI1->SR & SPI_I2S_FLAG_RXNE)==RESET);
 return(SPI1->DR);
}

 

SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

 

//咱用模式0

/*****************************************
**函数名:SSTCmd1/2/4
**功能:写一个SST命令/写一个命令后接一个数据/写一个命令后再写3个数据
**注意事项:这是一个完整的单命令操作,不返回
*****************************************/
void SSTCmd1(u8 cmd)
{
 SST_SELECT();
 SPIByte(cmd);
 SST_DESELECT();
}

void SSTCmd2(u8 cmd,u8 data)
{
 SST_SELECT();
 SPIByte(cmd);
 SPIByte(data);
 SST_DESELECT();
}

void SSTCmd4(u8 cmd,u8 *addr)
{
 SST_SELECT();
 SPIByte(cmd); //首命令
 SPIByte(*addr++);
 SPIByte(*addr++);
 SPIByte(*addr);
 SST_DESELECT();
}

 

/****************************************
**函数名:SSTCmdb1b/SSTCmd4bs
**功能:写一个SST命令,返回1字节数据/写1个命令字,3个地址字,返回多个字节
**更多使用在读出上的
****************************************/
u8 SSTCmdb1b(u8 cmd)
{
 u8 tmp;
 SST_SELECT();
 SPIByte(cmd);
 tmp=SPIByte(0xff);
 SST_DESELECT();
 return(tmp);
}
void SSTCmd4bs(u8 cmd,u8* addr,u8* data,u32 no)
{
 SST_SELECT();
 SPIByte(cmd); //首命令
 SPIByte(*addr++);
 SPIByte(*addr++);
 SPIByte(*addr);
 for(;no>0;no--)
 {
  *data++=SPIByte(0xff);
 }
 SST_DESELECT();
}

 

//命令时序复杂啊~~当然了我这为了求全都写出来了

 

常用的芯片功能

/***************************************
  SST25WREN  允许写功能
***************************************/
void SST25WREN(void)
{
 SSTCmd1(0x06);
}

/***********************************
  SST25WRDI  屏蔽写功能
***********************************/
void SST25WRDI(void)
{
 SSTCmd1(0x04);
}

SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

 

/**********************************
  SST25BY  检测忙
**********************************/
u8 SST25BY(void)
{
 u8 sta;
 sta=SSTCmdb1b(0x05);
 return(sta&0x01);
}

/***********************************
  SST25WPEN 允许软件写保护
  注意事项:25的写入比较繁琐,建议在每次操作前都取消掉写保护,操作完成后则重新允许写保护
SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

***********************************/
void SST25WPEN(void)
{
 u8 sta;
 sta=SSTCmdb1b(0x05)|0x1c;  //读出寄存器并加入保护位
 SSTCmd1(0x50);     //允许写Status Register
 SSTCmd2(0x01,sta);
}

//先消除保护位,再允许写位
void SST25WriteEn(void)
{
 u8 sta;
 sta=SSTCmdb1b(0x05)&(~0x1c); //读出寄存器并消除保护位
 SSTCmd1(0x50);     //允许写寄存器Status Register
 SSTCmd2(0x01,sta);    //写寄存器
 SSTCmd1(0x06);     //允许写
}

/********************************寄存器Status Register**********************************/

SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

就是这样实现写保护。

SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

/**********************************
  SST25ReadID 读取SST的ID 这个功能 呵呵不用多说~当然单纯的读写操作肯定用不上
**********************************/
u16 SST25ReadID(void)
{
 u8 id[3];
 u8 addr[3]={0,0,0};
 
 SSTCmd4bs(0x90,addr,id,3);
 return((id[0]<<8)+id[1]);
}

SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

/**********************************
  SST25ChipErase 刷除CHIP
**********************************/
void SST25ChipErase(void)
{
 SST25WriteEn();
 SSTCmd1(0x60);
 while(SST25BY());
 SST25WPEN();
}

SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

 

/***********************************
  SST25SectorErase  刷扇区 用的是4kb大小 假如地址在0~4095 之间那么这之间的地址都会刷除

当然我给 4096 的话4096到4096+4095 之间都会刷掉
***********************************/
void SST25SectorErase(u32 addr)
{
 u8 ad[3];
 ad[0]=(addr>>16)&0xff;
 ad[1]=(addr>>8)&0xff;
 ad[2]=addr&0xff;
 
 
 SST25WriteEn();
 
 SST_SELECT();
 SPIByte(0x20);
 SPIByte(ad[0]);
 SPIByte(ad[1]);
 SPIByte(ad[2]);
 SST_DESELECT();
 
 while(SST25BY());
// SST25WPEN();
}

 

/**********************************
  SST25ByteProgram  写一个字节*注意在此前要调用取消写保护,实际写应使用AAI,此函数在AAI中调用,用于写奇数个字节
**********************************/
void SST25ByteProgram(u32 addr,u8 byte)
{
 u8 ad[3];
 ad[0]=(addr>>16)&0xff;
 ad[1]=(addr>>8)&0xff;
 ad[2]=addr&0xff;

 SST_SELECT();
 SPIByte(0x02);
 SPIByte(ad[0]);
 SPIByte(ad[1]);
 SPIByte(ad[2]);
 SPIByte(byte);
 SST_DESELECT();
 while(SST25BY());

 

/***********************************
  SST25Write 写多个字节
***********************************/
void SST25Write(u32 addr,u8* p_data,u32 no)
{
 u8 ad[3];
 u32 cnt;
 if(no==0)
  return;
  
 SST25WriteEn();
 
 if(no==1) //no<2则应使用普通单字节方式
 {
  SST25ByteProgram(addr,*p_data);
 // SST25WPEN();
 } 
 else
 {
  cnt=no;
  
  ad[2]=(addr>>16)&0xff;
  ad[1]=(addr>>8)&0xff;
  ad[0]=addr&0xff;
  
  SST_SELECT();
  SPIByte(0xad);
  SPIByte(ad[2]);
  SPIByte(ad[1]);
  SPIByte(ad[0]);
  SPIByte(*p_data++);
  SPIByte(*p_data++);
  SST_DESELECT();
  cnt-=2;
  while(SST25BY()); //判忙
  
  //中间的双字节写
  for(;cnt>1;cnt-=2)
  {
   SST_SELECT();
   SPIByte(0xad);
   SPIByte(*p_data++);
   SPIByte(*p_data++);
   SST_DESELECT();
   while(SST25BY());  //判忙
  }
  SST25WRDI();  //WRDI用于退出AAI写模式 所谓AAI 就是地址自动加
  
  //如果有最后一个字节(no为奇数)
  if(cnt==1)
  {
   SST25WriteEn();
   SST25ByteProgram(addr+no-1,*p_data);
  }
 }
 SST25WPEN();//WP保护
}

 

SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志

//我们用的是下边这种

SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志


/*************************************
  SST25Read 高速读 对于后续带5的芯片,可调用此函数读
*************************************/
void SST25Read(u32 addr,u8* p_data,u32 no)
{
 SST_SELECT();

 SPIByte(0x0b);
 SPIByte(addr>>16);
 SPIByte(addr>>8);
 SPIByte(addr);
 SPIByte(0xff);

 for(;no>0;no--)
 *p_data++=SPIByte(0xff);
 SST_DESELECT();
}

/****************************************
SST25ReadL  低速读
****************************************/
void SST25ReadL(u32 addr,u8* p_data,u32 no)
{
 u8 ad[3];
 ad[2]=(addr>>16)&0xff;
 ad[1]=(addr>>8)&0xff;
 ad[0]=addr&0xff;
 
 SSTCmd4bs(0x03,ad,p_data,no);
}


SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志SST25VF080B SPI接口FLASH STM32驱动 - java - stm32学习日志
 
好了 所有的底层读写都做好了~!
 后面~~
 
  SST25SectorErase(0); //擦除 0~4095 地址之间的数据
  SST25Write(addr,db_sst1,64); //往addr 写入db_sst164个字节
  SST25Read(addr,db_sst1,64);  //从addr读64个字节到db_sst1
 
就这些接口常用了~~~

关键字:SST25VF080B  SPI接口  FLASH  STM32驱动 引用地址:SST25VF080B SPI接口FLASH STM32驱动

上一篇:STM32中USART的DMA 实现
下一篇:基于STM32 I2C的TMP101温度传感器的C源码

推荐阅读最新更新时间:2024-03-16 15:13

STM32入门学习笔记之外置FLASH读写实验
15.1 FLASH Flash,全名叫做Flash EEPROM Memory,即平时所说的“闪存”,它结合了ROM和RAM的长处,不仅可以反复擦除,还可以快速读取数据,STM32运行的程序其实就是存放在Flash当中,但是由于STM32的Flash一般1M左右,只能存储程序大小的数据,所以往往需要外扩Flash来存储数据,比如LCD界面当中的汉字字库,以及文件系统中读取的文件内容。 但是一般Flash的擦除次数有限制,STM32F1系列最新的文档指出,片内的FLASH擦写次数大约在1W次左右,所以一般Flash用于擦除次数不多,但是数据量很大的场合。 这个Flash读写实验我们用到的芯片是W25Q128,这是一款采用S
[单片机]
<font color='red'>STM32</font>入门学习笔记之外置<font color='red'>FLASH</font>读写实验
Microchip PIC24F dsPIC33E flash 自擦写的尿性小结
最近摸了好久,发现这个东西真的难, MHCP 这套16bit 体系flash的擦写操作,分为ICSP和RTSP两种方式,前者就是常见的官方pickit/ICD编程烧写操作时序。而后者是为bootload或者数据保存自擦写准备的,运行过程中的擦写操作。 RTSP flash读很简单,速度也很快。 但是RTSP擦写就是各种坑了。看了编程手册和datasheet发现这货在写入之前必须进行擦除操作,而擦除的最小擦除单位是一个page,不是一个row。那么一个page是多大呢,大概一千多words吧。摔QQQQ!!!! 然后,擦完了一页,就可以写入了,每次可以按row写32/64个words;也可以按双字节写,每次写一个指令
[单片机]
STM32 FSMC LCD 液晶的驱动—ILI9320
原来老早知道 STM32 具有 带4个片选的静态存储器控制器。支持CF卡、SRAM、PSRAM、NOR和NAND存储器 并行LCD接口,兼容8080/6800模式 这个其实就是FSMC 在这之前我一直使用IO口模拟8080时序感觉操作简单速度也很不错,而且ST官方上的FSMC的说明文档看得实在很晕找不到重点一直没试过FSMC。最近有机会尝试驱动驱动一块2.4的ILI9320由于要接线为了省力气直接使用了 FSMC的接法,顺便整理下写点东西出来。 我想使用12864液晶可能是每个会单片机的基本功了通常用个P0口发送8Bit数据在用一些控制线产生时钟信号,12864使用6800通信方式而小的彩色FTF 或CSTN屏流行8080通信
[单片机]
STM32驱动URM04超声波测距模块
URM04简介: URM04采用了RS485串行通信总线的架构,支持多传感器的并行工作,有着两个RS-485接口,最多支持32个超声波的并联, 内置温度传感器辅助校正距离值,同时支持温度的测量 应用场合:移动机器人,停车场,安全检测,超声波空间定位。 性能描述: 工作电源:+5V 接口方式:RS485 RS485总线通讯, 超声波距离测量: 最大距离4cm―500cm 测量范围角度: 60度 芯片型号:Atmel公司的ATmega8芯片 MAX202 MAX485 ST温度测量芯片 测量流程: 1触发超声波与温度测量指令 发送指令后,超声波开始测量,温度开始测量,无返回值 2延时30MS 超声波最大测距5米,
[单片机]
<font color='red'>STM32</font><font color='red'>驱动</font>URM04超声波测距模块
STM8L151 使用硬件SPI驱动W25Q16 Flash
SPI:有四根线的串行通信协议,允许与其他设备以半、全双工、同步、串行方式通信。 MISO:主模式输入、从模式输出线 MOSI:主模式输出、从模式输入线 CLK:时钟线 NSS:从设备选择引脚,主设备标准IO驱动,并用来区分从设备 以STM8L 驱动SPI Flash W25Q16 为例说明记录下,使用STM8L 的SPI该注意哪些地方,以及如何简单驱动W25Q16。 华邦的W25Q16 SPI Flash芯片是采用SPI接口,至于该芯片的优缺点就不说了,STM8L上有一个硬件SPI,可以很方便的来驱动W25Q16,下面就来看看该如何配置STM8L的SPI 外设。 void SPI_FLASH_Init(void) { //S
[单片机]
STM32 HAL+PWM+DMA方式驱动WS2812灯珠波形分析
1. 在DMA传送完PWM波形后不关闭PWM的DMA输出 灯珠显示效果: 灯珠会错乱显示(没有按正常设定的颜色显示) 示波器显示如下: 2. 在DMA传送完PWM波形后,在PWM传输完成后回调函数中关闭PWM的DMA输出 灯珠显示效果: 会按照设定的颜色正常显示,但灯带的起始位置会有绿色的余光(基于自己测试时使用的灯带) 示波器显示如下 3. 在DMA传送完PWM波形后,在DMA中断函数中关闭PWM的DMA输出 灯珠显示效果: 按照设定的颜色模式正常显示 示波器显示效果如下: 分析 方式1在pwm通过DMA的方式传输完成后会保持高电平,且会产生杂波,可能是导致灯珠显示错乱的主要原因. 方式2在DMA传输完成的回调函数关
[单片机]
<font color='red'>STM32</font> HAL+PWM+DMA方式<font color='red'>驱动</font>WS2812灯珠波形分析
STM32——FLASH(掉电保存)
今天使用STM32的FLASH进行保存数据,实现掉电保存的功能。 掉电保存:使用FLASH存储时,在每一次数据刷新后,进行一次存储即可。 PS:重新下载时,会刷新保存的数据。 FLASH编程思路: 写入:先执行擦除数据(页擦除||全片擦除),再进行写入操作 写入范围:0x08000000 +程序大小 写入地址 + 写入字节 = flash大小(根据芯片的数据手册可以查看) flash写入过程: 1,读FLASH_CR的LOCK 2,FLASH_SR的BSY位,是否有其他编程正在操作 3,设置FLASH_CR的PG位为1 4,指定的地址写入要编程的半字 5,等待BSY位变为0 6,读出写入的地址并验证数据 flash页擦除过程
[单片机]
盛群再推出HT68F60、HT66F60Flash MCU系列
继全新系列的Enhanced Flash MCU,I/O型的HT68Fxx系列及A/D型的HT66Fxx系列后,盛群再推出12KWords HT68F60及HT66F60系列,全系列符合工业上-40℃ ~ 85℃工作温度与高抗噪声的性能要求,搭配盛群ICP (In-Circuit Programming) 技术方案,可轻易实现成品韧体更新,全系列搭载非挥发性数据存储器(EEPROM),可于生产过程或成品运作中储存相关调校参数与数据,并且不因电源关闭而消失,可有效提高生产效能与产品弹性。 Enhanced Flash MCU系列Program Memory为12K Words,SRAM 576 Bytes,内建256 B
[单片机]
盛群再推出HT68F60、HT66F60<font color='red'>Flash</font> MCU系列
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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