STM32驱动SPI接口FLASH文档格式.docx

上传人:b****5 文档编号:21709396 上传时间:2023-01-31 格式:DOCX 页数:14 大小:55.95KB
下载 相关 举报
STM32驱动SPI接口FLASH文档格式.docx_第1页
第1页 / 共14页
STM32驱动SPI接口FLASH文档格式.docx_第2页
第2页 / 共14页
STM32驱动SPI接口FLASH文档格式.docx_第3页
第3页 / 共14页
STM32驱动SPI接口FLASH文档格式.docx_第4页
第4页 / 共14页
STM32驱动SPI接口FLASH文档格式.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

STM32驱动SPI接口FLASH文档格式.docx

《STM32驱动SPI接口FLASH文档格式.docx》由会员分享,可在线阅读,更多相关《STM32驱动SPI接口FLASH文档格式.docx(14页珍藏版)》请在冰豆网上搜索。

STM32驱动SPI接口FLASH文档格式.docx

<

SPI_FLASH_SPI 

Periph 

clock 

enable 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, 

ENABLE);

/*将PA5(CLK)配置成复用推挽输出 

GPIO_InitStructure.GPIO_Pin 

GPIO_Pin_5;

GPIO_InitStructure.GPIO_Speed 

GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode 

GPIO_Mode_AF_PP;

GPIO_Init(GPIOA, 

&

GPIO_InitStructure);

/*将PA6(DO)设置成浮空输入 

GPIO_Pin_6;

/*将PA7(DIO)设为浮空输入*/

GPIO_Pin_7;

/*将PA4(CS)设为推挽输出*/

GPIO_Pin_4;

GPIO_Mode_Out_PP;

/*拉高CS,失能芯片,该语句是宏定义,就是置高PA4*/

SPI_FLASH_CS_HIGH();

SPI配置/

// 

W25X16:

data 

input 

on 

the 

DIO 

pin 

is 

sampled 

rising 

edge 

of 

CLK. 

Data 

DO 

pins 

are 

clocked 

out 

falling 

CLK.

/*将SPI设为全双工模式*/

SPI_InitStructure.SPI_Direction 

SPI_Direction_2Lines_FullDuplex;

/*将SPI设为主模式*/

SPI_InitStructure.SPI_Mode 

SPI_Mode_Master;

/*将SPI通信的数据大小设为8位*/

SPI_InitStructure.SPI_DataSize 

SPI_DataSize_8b;

/*将CLK的高电平设为空闲*/

SPI_InitStructure.SPI_CPOL 

SPI_CPOL_High;

/*设置在第二个时钟沿捕获数据*/

SPI_InitStructure.SPI_CPHA 

SPI_CPHA_2Edge;

/*指定NSS信号由软件管理*/

SPI_InitStructure.SPI_NSS 

SPI_NSS_Soft;

/*SPI_BaudRatePrescaler用来定义波特率预分频的值,这个值用以设置发送和接收的SCK时钟*/

SPI_InitStructure.SPI_BaudRatePrescaler 

SPI_BaudRatePrescaler_4;

/*SPI_FirstBit指定了数据传输从高位还是低位开始*/

SPI_InitStructure.SPI_FirstBit 

SPI_FirstBit_MSB;

/*SPI_CRCPolynomial定义了用于CRC值计算的多项式*/

SPI_InitStructure.SPI_CRCPolynomial 

7;

SPI_Init(SPI1, 

SPI_InitStructure);

