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

📄 flash.c

📁 串行FLASH驱动程序
💻 C
字号:
#include "Flash.h"

#ifdef _USE_ONCHIP_FLASH

/*
*************************************************************************************
*                    片上FLASH操作           
*************************************************************************************
*描述: 擦除片上FLASH的一段
*说明: 擦除一段
*************************************************************************************
*/
void FlashEraseBlock(int address)
{
	char *Ptr = (char*)(address&0xFF00);
	_DINT();
	FCTL2 = FWKEY+FSSEL0+FN0; //设为主时钟,4分频状态
	FCTL3 = FWKEY; // LOCK=1,复位锁定标志
	//等待忙标志复位
	while (FCTL3&1) _NOP();
	FCTL1 = FWKEY+ERASE; //设置片擦除状态               
	*Ptr = 0; //启动擦除操作
	while (FCTL3&1) _NOP();  //等待擦除完毕
	FCTL1 = FWKEY;
	_EINT();
}

void FlashWriteBlock(int dest, int source, int len)
{
	int i;
	char *DPtr = (char*)dest;
	char *SPtr = (char*)source;
	FlashEraseBlock(dest); 
	FCTL1 = FWKEY + WRT;
	for (i=0;i<len;i++)
	{
		*DPtr++ = *SPtr++;
	}
	FCTL1 = FWKEY;
}

#endif

#ifdef _USE_SERIAL_FLASH
void Init_Spi()
{
	P3DIR |= (BIT0+BIT1+BIT3);      //定义p3.0 为片选信号,初始为高
	P3DIR &= ~BIT2;                 // SPI
	P3OUT |=BIT0;
}

/***********************************************************
对SPI接口存储器的操做
***********************************************************/
//写字节
void spi_bytewrite(uchar data)
{
	uchar i;

	for(i=0; i<8; i++)
	{
		if(data & BIT7)
		{SPIMO_1;_NOP();}

		else
		{SPIMO_0; _NOP();}

		SPICLK_1;
		_NOP();
		_NOP();
		SPICLK_0;
		data <<= 1;
	}
}

//读字节
uchar spi_byteread(void)
{
	uchar abyte=0,i;

	for (i=0; i<8; i++)
	{ 
		abyte <<= 1;
		if (SPIDATA_IN)  abyte += 1;
		SPICLK_1;
		_NOP();
		_NOP();
		SPICLK_0;
	}
	return abyte;
}

//写flash写使能锁存器
void spi_wren(void) 
{  
	SPI_EN;
	spi_bytewrite(WREN);
	SPI_DIS;
}


//读flash状态寄存器
uchar spi_rdsr(void)
{
	uchar tempdata;

	SPI_EN;
	spi_bytewrite(RDSR); 
	tempdata = spi_byteread();
	SPI_DIS;
	return tempdata;
}

//spi数据写操作
void Spi_Write(ulong addr,uchar data)
{  
	uchar st;
	spi_wren();                                   //写使能
	SPI_EN;
	spi_bytewrite(PROGRAM);
	spi_bytewrite(addr >> 16);                    //写高字节地址
	spi_bytewrite(addr >> 8);                     //写中字节地址
	spi_bytewrite(addr);                          //写低字节地址
	spi_bytewrite(data);                          //写数据
	SPI_DIS;

	do
	{
		st = spi_rdsr();
	}while(st & BIT0);                    //判别写操作是否完成? 
}

//spi数据写操作
void Spi_Write_Int(ulong addr,uint data)
{  
	uchar st;
	spi_wren();                                   //写使能
	SPI_EN;
	spi_bytewrite(PROGRAM);
	spi_bytewrite(addr >> 16);                    //写高字节地址
	spi_bytewrite(addr >> 8);                     //写中字节地址
	spi_bytewrite(addr);                          //写低字节地址
	spi_bytewrite(data);                          //写数据
	spi_bytewrite(data>>8);                       //写数据
	SPI_DIS;

	do
	{
		st = spi_rdsr();
	}while(st & BIT0);                   //判别写操作是否完成?  
}
//做一个FLASH的基地址
//做一个FLASH的首地址
void Spi_Write_Blk(ulong addr,uint len, uchar *data)
{
	uint idx;
	for (idx=0;idx<len;idx++)
	{
		Spi_Write(addr+idx,*(data+idx));

	}
}


//spi数据读操作
uchar Spi_Read(ulong addr)
{  
	uchar data;

	SPI_EN;
	spi_bytewrite(READ);
	spi_bytewrite(addr>>16);              //写高字节地址
	spi_bytewrite(addr >> 8);             //写中字节地址
	spi_bytewrite(addr);                  //写低字节地址
	data = spi_byteread();                //读数据
	SPI_DIS;
	return data;
}

//spi数据读操作
uint Spi_Read_Int(ulong addr)
{  
	uint data;

	SPI_EN;
	spi_bytewrite(READ);
	spi_bytewrite(addr>>16);              //写高字节地址
	spi_bytewrite(addr >> 8);             //写中字节地址
	spi_bytewrite(addr);                  //写低字节地址
	data = spi_byteread();                //读数据
	data += spi_byteread()<<8;            //读数据
	SPI_DIS;
	return data;
}

void Spi_Read_Blk(ulong addr,uint len, uchar *data)
{
	uint idx;
	for (idx=0;idx<len;idx++)
	{
		*(data+idx) = Spi_Read(addr+idx);

	}
}

//flash整片擦除
void Spi_Chip_Erase(void)  
{ 
	uchar  temp;

	temp =SR & GIE;//保存中断状态
	SR &= ~GIE;   //关闭中断,

	spi_wren();
	SPI_EN;
	spi_bytewrite(CERASE);                //启动片擦除
	SPI_DIS;
	SR |= temp;                           //如果中断开着的打开闭着的仍然闭着
	Delay(20);
	do
	{
		temp = spi_rdsr();
		
	}
	while(temp & BIT0);                   //判别擦除是否完成
	
}

//flash块擦除
void Spi_Sector_Erase(ulong addr)                            
{ 
	uchar temp;

	temp =SR & GIE;//保存中断状态
	SR &= ~GIE;   //关闭中断,

	spi_wren();
	SPI_EN; 
	spi_bytewrite(SERASE);                //写入块擦除指令
	spi_bytewrite(addr >> 16);            //启动擦除
	spi_bytewrite(addr >> 8);
	spi_bytewrite(addr);
	SPI_DIS;
	SR |= temp;                           //如果中断开着的打开闭着的仍然闭着
	Delay(20);
	do
	{
		temp = spi_rdsr();
		
	}while((temp & BIT0) != 0);      //判别擦除是否完成
	
}



#endif

⌨️ 快捷键说明

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