STM32F407实现FRAM驱动

2020-06-29来源: eefocus关键字:STM32F407  FRAM驱动  spi接口初始化

spi接口初始化

void SPI1_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

SPI_InitTypeDef SPI_InitStructure;


RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//使能SPI1时钟


//GPIOF9,F10初始化设置

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;//PB3~5复用功能输出

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉

GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化


GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_SPI1); //PB3复用为 SPI1

GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_SPI1); //PB4复用为 SPI1

GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_SPI1); //PB5复用为 SPI1



//这里只针对SPI口初始化

RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);//复位SPI1

RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);//停止复位SPI1


SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工

SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构

SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行同步时钟的空闲状态为高电平

SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //定义波特率预分频的值:波特率预分频值为256

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始

SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式

SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器


SPI_Cmd(SPI1, ENABLE); //使能SPI外设


//SPI1_ReadWriteByte(0xff);//启动传输  


}

//SPI1速度设置函数

//SpeedSet:0~7

//SPI速度=fAPB2/2^(SpeedSet+1)

//fAPB2时钟一般为84Mhz

void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler)

{

assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));

SPI1->CR1&=0XFFC7;

SPI1->CR1|=SPI_BaudRatePrescaler; //设置SPI1速度

SPI_Cmd(SPI1,ENABLE);

}

//SPI1 读写一个字节

//TxData:要写入的字节

//返回值:读取到的字节

u8 SPI1_ReadWriteByte(u8 TxData)

{

u8 retry = 0;

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)

{

retry++;

if(retry > 200) return 0;

}//等待发送区空


SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个byte  数据

retry = 0;


while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)

{

retry++;

if(retry > 200) return 0;

} //等待接收完一个byte


return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据


}


FRAM接口

#ifndef __FRAM_H

#define __FRAM_H


#ifdef __cplusplus

extern “C” {

#endif


#include “stm32f4xx.h”

#define CMD_WREN 0x06

#define CMD_WRDI 0x04

#define CMD_RDSR 0x05

#define CMD_WRSR 0x01

#define CMD_READ 0x03

#define CMD_WRITE 0x02


#define GPIO_CSN GPIOA

#define GPIO_Pin_CSN GPIO_Pin_4

#define GPIO_RCC_CSN RCC_AHB1Periph_GPIOA

#define Set_FRAM_CSN() GPIO_SetBits(GPIO_CSN,GPIO_Pin_CSN)

#define Clr_FRAM_CSN() GPIO_ResetBits(GPIO_CSN,GPIO_Pin_CSN)


void FRAM_Init(void);

void FRAM_Write(u16 writeaddr,u8 *fbuf,u16 n);

void FRAM_Read(u16 readaddr,u8 *fbuf,u16 n);

#ifdef __cplusplus

}

#endif


#endif


#include “fram.h”

#include “spi.h”


//初始化SPI FLASH的IO口

void FRAM_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;


RCC_AHB1PeriphClockCmd(GPIO_RCC_CSN, ENABLE);//使能GPIOB时钟

//GPIOA4

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CSN;//PB14

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//输出

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉

GPIO_Init(GPIO_CSN, &GPIO_InitStructure);//初始化


Set_FRAM_CSN();

SPI1_Init();     //初始化SPI

Clr_FRAM_CSN();

SPI1_ReadWriteByte(0xff);//启动传输

Set_FRAM_CSN(); //SPI FLASH不选中


}

void FRAM_Write_Enable(void)

{

u16 i;

Clr_FRAM_CSN();

SPI1_ReadWriteByte(CMD_WREN); //发送读取命令

Set_FRAM_CSN();

i=10;

while(i–);


}

void FRAM_Write(u16 writeaddr,u8 *fbuf,u16 n)

