STM32F103C8T6+软件SPI+W25Q64

 一共四个文件:myspi.c ,myspi.h ,W25Q64.c ,W25Q64.h

1.myspi.c文件

#include "myspi.h"

void MySPI_SS(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)BitValue);
}

void MySPI_MOSI(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA,GPIO_Pin_7,(BitAction)BitValue);
}

void MySPI_CLK(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA,GPIO_Pin_5,(BitAction)BitValue);
}

uint8_t MySPI_MISO(void)
{
	return GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6);
}

/*
	*软件SPI初始化
 接线:	
	*CS:PA4
	*DO:PA6
	*SLK:PA5
	*DI:PA7
*/
void MySPI_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	MySPI_SS(1);
	MySPI_CLK(0);
}

void MySPI_Start(void)
{
	MySPI_SS(0);
}

void MySPI_Stop(void)
{
	MySPI_SS(1);
}

uint8_t MySPI_W_R_one_Byte(uint8_t ByteData)
{
	for(uint8_t i=0;i<8;i++)
	{
		MySPI_MOSI(ByteData&0X80);
		ByteData<<=1;
		MySPI_CLK(1);
		ByteData|=(0X00|MySPI_MISO());
		MySPI_CLK(0);
	}
	return ByteData;
}

2.myspi.h

#ifndef __MYSPI_H
#define __MYSPI_H

#include "stm32f10x.h"                  // Device header

void MySPI_Init(void);
void MySPI_Start(void);
void MySPI_Stop(void);
uint8_t MySPI_W_R_one_Byte(uint8_t ByteData);


#endif

3.W25Q64.c

#include "W25Q64.h"


void W25Q64_Init(void)
{
	MySPI_Init();
}


/**
  * @brief  读取从设备ID
  * @param1  存入厂商ID
  * @param2  存入设备ID
  * @retval None
  */
void W25Q64_ReadID(uint8_t *MID,uint16_t *DID)
{
	MySPI_Start();
	MySPI_W_R_one_Byte(JEDEC_ID);
	*MID=MySPI_W_R_one_Byte(DUMMY_BYTE);
	*DID=MySPI_W_R_one_Byte(DUMMY_BYTE);
	*DID<<=8;
	*DID|=MySPI_W_R_one_Byte(DUMMY_BYTE);
	MySPI_Stop();
}


/**
  * @brief  写使能
  * @retval None
  */

void W25Q64_Write_Enable(void)
{
	MySPI_Start();
	MySPI_W_R_one_Byte(Write_Enable);
	MySPI_Stop();
}


/**
  * @brief  设备在擦除或写入数据是处于BUSY状态,需等待设备完成	
  * @retval 1:设备正常;0:设备卡死
  */
uint8_t W25Q64_Wait_Busy(void)
{
	uint32_t TimeOUT=100000;
	MySPI_Start();
	MySPI_W_R_one_Byte(Read_Status_Register_1);
	while(MySPI_W_R_one_Byte(DUMMY_BYTE)&0x01)//读取BUSY位等待Flash空闲
	{
		TimeOUT--;
		if(TimeOUT==0)//等待时间过长认为卡死 直接退出
		{
			MySPI_Stop();
			return 0;
		}
	}
	MySPI_Stop();
	return 1;
}


/**
  * @brief  写数据(同时最多写入256Byte)
  * @param1  首地址,取值范围:0X000000~~0X7FFFFF
  * @param2  被写入的数据
  * @param3  数据长度,单位:字节
  * @retval None
  */
void W25Q64_WriteData(uint32_t BaseAddr,uint8_t *DataArr,uint8_t count)
{
	W25Q64_Write_Enable();
	MySPI_Start();
	MySPI_W_R_one_Byte(Page_Program);
	MySPI_W_R_one_Byte((uint8_t)(BaseAddr>>16));
	MySPI_W_R_one_Byte((uint8_t)(BaseAddr>>8));
	MySPI_W_R_one_Byte((uint8_t)BaseAddr);
	for(uint8_t i=0;i<count;i++)
	{
		MySPI_W_R_one_Byte(DataArr[i]);
	}
	MySPI_Stop();
	W25Q64_Wait_Busy();
}