/* 

SPI_Cmd(SPI1, 

}

(2)获取器件地址1

因为SPI总线上可以挂很多的器件,所以首先要获得器件的地址。

获得器件地址的步骤是:

拉低CS——>

向器件发送获得地址的命令——>

连续发送三个任意数据——>

在发送第四个任意数据时在DO口上读出器件地址。

注意,发送完读地址后,从机会将数据自动传给主机的SPI数据寄存器中,用户只要到该寄存器中取数就可以了。

好的,既然用到写命令那么我们写来写这两个最基础的程序。

写数据函数:

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

Function 

Name 

:

SPI_FLASH_SendByte

Description 

通过SPI总线发送一字节数据,再通过SPI总线返回

一字节数据

Input 

byte 

——要发送的数据

Output 

从机返回的数据

被SPI_FLASH_ReadDeviceID调用

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

u8 

SPI_FLASH_SendByte(u8 

byte)

等待SPI发送寄存器里的数据发送结束 

while(SPI_I2S_GetFlagStatus(SPI1, 

SPI_I2S_FLAG_TXE) 

== 

RESET);

发送数据*/

SPI_I2S_SendData(SPI1, 

byte);

等待接收完一字节数据 

while 

(SPI_I2S_GetFlagStatus(SPI1, 

SPI_I2S_FLAG_RXNE) 

返回接收到的数据 

return 

SPI_I2S_ReceiveData(SPI1);

现在我们再来看看读器件地址函数:

SPI_FLASH_ReadDeviceID(void)

读器件地址1

返回 

:

器件地址

u32 

Temp 

0;

SPI_FLASH_CS_LOW(),是一个宏定义,就是拉低CS(PA4) 

SPI_FLASH_CS_LOW();

/*W25X_DeviceID=0XAB,是读器件地址的命令,发送完该命令后连续发三个任意数字,在发第五个任意数后可以读出地址 

SPI_FLASH_SendByte(0XAB);

SPI_FLASH_SendByte(0XFF);

Read 

from 

FLASH 

*/ 

Temp 

SPI_FLASH_SendByte(0XFF);

失能芯片*/ 

SPI_FLASH_CS_HIGH();

/*返回器件地址*/ 

return 

Temp;

像温度传感器一样,WX25X16也有很多的命令,具体的命令看下图:

(4)擦除扇区

WX25X16是2M的字节,共分为8页,每页是256个字节的大小。

可以采用页写入的方式写入数据。

这里需要注意的是,采用页写入时,每写入一个字节的数据地址会自动加1,当写满一页后会从该页的起始位置写起,即覆盖掉已写的数据。

如果想写完一页后进入下一页继续写入数据那么就要在写入数据的起始地址上加上256(页的大小就是256),比如我是从0开始写的,写到255时一页写完,那么要在第二页开始写,那么要将写入的地址变成(0+256),这一点大家一定要注意。

在写入数据前先要对芯片进行擦除。

芯片的擦除主要有一下几个步骤:

发送写使能命令——>

等待写使能命令执行结束——>

选中芯片——>

发送擦除命令——>

发送要擦除的起始地址——>

释放芯片——>

等待擦除命令执行结束

这里要注意的是,并不是发送任何命令都需要等待命令执行结束的,WX25X16手册规定以下几个操作要等待命令执行结束:

1.数据擦除 

2.对状态寄存器写的操作(例如数据写入失能结会改

变状态寄存器中的BUSY位)

首先看发送写使能命令:

SPI_FLASH_WriteEnable

允许想芯片内写入数据

None

Return 

被SPI_FLASH_SectorErase调用

SPI_FLASH_WriteEnable(void)

Select 

FLASH:

Chip 

low 

Send 

"

Write 

Enable"

instruction 

SPI_FLASH_SendByte(0X06);

Deselect 

high 

等待命令执行结束

SPI_FLASH_WaitForWriteEnd

执行写使能会值位状态寄存器中的BUSY位,只有

BUSY位变为0时说明写使能命令执行完成

*调用 

SPI_FLASH_WaitForWriteEnd(void)

FLASH_Status 

Status 

Register"

SPI_FLASH_SendByte(0X05);

Loop 

as 

long 

memory 

busy 

with 

write 

cycle 

do{

dummy 

to 

generate 

needed 

by 

put 

value 

status 

register 

in 

variable 

SPI_FLASH_SendByte(Dummy_Byte);

while 

((FLASH_Status 

0X01) 

SET);

progress 

下面看看数据擦除函数

SPI_FLASH_SectorErase

Erases 

specified 

sector.

SectorAddr:

address 

sector 

erase.

SPI_FLASH_WriteEnable()

SPI_FLASH_WaitForWriteEnd()

SPI_FLASH_SendByte()

SPI_FLASH_SectorErase(u32 

SectorAddr)

发送使能写命令 

SPI_FLASH_WriteEnable();

/*使能写命令是一个写状态寄存器的命令,所以要等待该命令执行完,才能写其他命令*/

SPI_FLASH_WaitForWriteEnd();

发送擦除扇区命令 

SPI_FLASH_SendByte(0X20);

发送要擦除的起始地址 

SPI_FLASH_SendByte((SectorAddr 

0xFF0000) 

>

16);

SectorAddr 

medium 

nibble 

0xFF00) 

8);

