FM25V20A使用记录

news/2025/1/15 8:49:29/

1.芯片简介

铁电存储器F-RAM,2Mbit(256K * 8) SPI(Up to 40 MHz)

项目有用到,做个mark,有错误请指正。

开发环境STM32F407

 

存储器地址范围00000H~3FFFFH,共2Mbit (256k * 8)bit, 

其中256k即为 256 * 1024 = 262144 个byte(0x4 00 00,因此存储器最后字节为0x3 ff ff)
               即  2Mbit

                     =(256 * 1024) * 8 个bit
                     = 262144 byte * 8bit
                     = 2097152 bit  即2Mbit

2.引脚定义及接线

引脚较少,具体可参考datasheet中引脚定义和接线注意事项。

其中WP为写入保护,我没有用到,因此拉高。

CS为片选。

HOLD用来在CPU芯片需要中断当前铁电操作,进入其他任务时使用。未使用,拉高。

 

3.寄存器相关配置

3.1 命令码

使用SPI发送相应命令码,来进行相关操作

3.2 状态寄存器

3.3 存储器地址范围

3.4 读写操作注意事项

  

MSB先写入或读取。

写入及读取操作不做详细叙述,多看datasheet。

 

3.驱动代码

3.1 FM25V20.H

#ifndef _FM25V20_H_
#define _FM25V20_H_#include "stm32f4xx.h"#define FM_CS_1     GPIO_SetBits(GPIOA, GPIO_Pin_4);//片选高
#define FM_CS_0     GPIO_ResetBits(GPIOA, GPIO_Pin_4);//片选低#define FMStartAddr 0x0000C //自定义开始使用的地址#define WREN  			0x06   //使能写
#define WRDI  			0x04   //失能写
#define RDSR  			0x05   //读状态寄存器
#define WRSR  			0x01   //写状态寄存器
#define READ  			0x03   //读数据
#define FSTRD 			0x0B   //快速读数据
#define WRITE 			0x02   //写数据
#define RDID            0x9F   //读设备ID
#define DUMMY_BYTE      0xFF   //虚拟字节void FMGetId(void);
void FM25V20_Init(void);
void FMWrite(uint8_t *buf,uint16_t size,uint32_t addr);
void FMRead(uint8_t *databuffer,uint16_t datasize,uint32_t address);#endif

3.2 FM25V20.C