{

u16 i;

FRAM_Write_Enable(); //操作命令之前必须写使能

Clr_FRAM_CSN(); //使能器件

SPI1_ReadWriteByte(CMD_WRITE); //发送读取命令

SPI1_ReadWriteByte((u8)((writeaddr)>>8)); //发送16bit地址

SPI1_ReadWriteByte((u8)writeaddr);

for(i=0;i

{

SPI1_ReadWriteByte(fbuf[i]); //循环读数

}

Set_FRAM_CSN();

}


void FRAM_Read(u16 readaddr,u8 *fbuf,u16 n)

{

u16 i;

FRAM_Write_Enable(); //操作命令之前必须写使能

Clr_FRAM_CSN(); //使能器件

SPI1_ReadWriteByte(CMD_READ); //发送读取命令

SPI1_ReadWriteByte((u8)((readaddr)>>8)); //发送16bit地址

SPI1_ReadWriteByte((u8)readaddr);

for(i=0;i

{

fbuf[i]=SPI1_ReadWriteByte(0xff); //循环读数

}

Set_FRAM_CSN();

}


总结

1、操作读写之前要发送写使能命令才进行操作

2、FRAM可以按字节操作或连接操作。

关键字:STM32F407  FRAM驱动  spi接口初始化 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic501498.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:绝对值编码器数据接收的问题
下一篇:STM32 网络通信Web Server中 SSI与CGI的应用解析

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32F407使用MFRC522射频卡调试及程序移植成功
本学期感测技术选修课需要做一个作品出来,用到了MFRC522射频卡模块,经历一个星期的调试,终于可以正常使用并寻卡成功了了。 成功的把C51的程序移植到了STM32上面。 现在分享一下调试过程1、操作环境我所使用的是STM32F407的开发板,使用STM32CubeMX配置初始代码。 MFRC522使用软件模拟SPI通信2、关于引脚的配置淘宝买来的模块,店家都会送资料 ,也可以点下面连接保存至网盘链接:http://pan.baidu.com/s/1boMyMlx1、SPI通信引脚 NSS(SDA)       --------->> 片选信号 SCK   
发表于 2020-05-22
STM32F407使用MFRC522射频卡调试及程序移植成功
STM32f407---oled屏幕配套取字模软件使用
我使用的是正点原子提供的oled字库,自己用取模软件取字模PC2LCD2002取模方式设置:阴码+逐列式+顺向+C51格式附: 代码//24*24的OLED汉字点阵,包括三个汉字:开、发、板。这三个汉字的点阵库,是利用PCtoLCD2002生产的,//软件设置的取模方式同OLED实验ASCII的取模方式一模一样,字体采用12*大小,一个汉字点阵占用24字节。const unsigned char OLED_HZK_TBL[14][24]={ {0x00,0x00,0x1F,0x80,0x11,0x00,0x11,0x00,0x11,0x00,0xFF,0xF0,0x11,0x00,0x11,0x00,0x11,0x00,0x1F
发表于 2020-05-20
STM32CubeMX 配置STM32F407 实现HAL库延时微妙方案
,但是最好使用最低级的定时器,TIM7和TIM8都只能定时,所以我这里用的TIM7这里我新建一个工程演示选择STM32F407zg芯片RCC和SYS配置就不截图了,大家都会的时钟树配置如下图通过查看STM32F407的数据手册可以知道TIM7的频率就是APB1的频率,84MHzTIM7配置:预分频系数为84-1 (83)自动重载值 1(这里的自动重载(arr)一定要设置为1,不能为0,否则无法得到正确的结果)则TIM7的溢出频率 = 84MHz / (83 + 1) = 1MHz(1us)在IAR或者MDK编译器中写代码在tim.c文件里面添加代码,一定要写在/* USER CODE BEGIN 1 *//* USER CODE
发表于 2020-05-17
STM32CubeMX 配置STM32F407 实现HAL库延时微妙方案
CubeMX Stm32F407 生成一定周期的占空比不同的方波 DMA + 定时器
先上图如图 是我生成的一个波形  这个波形的占空比在连续的四个周期内分别是10%,20%,30%,40%, 并且按照这个顺序循环这里大致介绍一下实现的方式。使用的软件是Cubemx(库函肯定也可以实现)第一步是器件选型  这一部分不做介绍  用的是Stm32F407第二是时钟配置接下来是定时器配置 第三步就是生成代码了这里 需要在生成的代码里面加上一行开始的代码。
发表于 2020-04-14
CubeMX Stm32F407 生成一定周期的占空比不同的方波 DMA + 定时器
基于Stm32F407的任意波形发生器
今天跟大家分享一个DAC转换的例子:先来效果图示波器使用的是Loto示波器OSC802三角波20KHz示例三角波20KHz示例正弦波20KHz示例测试使用的是Loto虚拟示波器   以上两张图的波形每一个周期都是300个DAC点组成,DAC转换速度是3MHz具体的实现代码如下:主要是最下面的三个函数  一个是DAC的初始化函数,另一个是定时器4的初始化函数 最后一个是波形发生函数。这是DAC+DMA的初始化函数  这要是设置DAC和DMA的基本参数 DAC触发选择的是定时器4的触发引脚, 也可以换成以上的其他定时器接下来是定时器的初始化定时器初始化部分很简单,不需要配置IO 
发表于 2020-04-14
基于Stm32F407的任意波形发生器
基于STM32F407的 中景园0.96寸OLED(IIC)的程序升级
前天学习了韦东山老师的嵌入式linux教学的一期视频中关于LCD的刷新显示章节,对于显示的机制有了一些略微的理解,回想起来之前一直在用的OLED不禁想要去看看有没有人做过相应的程序,结果没有找到!于是自己做了一个底层的代码。还是老规矩先来展示效果图图片展示的是OLED 的显示数字和字符串,OLED屏幕的刷新频率达到了惊人的40Hz,而且几乎不占用 CPU时间(数据全部走DMA) 我的程序是基于其他大佬的硬件IIC和DMA程序改编的,程序的整体框架如下在编写用户程序之前 我需要先实现 单片机内存到 OLED内存的这个工作,这一部分我选择使用的是STM32F407的硬件IIC 集合DMA来实现的,虽然网上对STM32F407的硬件
发表于 2020-04-14
基于STM32F407的 中景园0.96寸OLED(IIC)的程序升级
何立民专栏 单片机及嵌入式宝典

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

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