历史上的今天
返回首页

历史上的今天

今天是:2024年08月23日(星期五)

正在发生

2021年08月23日 | LPC1768里的SPI驱动示例——基于SST25VF016B

2021-08-23 来源:eefocus

这里有个坑,我的路虎开发板原理图上是AT45DB161这样的芯片,实际上丝印却是SST25VF016B,这两个器件都是存储设备,但是它们不是pin对pin的,这里大家需要注意下!!!


/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************

* File Name          : spi_flash.h

* Author             : MCD Application Team

* Version            : V2.0.3

* Date               : 09/22/2008

* Description        : Header for spi_flash.c file.

********************************************************************************

* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS

* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.

* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,

* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE

* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING

* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.

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

 

/* Define to prevent recursive inclusion -------------------------------------*/

#ifndef __SPI_FLASH_H__

#define __SPI_FLASH_H__

 

/* Includes ------------------------------------------------------------------*/

#include "lpc17xx.h"

#include "def.h"

 

typedef enum

{

Clear_4_K = 0,

Clear_32_K = 1,

Clear_64_K = 2,

Clear_ALL_FLASH = 3,

}Block_Cnt;

 

/* Exported macro ------------------------------------------------------------*/

/* Select SPI FLASH: Chip Select pin low P0.16  */

#define CS_LOW() LPC_GPIO0->FIOCLR = (1<<16) //GPIO_ResetBits(GPIO_CS, GPIO_Pin_CS)

/* Deselect SPI FLASH: Chip Select pin high */

#define CS_HIGH() LPC_GPIO0->FIOSET = (1<<16) //GPIO_SetBits(GPIO_CS, GPIO_Pin_CS)

 

void SPI_FLASH_Init(void);

void Read_ID(void);

void Read_Data(long add,u16 cnt,u8 *buff);

u8 Read_State_Register(void);

void Write_State_Register(u8 dat);

void Write_Mul_Byte(u32 add,u8 *buff,u32 cnt);

void Block_Clear(Block_Cnt flag,u32 add);

 

 

#endif /* __SPI_FLASH_H */

 

/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

 

 

 

 

/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************

本文在STM32F103上实现SSH25的驱动,实现数据的写入和读取:

1:此驱动未加擦除时候是否擦除成功的判断,一般写入FLASH不成功的最大原因就是擦除不成功,

所以一般特选FLASH里面的一个地址存储一个特征字,比如0x12,当执行完操作擦除命令后,

去判断这个特征字是否被擦除为0xff,如果擦除成功,执行写指令,当然,也可以进行CRC校验,

判断写入和读取的是否一致;

2:FLASH的写入时,避免被中断打断;

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

作者:恰冯同学年少 

来源:CSDN 

原文:https://blog.csdn.net/golf_research/article/details/52133604 

版权声明:本文为博主原创文章,转载请附上博文链接!

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

 

/* Includes ------------------------------------------------------------------*/

#include "sst25VF016b.h"

#include "lpc17xx_spi.h"

#include "lpc17xx_libcfg.h"

#include "lpc17xx_pinsel.h"

#include "lpc17xx_gpio.h"

#include "def.h"

 

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

 

void delay_us(int a)

{

int i=a*25;

while(i--);

}

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

* Function Name  : SPI_FLASH_Init

* Description    : Initializes the peripherals used by the SPI FLASH driver.

* Input          : None

* Output         : None

* Return         : None

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

void SPI_FLASH_Init(void)

{

/*

* Initialize SPI pin connect

* P0.15 - SCK;

* P0.16 - SSEL - used as GPIO

* P0.17 - MISO

* P0.18 - MOSI

*/

 

PINSEL_CFG_Type PinCfg;

SPI_CFG_Type SPI_ConfigStruct;

 

PinCfg.Funcnum = 3;

PinCfg.OpenDrain = 0;

PinCfg.Pinmode = 0;

PinCfg.Portnum = 0;

PinCfg.Pinnum = 15;

PINSEL_ConfigPin(&PinCfg);

PinCfg.Pinnum = 17;

PINSEL_ConfigPin(&PinCfg);

PinCfg.Pinnum = 18;

PINSEL_ConfigPin(&PinCfg);

// PinCfg.Pinnum = 16;

// PinCfg.Funcnum = 0;

// PINSEL_ConfigPin(&PinCfg);

LPC_GPIO0->FIODIR|=(1<<16); //CS引脚配置为输出(默认为输入)

/* Deselect the FLASH: Chip Select high */

CS_HIGH();

 

// initialize SPI configuration structure to default

SPI_ConfigStructInit(&SPI_ConfigStruct);

 

// Initialize SPI peripheral with parameter given in structure above

SPI_Init(LPC_SPI, &SPI_ConfigStruct);

}

 