void FM25V20_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;/*Enable GPIOA 片选*/RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOA, &GPIO_InitStructure);/*SPI初始化*/SPI1_Init();/*拉高片选,等待命令*/FM_CS_1; //Chip DeSelect
}//获取ID 9个字节
/*  71-16(56bits) Manufacturer ID15-13(3 bits) Family12-08(5 bits) Density07-06(2 bits) Sub05-03(3 bits) Rev02-00(3 bits) Rsvd     */
uint8_t FMID[8];//设备ID
void FMGetId(void)
{uint8_t i;FM_CS_0;                     //置CS低选中SPI1_ReadWriteByte(RDID);	   //读ID功能码for(i = 0; i < 8; i ++){FMID[i] = SPIReadByte();}FM_CS_1;                     //置CS高取消选中
}
/******************************************
** 函数名称:uint8 FMReadStatus(void)
** 功能描述:查询FM25V20状态
** 参数说明:无    
** 参数返回:返回状态字节
******************************************/
static uint8_t FMReadStatus(void)
{uint8_t status;FM_CS_0;                     //置CS低选中SPI1_ReadWriteByte(RDSR);status = SPI1_ReadWriteByte(DUMMY_BYTE);FM_CS_1;                     //置CS高取消选中return status;
}
/******************************************
** 函数名称:FMWriteEnable
** 功能描述:写使能
** 参数说明:无
** 参数返回:1-成功  0-失败
*******************************************/
static void FMWriteEnable(void)
{FM_CS_0;          //置CS低选中SPI1_ReadWriteByte(WREN);//发送写使能FM_CS_1;          //置CS高取消选中
}
/******************************************
** 函数名称:FMWriteDisable
** 功能描述:写禁能
** 参数说明:无
** 参数返回:1-成功  0-失败
*******************************************/
static void FMWriteDisable(void)
{FM_CS_0;            //置CS低选中SPI1_ReadWriteByte(WRDI);FM_CS_1;            //置CS高取消选中
}
/******************************************************************************
** 函数名称:FMWrite
** 功能描述:向指定地址写入指定数量的字节
** 参数说明:数据缓存区,字节数,起始地址
** 参数返回:无
******************************************************************************/
void FMWrite(uint8_t *buf, uint16_t size, uint32_t addr)
{uint16_t waittimes = 0;FMWriteEnable();//写使能delayus(20);//延时,采用计数法粗略延时即可if(FMReadStatus() & 0x02)//¼ì²éÊÇ·ñ³É¹¦Ê¹ÄÜд bit1-WEL  0ΪдʧÄÜ£¬1ΪдʹÄÜ{if(buf != 0){FM_CS_0;  //置CS低选中SPI1_ReadWriteByte(WRITE);SPI1_ReadWriteByte((uint8_t)(addr >> 16));SPI1_ReadWriteByte((uint8_t)(addr >> 8));SPI1_ReadWriteByte((uint8_t) addr);while(size--){SPI1_ReadWriteByte(*buf++);}while(waittimes<1000)         //等待器件写完{waittimes++;}	FM_CS_1;  //置CS高取消选中   }}FMWriteDisable();//写禁能
}/*****************************************************************
** 函数名称:FMRead
** 功能描述:从指定地址读取指定数量的字节
** 参数说明:数据缓存区,字节数,起始地址
** 参数返回:无
******************************************************************/
void FMRead(uint8_t *buf, uint16_t size, uint32_t addr)
{uint16_t i;if(buf != 0){FM_CS_0;SPI1_ReadWriteByte(READ);//读功能码SPI1_ReadWriteByte((uint8_t)(addr >> 16));//发送高位地址SPI1_ReadWriteByte((uint8_t)(addr >> 8));SPI1_ReadWriteByte((uint8_t)addr);for(i = 0; i < size; i++){buf[i] = SPI1_ReadWriteByte(DUMMY_BYTE);}FM_CS_1; //置CS高取消选中   }
}
/*****************************************************************
** 函数名称:FMFastRead
** 功能描述:快速从指定地址读取指定数量的字节
** 参数说明:数据缓存区,字节数,起始地址
** 参数返回:无
******************************************************************/
uint8_t FMFastRead(uint8_t *buf, uint16_t size, uint32_t addr)
{uint16_t i;if(buf != 0){FM_CS_0;SPI1_ReadWriteByte(FSTRD);//快速读功能码SPI1_ReadWriteByte((uint8_t)(addr >> 16));//发送高位地址SPI1_ReadWriteByte((uint8_t)(addr >> 8));SPI1_ReadWriteByte((uint8_t)addr);SPI1_ReadWriteByte(DUMMY_BYTE);//虚拟字节for(i = 0; i < size; i++){buf[i] = SPI1_ReadWriteByte(DUMMY_BYTE);}FM_CS_1; //置CS高取消选中   return 1;}return 0;
}

3.3 SPI.H

#ifndef _SPI_H_
#define _SPI_H_#include "stm32f4xx.h"void SPI1_Init(void);
uint8_t SPI1_ReadWriteByte(uint8_t TxData);#endif

3.4 SPI.C

//SPI1初始化
void SPI1_Init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;SPI_InitTypeDef  SPI_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//使能SPI1时钟//复用GPIO_PinAFConfig(GPIOA , GPIO_PinSource5, GPIO_AF_SPI1);GPIO_PinAFConfig(GPIOA , GPIO_PinSource6, GPIO_AF_SPI1);GPIO_PinAFConfig(GPIOA , GPIO_PinSource7, GPIO_AF_SPI1);//GPIOA 5 6 7 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;//PA5 6 7GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOSPI_I2S_DeInit(SPI1);SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//全双工  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//STM32为主机SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//发送接收8位帧结构SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;		//时钟空闲状态为低电平SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;	//第1个跳变沿采样SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//波特率分频值SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//MSB位开始传输SPI_InitStructure.SPI_CRCPolynomial = 7;	//CRC计算的多项式SPI_Init(SPI1, &SPI_InitStructure);  //初始化SPI_Cmd(SPI1, ENABLE); //使能
}
/*****************************************
**函数名称:SPI1_ReadWriteByte
**功能描述:SPIx读写一个字节
**参数说明:写入字节
**参数返回:读取到的字节
*****************************************/
uint8_t SPI1_ReadWriteByte(uint8_t TxData)
{uint8_t returnData;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}//等待发送区空SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个byte数据while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){} //等待接收完一个bytereturnData = SPI_I2S_ReceiveData(SPI1);return returnData;//返回读取到的值
}

