STM32F103C8T6使用HAL库——W25Q64编程实例(发送/接收32位数据、扇区写入... ...)

W25Q64是华邦公司推出的大容量 基于SPI通信 的FLASH 产品,工作电压为 2.7~3.6V,存储容量为 64Mb(8MB),擦写周期可达 10万次,数据保存时间可达 20年。 W25Q64系列 Flash存储器与 普通串行Flash存储器 相比,其使用 更灵活、性能更出色,非常 适合用于存储声音、文本和数据。

       W25Q64 有 32768个 可编程页,每页 256字节。

        使用 页编程指令 就可以 每次编程 256字节。

        使用 扇区擦除指令 可以 每次擦除 256字节。

        使用 块擦除指令 可以 每次擦除 256 页。

        使用 整片擦除指令 可以 擦除整个 芯片
————————————————

这是常用指令cube_mx的spi设置

设置PB0为cs选择引脚

W25Q64.C

#include "spi.h" 
#include "main.h" 
#include "gpio.h"
#include "W25Q64_INS.h"
/**
   *@brief:CS置0(选择从机)
   *@param:
   *@retval:
   */
void W25Q64_W_CS()
{
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);
}


/**
   *@brief:CS置1(关闭从机)
   *@param:
   *@retval:
   */
void W25Q64_S_CS()
{
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);
}


/**
   *@brief:发送一个字节
   *@param:
   *@retval:
   */
HAL_StatusTypeDef	SPI_TransmitOneByte(uint8_t	byteData)
{
	return HAL_SPI_Transmit(&hspi1, &byteData, 1, 0XFF);
}


/**
   *@brief:接收一个字节
   *@param:
   *@retval:
   */
uint8_t	SPI_ReceiveOneByte(void)
{
	uint8_t	byteData=0;
	HAL_SPI_Receive(&hspi1, &byteData, 1, 0XFF);
	return  byteData;
}


/**
   *@brief:发送多个字节
   *@param:
   *@retval:
   */
HAL_StatusTypeDef	SPI_TransmitMultiByte(uint8_t *byteData,uint8_t	size)
{
	return HAL_SPI_Transmit(&hspi1, byteData, size,0XFF);
}


/**
   *@brief:接收多个字节
   *@param:
   *@retval:
   */
uint8_t	SPI_ReceiveMultiByte(uint8_t *byteData,uint8_t	size)
{

	HAL_SPI_Receive(&hspi1, byteData, size, 0XFF);
}


/**
   *@brief:写使能
   *@param:
   *@retval:
   */
void W24Q64_W_Enable()
{
	W25Q64_W_CS();
	SPI_TransmitOneByte(W25Q64_WRITE_ENABLE);
	W25Q64_S_CS();
}

/**
   *@brief:等待忙
   *@param:
   *@retval:
   */
void W25Q64_WaitBusy()
{
	uint32_t timeout;
	W25Q64_W_CS();
	SPI_TransmitOneByte(W25Q64_READ_STATUS_REGISTER_1);
	timeout=100000;
	SPI_TransmitOneByte(W25Q64_DUMMY_BYTE);
	while((SPI_ReceiveOneByte()&0x01)==0x01)
	{
		SPI_TransmitOneByte(W25Q64_DUMMY_BYTE);
		timeout--;
		if(timeout==0)break;
	}
	W25Q64_S_CS();		
}

/**
   *@brief:读设备ID
   *@param:
   *@retval:
   */
uint16_t W25Q64_R_ID(void)
{
	uint16_t Temp = 0;
	W25Q64_W_CS();	//CS=0

	SPI_TransmitOneByte(0x90);		//???,0x90=Manufacturer/Device ID
	SPI_TransmitOneByte(0x00);		//dummy
	SPI_TransmitOneByte(0x00);		//dummy
	SPI_TransmitOneByte(0x00);		//0x00
	Temp =SPI_ReceiveOneByte()<<8;	//Manufacturer ID
	Temp|=SPI_ReceiveOneByte();	 	//Device ID, ???????

	W25Q64_S_CS();	//CS=1
	return Temp;
}


/**
   *@brief:扇区擦除
   *@param:µØÖ·
   *@retval:
   */
void W25Q64_EraseSector(uint32_t address)	
{
	W24Q64_W_Enable();
	W25Q64_W_CS();
	SPI_TransmitOneByte(W25Q64_SECTOR_ERASE_4KB);
	SPI_TransmitOneByte(address>>16);
	SPI_TransmitOneByte(address>>8);
	SPI_TransmitOneByte(address);
	W25Q64_S_CS();
	W25Q64_WaitBusy();
}


/**
   *@brief:页编程
   *@param:
   *@retval:
   */