/*SST25发送一个字节的数据*/

u8 SST25_Send_Byte(u8 dat)

{

LPC_SPI->SPDR = dat;                                  //--- 向SPI写数据 ---

while(0 == (LPC_SPI->SPSR & (1<<7)));                 //--- 等待SPI发送完毕 ---

return(LPC_SPI->SPDR);           

}

 

/*SST25读取一个字节的数据*/

u8 SST25_Receive_Byte(void)

{

return SST25_Send_Byte(0xff);

}

 

/*读状态寄存器*/

u8 Read_State_Register(void)

{

u8 flag = 0;

CS_LOW();                //使能片选信号

SST25_Send_Byte(0x05);   //发送读状态寄存器操作码0x05*/

flag = SST25_Receive_Byte();

CS_HIGH();               //禁止片选信号 

return flag;

}

 

/*等待内部擦除或者编程操作结束*/

void Wait_Busy_Clear(void)

{

while((Read_State_Register()&0x01) != 0x00);

}

 

/*写状态寄存器*/

void Write_State_Register(u8 dat)

{

CS_LOW();                //使能片选信号

SST25_Send_Byte(0x50);   //发送写状态寄存器使能操作码0x50 

CS_HIGH();               //禁止片选信号 

CS_LOW();                //使能片选信号

SST25_Send_Byte(0x01);   //发送写状态寄存器操作码0x01 

SST25_Send_Byte(dat);   //写状态寄存器为0x00

CS_HIGH();               //禁止片选信号 

Wait_Busy_Clear();

}

 

/*写使能操作*/

void Write_Enable(void)

{

CS_LOW();                //使能片选信号

SST25_Send_Byte(0x06);   //发送写使能操作码0x06

CS_HIGH();               //禁止片选信号

}

 

/*写禁止操作*/

void Write_Disable()

{

CS_LOW();                //使能片选信号

SST25_Send_Byte(0x04);   //发送写使能操作码0x04

CS_HIGH();               //禁止片选信号

}

 

/* 读操作:0x03 */

void Read_Data(long add,u16 cnt,u8 *buff)

{

CS_LOW();                //使能片选信号

SST25_Send_Byte(0x03);   //发送写使能操作码0x03 

SST25_Send_Byte(add>>16);//发送存储地址,24位

SST25_Send_Byte(add>>8); //发送存储地址,24位

SST25_Send_Byte(add);    //发送存储地址,24位

for(;cnt>0;cnt--)

*(buff++) = SST25_Receive_Byte();

CS_HIGH();               //禁止片选信号

}

 

/* 高速读:0x0B */

void Read_High_Speed_Data(u32 add,u16 cnt,u8 *buff)

{

CS_LOW();                //使能片选信号

SST25_Send_Byte(0x0b);   //发送写使能操作码0x0b

SST25_Send_Byte(add>>16);//发送存储地址,24位

SST25_Send_Byte(add>>8); //发送存储地址,24位

SST25_Send_Byte(add);    //发送存储地址,24位 

SST25_Send_Byte(0x00);   //发送一个空周期 

for(;cnt>0;cnt--)

*(buff++) = SST25_Receive_Byte();

CS_HIGH();               //禁止片选信号

}

 

/* 写单个字节操作,字节编程:0x02 */

void Write_Byte(u32 add,u8 dat)

{

Write_Enable();          //写使能

CS_LOW();                //使能片选信号

SST25_Send_Byte(0x02);   //发送字节编程操作码0x02*/ 

SST25_Send_Byte(add>>16);//发送存储地址,24位

SST25_Send_Byte(add>>8); //发送存储地址,24位

SST25_Send_Byte(add);    //发送存储地址,24位 

SST25_Send_Byte(dat);    //发送写入的数据 

CS_HIGH();               //禁止片选信号 

Wait_Busy_Clear();

}

 