4.示例

4.1 写入

将变量   uint8_t param1 = 0x01  写入到存储器0x00002字节位置

FMWrite((uint8_t *)&param1 , 1, 0x00002);

 

将变量  uint16_t param2 = 0x1122  写入到存储器0x00000开始的两个字节(及0x00000~0x00001)

FMWrite((uint8_t *)&param2 , 2, 0x00000);

4.2 读取

读取0x00000开始的3个字节到 uint8_t parambuf[3]

FMRead(parambuf, 3, 0x00000);

 

 

 

 

 

 

 


http://www.ppmy.cn/news/194728.html

相关文章

v20超级计算机,买荣耀V20还是华为P20?华为P20和荣耀V20区别对比

买荣耀V20还是华为P20&#xff1f;和采用麒麟970芯片的华为P20不同&#xff0c;荣耀手机新近推出的“荣耀V20”手机用上了麒麟980芯片。那么&#xff0c;荣耀V20和华为P20哪个更好一些&#xff1f;是该买荣耀V20还是华为P20呢&#xff1f; 针对上述问题&#xff0c;小编今天为大…

V20变频器MODBUS-RTU通信和内置PID应用

MODBUS通信的相关内容大家可以查看专栏的系列文章,这篇博客主要是记录和分享V20变频器常用参数的MODBUS地址表和参数设置,方便大家查询。限于本人能力和水平,文中难免出现错误和不妥,诚恳的欢迎大家批评指正。同时也感谢大家关注。 SMART S7-200PLC MODBUS通信_RXXW_Dor的…

deepin v20桌面bug_深度操作系统 Deepin V20

现在除 Win 和 Mac 外&#xff0c;很多人都想学习使用 Linux 系统。除了国外的 CentOS、Ubuntu、Debian 等专业的发行版外&#xff0c;对新手/普通用户而言&#xff0c;面向国人的优麒麟或「深度操作系统」则可能更加合适入门。 作为优秀的国产 Linux 发行版之一&#xff0c;De…

荣耀v20屏幕测试软件,测量原来可以这么简单 荣耀V20 AR测量功能体验

最近&#xff0c;荣耀V20升级系统后新增了AR测量功能。荣耀V20的AR测量功能是通过后面搭载的TOF立体深感镜头来实现&#xff0c;目前可以支持直线、面积、体积、身高四项测量。 除了这次新增的AR测量功能外&#xff0c;通过背面搭载的TOF立体深感镜头&#xff0c;荣耀V20还可以…

S7-200 SMART PLC和V20变频器绕线机控制应用

绕线机PLC控制应用涉及到编码器的速度采集和高速计数,相关内容可以参看如下博客 PLC通过编码器反馈值计算速度的推荐做法(算法解析+ST代码)_RXXW_Dor的博客-CSDN博客_编码器计算速度程序实例PLC如何测量采集编码器的位置数据,不清楚的可以参看我的另一篇博文:三菱FX3U PLC…

lgv20刷twrp_LG港版v20 root

这是LG港版v20 root,整理了一下有关LG港版v20的官方固件包了,有没有需要的呢,这里把固件包整理一下也是方便大家以后好下载了,因此有一些机友还是不知道在哪里下载官方的rom包,在这里说的固件rom包也就是原版的系统包了,大家可以放心的使用,这些系统包也都是支持线刷的,…

统信桌面操作系统V20专业版(1022)发布

今日&#xff0c;统信桌面操作系统V20专业版&#xff08;1022&#xff09;正式发布。 统信桌面操作系统具有安全稳定、智能协同、美观易用的特点&#xff0c;拥有丰富的软硬件兼容性&#xff0c;广泛的应用生态支持, 兼容国内主流处理器架构&#xff0c;可为党政军、金融及各行…

爱奇艺视频格式转换工具

下载链接&#xff1a;http://www.pc6.com/pc/qsvzhgj/