SPI_FLASH_SendByte(SectorAddr 

0xFF);

从机的数据手册规定(12页)规定,对于写擦除命令,要等待命令执行完才能执行下一命令*/

这里要注意,发送擦除地址时要发送三个8位的地址。

(5)写入数据

由于我们是选择的的页写入的方式,所以这里的程序又点小复杂,大家慢慢看,好好理解。

SPI_FLASH_BufferWrite

Writes 

block 

FLASH. 

In 

this 

function, 

the

number 

WRITE 

cycles 

reduced, 

using 

Page 

WRITEsequence.

pBuffer 

pointer 

buffer 

containing 

be

written 

FLASH.

WriteAddr 

FLASH'

internal 

to.

NumByteToWrite 

bytes 

SPI_FLASH_BufferWrite(u8 

*pBuffer,u32 

WriteAddr,u16NumByteToWrite)

NumOfPage 

=0,NumOfSingl 

=0,Addr 

=0,count 

=0,temp 

=0;

/*Addr记录的数据是用来判断写入的数据是否从页的起始地址开始写,如果Addr 

=0,则表示从起始地址开始写 

,SPI_FLASH_PageSize=256*/

Addr 

=WriteAddr 

SPI_FLASH_PageSize;

/*count记录的是从开始写的地址到该页结束处共有多少字节*/

count 

=SPI_FLASH_PageSize 

-Addr;

/*NumOfPage指示要写的数据要占几个整页*/

NumOfPage 

=NumByteToWrite 

/*NumOfSingl指示的是要写的数据在写完整页后还剩下的部分*/

NumOfSingl 

/*判断是否从页的起始处开始写起,Addr=0说明从起始处写起*/

if(Addr 

==0)

{

if(NumOfPage 

==0) 

//说明要写的数据的大小不足1页 

 

SPI_FLASH_PageWrite(pBuffer,WriteAddr,NumByteToWrite);

else 

//要写的数据大于1页

while(NumOfPage--) 

//将整页的数据写完

SPI_FLASH_PageWrite(pBuffer,WriteAddr,SPI_FLASH_PageSize);

WriteAddr 

+=SPI_FLASH_PageSize;

pBuffer 

}

SPI_FLASH_PageWrite(pBuffer,WriteAddr,NumOfSingl);

//不是从起始地址开始写

//要写的数据小于一页

if(NumOfSingl 

count) 

//要写入的数据大于从开始写处到页结束之间的空间大小

temp 

NumOfSingl 

count;

/*先写完该页*/

SPI_FLASH_PageWrite(pBuffer,WriteAddr,count);

/*多余的数据转到下页写*/

+= 

SPI_FLASH_PageWrite(pBuffer, 

WriteAddr, 

temp);

//要写的数据小于从开始写处到页结束之间的空间大小

NumByteToWrite);

//要写的数据大于一页

NumByteToWrite 

-=count;

count);

(NumOfPage--)

SPI_FLASH_PageSize);

if 

(NumOfSingl 

!

0)

NumOfSingl);

上面的函数用到了

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1