⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spiflash.c

📁 spiflash操作
💻 C
字号:

/***********************************************************
 2007 3.27	 ccc
************************************************************/

#include "spiflash.h"
#include <INTRINS.H>

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#define High  1
#define Low   0	     

//spiflash指令
#define WREN 		0x06   		//写使能
#define WRDI 		0x04		//写禁止
#define RDID 		0x9F		//读ID
#define RDSR 		0x05		//读状态寄存器
#define WRSR 		0x01		//写状态寄存器
#define READ 		0x03		//读数据
//#define FAST_READ	0x0B		//快速读
#define PP			0x02		//页编程
#define SE			0xD8		//扇区擦除


unsigned char pre_treat(void);
unsigned char now_is_writing = 0;

//-------SPIBus operation Function-----------------------

void SPI_SendOneByte(unsigned char ch)	//发送一个字节
{
#if SIMULATION_SPI 					/*软件模拟*/
	unsigned char n;
	n = 8;
	while(n)
	{
		if(ch&0x80)
			SPI_MOSI = High;
		else
			SPI_MOSI = Low;
		SPI_SCK = High;
		ch = ch << 1;
		n--;
		SPI_SCK =  Low;
	}
#else 								/*硬件SPI*/
	SPIF = 0;
	SPI0DAT = ch;
	while(SPIF==0);
#endif	
}

unsigned char SPI_ReceiveOneByte(void)			//接受一个字节
{
#if SIMULATION_SPI					//软件模拟
	unsigned char ch,n;
	ch = 0;
	n = 8;
	while(n)
	{
		SPI_SCK = High;
		ch = ch<<1;
		if(SPI_MISO)
			ch|=0x01;
		SPI_SCK = Low;
		n--;
	}
	return ch;
#else								//硬件SPI
	SPIF = 0;
	SPI0DAT = 0;
  	while (SPIF == 0);
  	return SPI0DAT;
#endif
}

void SPIFlashWriteEnable(void)	 			
{
	SPI_NSS = Low;  //选择从器件
	SPI_SendOneByte(WREN);
	SPI_NSS = High;	 	
}

unsigned char SPIFlashReadStatusReg(void)	 //读SPIFlash的状态寄存器
{
	unsigned char ch1;

	SPI_NSS = Low;
	SPI_SendOneByte(RDSR);
	ch1 = SPI_ReceiveOneByte();
	SPI_NSS = High;

	return ch1;
}

unsigned char SPIFlashWriteStatusReg(unsigned char value)   //写SPIFlash的状态寄存器
{
	if(pre_treat())	return FALSE;

	SPIFlashWriteEnable();

	SPI_NSS = Low;
	SPI_SendOneByte(WRSR);
	SPI_SendOneByte(value);
	SPI_NSS = High;

	now_is_writing = 1;

	return TRUE;
}

unsigned char SPIFlashPageWrite(unsigned long addr, unsigned char xdata *wbuf, unsigned char wlen)
{
	if(pre_treat())	return FALSE;

	SPIFlashWriteEnable();

	SPI_NSS = Low;

	SPI_SendOneByte(PP);
	SPI_SendOneByte(addr>>16);
	SPI_SendOneByte(addr>>8);
	SPI_SendOneByte(addr);

	while(wlen)
	{
		wlen--;
		SPI_SendOneByte(*wbuf);
		wbuf++;
	}

	SPI_NSS = High;

	now_is_writing = 1;

	return TRUE;
}

unsigned char pre_treat(void)		//return 1--fail
{
	unsigned long cc;

	if(!now_is_writing)
		return 0;

	cc = COUNT_FOR_WRITE_DELAY;
	while(cc)
	{
		cc--;
		if(SPIFlashReadStatusReg()&0x01)
			continue;
		else
		{
			now_is_writing = 0;
			return 0;
		}
	}	

	return 1;
}

unsigned char SPIFLASH_init(void)
{
	unsigned char ch;

	ch = SPIFlashReadStatusReg();

	if((ch&0x61)!=0x00)
		return FALSE;

	if((ch&0x9c)!=0x9c)
		SPIFLASH_protect();

	SPI_WP = Low;

	return TRUE;
}

unsigned char SPIFLASH_protect(void) 	//	 硬件保护SPIFlash
{
	if(pre_treat())	return FALSE;

	SPI_WP = High;
	SPIFlashWriteEnable();

	SPIFlashWriteStatusReg(0x9C);
	SPI_WP = Low;

	now_is_writing = 1;
			
	return TRUE;
}

unsigned char SPIFLASH_unProtect(void)		//	 解保护
{
	if(pre_treat())	return FALSE;

	SPI_WP = High;
	SPIFlashWriteEnable();	

	SPIFlashWriteStatusReg(0x00);

	now_is_writing = 1;

	return TRUE;
}

unsigned char SPIFLASH_erase_sector(unsigned char sectorNo)
{
	if(sectorNo >= FLASH_SECTOR_COUNT) 
		return  FALSE;

	if(pre_treat())	return FALSE;

	SPIFlashWriteEnable();

	SPI_NSS = Low;

	SPI_SendOneByte(SE);
	SPI_SendOneByte(sectorNo);		   //sectorNo 0  address  00000~0ffff
	SPI_SendOneByte(0x00);			   //要发3字节的指令
	SPI_SendOneByte(0x00);

	SPI_NSS = High;

	now_is_writing = 1;
		
	return TRUE;
}

unsigned char SPIFLASH_read(unsigned long addr, unsigned char xdata *rbuf, unsigned char rlen)
{
	if(addr + rlen > FLASH_SIZE)
		return FALSE;

	if(pre_treat())	return FALSE;

	SPI_NSS = 0;

	SPI_SendOneByte(READ);
	SPI_SendOneByte(addr>>16);
	SPI_SendOneByte(addr>>8);
	SPI_SendOneByte(addr);

	while(rlen)
	{
		*rbuf = SPI_ReceiveOneByte();
		rbuf++;
		rlen--;
	}

	SPI_NSS = High;

	return TRUE;
}

unsigned char SPIFLASH_write(unsigned long addr, unsigned char xdata *wbuf, unsigned char wlen) // 写数据
{
	unsigned char PageMargin;

	if((addr + wlen) >= FLASH_SIZE)			  	//要写入的数据最后是否超出容量
		return FALSE;

	PageMargin =(unsigned char)(~addr) + 1;

	if((wlen>PageMargin) && (PageMargin!=0) )
	{
		if(!SPIFlashPageWrite(addr,wbuf,PageMargin))
			return FALSE;

		wlen -= PageMargin;
		wbuf += PageMargin;
		addr += PageMargin;
	}

	return SPIFlashPageWrite(addr,wbuf,wlen);
}
		  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -