环境
1.STM32CubeMX 6.15
2.keil_mdk
3,stm32f767
STM32CUBE配置
FM25CL64是SPI驱动的,频率不超过20MHz.配置好后,直接生成了。注意,不要用硬件NSS,软件控制比较好。
代码
1.头文件
#ifndef __FRAM_H
#define __FRAM_H
#include "main.h"
#include "spi.h"
#define FRAM_COM_PORT hspi1
#define Fram_SetCS(x) HAL_GPIO_WritePin(SPI1_CS_GPIO_Port,SPI1_CS_Pin,(x))
//状态寄存器 X表示无意义,默认值是0
// BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0
// WPEN X(0) X(0) X(0) BP1 BP0 WEL X(0)
// WEL: 1为写使能,0为禁止写
// BP0,BP1: 块保护
// WPEN:
#define FRAM_WREN 0x06 //写入使能,即设置WEL位 在写操作(WRSR和WRITE)之前,必须先发本命令
#define FRAM_WRDI 0x04 //写入禁止,即清除WEL位 本操作会禁止写操作(WRSR和WRITE),此后即使发送(WRSR和WRITE)也无效
#define FRAM_RDSR 0x05 //读状态寄存器
#define FRAM_WRSR 0x01 //写状态寄存器,前序操作为FRAM_WREN
#define FRAM_READ 0x03 //读
#define FRAM_WRITE 0x02 //写,前序操作为FRAM_WREN
uint8_t Fram_ReadReg(void);
//void Fram_WriteReg(uint8_t dat);
void Fram_ReadData(uint16_t addr, uint8_t *dat, uint16_t len);
void Fram_WriteData(uint16_t addr, const uint8_t *dat, uint16_t len);
#endif
2.C文件
#include "fram.h"
uint8_t Fram_ReadReg(void)
{
uint8_t data[1];
data[0] = FRAM_WREN; //使能写入,上电后默认禁止
Fram_SetCS(0);
HAL_SPI_Transmit(&FRAM_COM_PORT,data,1,100);
Fram_SetCS(1);
Fram_SetCS(0);
uint8_t tx_data[2] = {FRAM_RDSR, 0x00}; // 命令 + 空字节用于接收
uint8_t rx_data[2];
HAL_SPI_TransmitReceive(&FRAM_COM_PORT, tx_data, rx_data, 2, 100);
uint8_t status = rx_data[1]; // 第二个字节是状态寄存器值
Fram_SetCS(1);
return status;
}
void Fram_WriteReg(uint8_t dat)
{
uint8_t data[1];
data[0] = FRAM_WREN; //使能写入,默认禁止
Fram_SetCS(0);
HAL_SPI_Transmit(&FRAM_COM_PORT,data,1,100);
Fram_SetCS(1);
//写状态寄存器 0x01
Fram_SetCS(0);
uint8_t tx_data[2] = {FRAM_WRSR, dat}; //
uint8_t rx_data[2];
HAL_SPI_TransmitReceive(&FRAM_COM_PORT, tx_data, rx_data, 2, 100);
Fram_SetCS(1);
}
//void Fram_WriteData(uint16_t addr,uint8_t dat)
//{
// Fram_SetCS(0);
// uint8_t tx_data[4] = {FRAM_WRITE, addr >> 8, addr,dat}; // 命令 + 空字节用于接收
// uint8_t rx_data[4];
// HAL_SPI_TransmitReceive(&FRAM_COM_PORT, tx_data, rx_data, 4, 10);
// Fram_SetCS(1);
//}
void Fram_WriteData(uint16_t addr, const uint8_t *dat, uint16_t len)
{
uint8_t cmd[3];
// cmd[0] = FRAM_WREN;
// Fram_SetCS(0);
// HAL_SPI_Transmit(&FRAM_COM_PORT, cmd, 1, 100);
// Fram_SetCS(1);
cmd[0] = FRAM_WRITE;
cmd[1] = addr >> 8;
cmd[2] = addr & 0xFF;
Fram_SetCS(0);
HAL_SPI_Transmit(&FRAM_COM_PORT, cmd, 3, 100);
HAL_SPI_Transmit(&FRAM_COM_PORT, (uint8_t*)dat, len, 100);
Fram_SetCS(1);
}
//void Fram_ReadData(uint16_t addr,uint8_t *dat)
//{
// Fram_SetCS(0);
// uint8_t tx_data[4] = {FRAM_READ, addr >> 8, addr,0x00}; // 命令 + 空字节用于接收
// uint8_t rx_data[4];
// HAL_SPI_TransmitReceive(&FRAM_COM_PORT, tx_data, rx_data, 4, 10);
// *dat = rx_data[3];
// Fram_SetCS(1);
//}
void Fram_ReadData(uint16_t addr, uint8_t *dat, uint16_t len)
{
uint8_t cmd[3];
cmd[0] = FRAM_READ;
cmd[1] = addr >> 8;
cmd[2] = addr & 0xFF;
Fram_SetCS(0);
HAL_SPI_Transmit(&FRAM_COM_PORT, cmd, 3, 100);
HAL_SPI_Receive(&FRAM_COM_PORT, dat, len, 100);
Fram_SetCS(1);
}
使用
正常的文件包含后,首先使用Fram_ReadReg();读取状态寄存器的值,正常值应该是0x02,这个函数里面,使能了写入功能,因为手册上写,这个芯片上电默认是禁止写入的。
(在写入函数里面,每次写入新数据前,都使能写入功能)
如果一上电就使能了写入,可以修改数据写代码,注释掉每次写前使能写入功能代码。
然后就是写入和读取了。