void W25Q64_W_Data(uint8_t *w25q64_W_data,uint8_t size,uint32_t address)
{
    W24Q64_W_Enable();
	W25Q64_W_CS();
	SPI_TransmitOneByte(W25Q64_PAGE_PROGRAM);
	SPI_TransmitOneByte(address>>16);
	SPI_TransmitOneByte(address>>8);
	SPI_TransmitOneByte(address);
	SPI_TransmitMultiByte(w25q64_W_data,size);
	W25Q64_S_CS();
	W25Q64_WaitBusy();
}

//扇区编程

void W25Q64_SectorW_Data(uint8_t *w25q64_W_data,uint16_t size,uint32_t address)
{
	uint8_t i;
	for(i=0;i<=size/256;i++)
	{
	W25Q64_W_Data(w25q64_W_data,255,address);
	address+=0x000100;
	w25q64_W_data+=256;	
	}

}
/**
   *@brief:写入32位数据
   *@param:
   *@retval:
   */

void W25Q64_W_32bitData(uint32_t *w25q64_W_data,uint8_t size,uint32_t address)
{
	uint8_t data[4];
    W24Q64_W_Enable();
	W25Q64_W_CS();
	SPI_TransmitOneByte(W25Q64_PAGE_PROGRAM);
	SPI_TransmitOneByte(address>>16);
	SPI_TransmitOneByte(address>>8);
	SPI_TransmitOneByte(address);
	for(uint8_t i=0;i<size;i++)
	{
		data[0]=*w25q64_W_data>>24;
		data[1]=*w25q64_W_data>>16;
		data[2]=*w25q64_W_data>>8;
		data[3]=*w25q64_W_data;
	    SPI_TransmitMultiByte(data,4);
		w25q64_W_data++;
	}
	W25Q64_S_CS();
	W25Q64_WaitBusy();
}



/**
   *@brief:读8位数据
   *@param:·
   *@retval:
   */
void W25Q64_R_Data(uint8_t *w25q64_R_data,uint8_t size,uint32_t address)
{
	W25Q64_W_CS();
	SPI_TransmitOneByte(W25Q64_READ_DATA);
	SPI_TransmitOneByte(address>>16);
	SPI_TransmitOneByte(address>>8);
	SPI_TransmitOneByte(address);
	SPI_ReceiveMultiByte(w25q64_R_data,size);
	W25Q64_S_CS();
}


//读扇区内数据
void W25Q64_SectorR_Data(uint8_t *w25q64_data,uint16_t size,uint32_t address)
{	
	uint8_t i;
	for(i=0;i<=size/256;i++)
	{
	W25Q64_R_Data(w25q64_data,255,address);
	address+=0x000100;
	w25q64_data+=256;	
	}
}


/**
   *@brief:读32位数据
   *@param:
   *@retval:
   */
void W25Q64_R_32bitData(uint32_t *w25q64_R_data,uint8_t size,uint32_t address)
{
	uint8_t data[4];
	W25Q64_W_CS();
	SPI_TransmitOneByte(W25Q64_READ_DATA);
	SPI_TransmitOneByte(address>>16);
	SPI_TransmitOneByte(address>>8);
	SPI_TransmitOneByte(address);
	
	
	for(uint8_t i=0;i<size;i++)
	{
		SPI_ReceiveMultiByte(data,4);
		*w25q64_R_data=data[0];
		*w25q64_R_data=*w25q64_R_data<<8;
		*w25q64_R_data|=data[1];
		*w25q64_R_data=*w25q64_R_data<<8;
		*w25q64_R_data|=data[2];
		*w25q64_R_data=*w25q64_R_data<<8;
		*w25q64_R_data|=data[3];
		w25q64_R_data++;
	}
	W25Q64_S_CS();
}

W25Q64.H

#ifndef __W25Q64_H__
#define __W25Q64_H__

void W24Q64_W_Enable();
uint16_t W25Q64_R_ID();
void W25Q64_W_Data(uint8_t *w25q64_W_data,uint8_t size,uint32_t address);
void W25Q64_SectorW_Data(uint8_t *w25q64_W_data,uint16_t size,uint32_t address);
void W25Q64_W_32bitData(uint32_t *w25q64_W_data,uint8_t size,uint32_t address);
void W25Q64_R_Data(uint8_t *w25q64_R_data,uint8_t size,uint32_t address);
void W25Q64_SectorR_Data(uint8_t *w25q64_data,uint16_t size,uint32_t address);
void W25Q64_R_32bitData(uint32_t *w25q64_R_data,uint8_t size,uint32_t address);
void W25Q64_EraseSector(uint32_t address);
#endif

OLED使用硬件iic部分后继更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值