/**
  * @brief  擦除内存数据
  * @param1  首地址,取值范围:0X000000~~0X7FFFFF
  * @param2  擦除模式:
					* 0:芯片擦除
					* 1:扇区擦除(4KB)
					* 2:块擦除(32KB)
					* 3:块擦除(64KB)
  * @retval 擦除状态:
					*1:擦除成功
					*0:擦除失败
 */
uint8_t W25Q64_Erase(uint32_t BaseAddr,uint8_t mode)
{
	W25Q64_Write_Enable();
	MySPI_Start();
	switch(mode)
	{
		case 0:MySPI_W_R_one_Byte(Chip_Erase);break;
		case 1:MySPI_W_R_one_Byte(Sector_Erase_4KB);break;
		case 2:MySPI_W_R_one_Byte(Block_Erase_32KB);break;
		case 3:MySPI_W_R_one_Byte(Block_Erase_64KB);break;
		default:MySPI_Stop();return 0;
	}
	if(mode==1||mode==2||mode==3)
	{
		MySPI_W_R_one_Byte((BaseAddr>>16));
		MySPI_W_R_one_Byte((BaseAddr>>8));
		MySPI_W_R_one_Byte(BaseAddr);
	}
	MySPI_Stop();
	W25Q64_Wait_Busy();
	return 1;
}


/**
  * @brief  读取数据
  * @param1  首地址,取值范围:0X000000~~0X7FFFFF
  * @param2  数据缓冲区
  * @param2  读取长度 取值范围:0X000000~~0X7FFFFF
  * @retval 读取状态:
				   *1:读取成功
 */
uint8_t W25Q64_ReadData(uint32_t BaseAddr,uint8_t *DataArr,uint32_t count)
{
	MySPI_Start();
	MySPI_W_R_one_Byte(Read_Data);
	MySPI_W_R_one_Byte((uint8_t)(BaseAddr>>16));
	MySPI_W_R_one_Byte((uint8_t)(BaseAddr>>8));
	MySPI_W_R_one_Byte((uint8_t)BaseAddr);
	for(uint32_t i=0;i<count;i++)
	{
		DataArr[i]=MySPI_W_R_one_Byte(DUMMY_BYTE);
	}
	MySPI_Stop();
	return 1;
}





4.W25Q64.h

#ifndef __W25Q64_H
#define __W25Q64_H

#include "stm32f10x.h"                  // Device header
#include "myspi.h"


void W25Q64_Init(void);
void W25Q64_ReadID(uint8_t *MID,uint16_t *DID);
uint8_t W25Q64_Erase(uint32_t BaseAddr,uint8_t mode);
void W25Q64_WriteData(uint32_t BaseAddr,uint8_t *DataArr,uint8_t count);
uint8_t W25Q64_ReadData(uint32_t BaseAddr,uint8_t *DataArr,uint32_t count);



#define Write_Enable 						0X06
#define Write_Disable 						0X04
#define Read_Status_Register_1  			0X05
#define Read_Status_Register_2 				0X35
#define Write_Status_Register 				0X01
#define Page_Program 						0X02
#define Quad_Page_Program 					0X32
#define Block_Erase_64KB 					0XD8
#define Block_Erase_32KB 					0X52
#define Sector_Erase_4KB 					0X20
#define Chip_Erase 							0XC7//或者0X60
#define Erase_Suspend 						0X75
#define Erase_Resume 						0X7A
#define Power_down 							0XB9
#define High_Performance_Mode 				0XA3
#define Continuous_Read_Mode_Reset 			0XFF
#define Release_Power_down_or_HPM_Device_ID 0XAB
#define Manufacturer_Device_ID 				0X90
#define Read Unique_ID 						0X4B
#define JEDEC_ID 							0X9F
#define Read_Data							0X03
#define Fast_Read 							0X0B
#define Fast_Read_Dual_Output				0X3B
#define Fast_Read_Dual_IO 					0XBB
#define Fast_Read_Quad_Output 				0X6B
#define Fast_Read_Quad_IO 					0XEB
#define Octal_Word_Read_Quad_IO 			0XE3

#define DUMMY_BYTE 							0XFF//无用数据


#endif

来自江科大[狗头][狗头][狗头]

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式小F

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值