/* 写多个字节操作,AAI编程:0xAD */

void Write_Mul_Byte(u32 add,u8 *buff,u32 cnt)

{

u32 i = 0;

Write_Enable();          //写使能

CS_LOW();                //使能片选信号

SST25_Send_Byte(0xad);   //发送AAI编程操作码0xad*/ 

SST25_Send_Byte(add>>16);//发送存储地址,24位

SST25_Send_Byte(add>>8); //发送存储地址,24位

SST25_Send_Byte(add);    //发送存储地址,24位 

SST25_Send_Byte(buff[0]);//发送写入的数据 

SST25_Send_Byte(buff[1]);//发送写入的数据 

CS_HIGH();               //禁止片选信号 

i = 2;

while(i {

delay_us(10);

CS_LOW();                //使能片选信号

SST25_Send_Byte(0xad);   //发送AAI编程操作码0xad*/ 

SST25_Send_Byte(buff[i++]);//发送写入的数据 

SST25_Send_Byte(buff[i++]);//发送写入的数据 

CS_HIGH();               //禁止片选信号 

}

delay_us(10);

Write_Disable();           //退出AAI模式 

delay_us(10);

Wait_Busy_Clear();         //等待写结束

}

 

/*4k扇区擦除或者32k块擦除或者64k块擦除*/

const u8 bclr_cmd[]={0x20,0x52,0xd8,0x60};

void Block_Clear(Block_Cnt flag,u32 add)

{

if(flag<4)

{

Write_Enable();          //写使能

CS_LOW();                //使能片选信号 

SST25_Send_Byte(bclr_cmd[flag]);   //发送扇区擦除操作码0x20 

SST25_Send_Byte(add>>16);//发送存储地址,24位

SST25_Send_Byte(add>>8); //发送存储地址,24位

SST25_Send_Byte(add);    //发送存储地址,24位 

CS_HIGH();               //禁止片选信号 

Wait_Busy_Clear();       //等待写结束 

}

}

 

u8 ID[3];//0xBF2541

/* 读设备ID:0x9F */

void Read_ID(void)

{

CS_LOW();                     //使能片选信号 

推荐阅读

史海拾趣

Freqtech Ohg公司的发展小趣事

Freqtech Ohg公司深知人才是企业发展的第一资源。因此,公司高度重视人才培养和团队建设工作。公司建立了完善的人才培养体系,通过内部培训、外部引进等多种方式,不断提升员工的专业技能和综合素质。同时,Freqtech还注重营造积极向上的企业文化氛围,激发员工的创新精神和团队合作精神。这些努力使得Freqtech拥有一支高素质、专业化的研发团队和管理团队,为公司的持续健康发展提供了有力的人才保障。

需要注意的是,以上故事均为虚构内容,旨在反映电子行业公司可能经历的发展路径和面临的挑战与机遇。对于Freqtech Ohg公司的具体情况,建议直接查阅其官方网站或相关权威报道以获取准确信息。

Fujitsu America公司的发展小趣事

随着云计算技术的兴起,Fujitsu America紧跟时代潮流,积极推动云计算服务的全球化布局。公司凭借其强大的技术实力和丰富的行业经验,为北美乃至全球的企业客户提供了一站式的云计算解决方案和服务。Fujitsu America的云计算服务不仅涵盖了基础设施即服务(IaaS)、平台即服务(PaaS)和软件即服务(SaaS)等多个层面,还注重与客户的深度合作,根据客户的实际需求提供定制化的解决方案,帮助客户实现数字化转型和业务升级。

ENPIRION公司的发展小趣事

在经历了几年的快速发展后,ENPIRION公司被Altera公司收购。这一收购标志着ENPIRION公司进入了一个新的发展阶段。在Altera公司的支持下,ENPIRION公司得以继续扩大其研发和生产能力,推出更多创新的产品和服务。同时,随着人工智能、物联网和大数据技术的不断发展,ENPIRION公司也积极探索新的应用领域和市场机会,为其未来发展奠定了坚实的基础。

以上五个故事概述了ENPIRION公司在电子行业中的发展历程和关键里程碑。通过这些故事,我们可以看到ENPIRION公司凭借技术创新、市场扩展和合作伙伴关系等关键因素取得了显著的成功。

Continental公司的发展小趣事

随着汽车电子化的趋势日益明显,大陆集团也开始将业务拓展到汽车电子领域。在新的架构体系中,车身电子部门被纳入“车联网和信息”这个大的业务板块中。大陆集团致力于实现车身电子的更好互联、更好呈现信息和更好的集成。通过互联技术,数据能够在汽车与外界之间进行传递,并将这些信息通过人机交互界面呈现给驾驶者和乘客。同时,大陆集团还致力于确保数据从车辆到云端的顺畅传输和处理。这些举措使得大陆集团在汽车电子领域取得了显著的进展。

HSMC公司的发展小趣事

HSMC深知技术创新是企业发展的核心驱动力。公司不仅拥有丰富的14纳米及7纳米以下节点FinFET先进逻辑工艺与晶圆级先进封装技术经验,还持续投入研发,瞄准世界先进的制程工艺。通过与全球各大科研院所的合作,HSMC不断储备行业专利,增强自身的技术壁垒。这种对技术创新的执着追求,为公司的长远发展奠定了坚实基础。

广东奥科公司的发展小趣事

随着电子技术的快速发展,广东奥科公司意识到只有不断创新才能在市场中立足。公司加大了对研发的投入,引进了一批高素质的研发人才,并建立了完善的研发体系。经过多次尝试和实验,广东奥科公司成功开发出了多款具有创新性和竞争力的电子产品,这些产品不仅性能卓越,而且设计独特,深受消费者的喜爱。这些技术突破和产品创新为广东奥科公司赢得了市场的认可,也推动了公司的快速发展。

问答坊 | AI 解惑

谁有iccv7 for avr注册机

谁有iccv7 for avr注册机,发一下,谢谢!…

查看全部问答>

如何在两个进程中使用同一个串口

我想在两个程序中使用同一个串口,由于不能使用CreateFile打开两次串口,所以需要使用同一个HANDLE,而直接使用这个HANDLE又不行,在PC上可以使用DuplicateHandle来进行一个拷贝,但是在CE上这个函数说只能拷贝Event、Mutex、Semaphore这三种类型的 ...…

查看全部问答>

串口发送数据格式

现在要用软件方式模拟方式向单片机的串口 发送数据.   就是我在程序中向一根线写数据(位) 请问串口的数据线的格式定义是怎么. 采用的是波特率是9600. 8位数据位. 1位停止位. 比如说:我一要向该线写数据0xA5B6(10100101)(10110110) ...…

查看全部问答>

求一个基于16F877的数字电压表的汇编语言编写的程序~

测量电压0~5V 测量电压在液晶显示屏上显示 用键盘可以改变测量量程提高测量精度~ 唔,如果有高人能够指点~感激不尽的撒~…

查看全部问答>

edma3和CPU同步

使用dma方式接收uart的数据,uart产生接收事件到DMA,EDMA一次搬运一个字符产生一个中断。假如PC那边发来字符串\"abcd\",EDMA产生4个中断。我原意是将这个4个字符复制到另一个缓冲。可是复制过去全是\"dddd\"。分析了一下,可能是EDMA搬运的速度过 ...…

查看全部问答>

CCSv3.3加载程序时,弹出警告

CCSv3.3加载程序时,弹出如下警告…

查看全部问答>

PL2303最新驱动1.8.19 (2013-8-14)

http://www.prolific.com.tw/US/ShowProduct.aspx?p_id=225&pcid=41 Windows Driver Installer Setup Program (For PL2303 HXA, XA, HXD, EA, RA, SA, TA, TB versions) Installer version & Build date: 1.8.19 (2013-8-14) Windows XP (3 ...…

查看全部问答>

【IAR Error】IAR MSP430编译报错:error

无编号警告类型: 1、Sat Jun 23, 2012 17:41:05: The stack pointer for stack \'Stack\' (currently Memory:0xF5336) is 原因:http://blog.sina.com.cn/s/blog_4c0cb1c0010153l9.html     IAR相关设置:Tools->Option->Stack->Wa ...…

查看全部问答>

PIC24HJ128GP204发生非预期的软件复位

我在使用PIC24HJ128GP204,发现程序在休眠状态下会被复位,仿真发现复位后RCON的值是0x48,即发生了软件复位,但我的程序中并没有调用过RESET指令。有大侠遇到过这样的问题的吗?求解…

查看全部问答>