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

📄 flash.c

📁 本程序是并口FLASH 39sf040读写程序,并给出调用函数.
💻 C
字号:
#include 	<reg51.h>
#include	<intrins.h>
#include	<absacc.h>
#include	"..\Include\FLASHDEF.h"

#ifndef FLASH_ONLY_READ
//us 延时函数
void Delayus(unsigned char time)
{
 unsigned char idata  i;
	for(i=0;i<time;i++);
}
//查询是否已经完成写操作
//byteaddr:查询的地址
void CheckToggleReady(unsigned int byteaddr)
{
	unsigned long xdata timeout = 0x07FFFFFF;
	unsigned char PreData, CurData;
	PreData	= ReadIO(byteaddr) & 0x40;
	while ( timeout-- )
	{
		CurData = ReadIO(byteaddr) & 0x40;
		if (CurData == PreData)	  
			break;
		PreData	= CurData;
	}
}

void Flash_wb(unsigned int ChipAddr, unsigned char byte)
{
	WriteFlashIO(ChipAddr, 0x5555, 0xaa);
	WriteFlashIO(ChipAddr, 0x2aaa, 0x55);
	WriteFlashIO(ChipAddr, 0x5555, byte);
}

/*************************************************************************************/
//检查ID函数
// Flash_chipseletaddr:片选地址(0x0000,0x1000,0x2000,0x3000,0x4000.....)
unsigned char Flash_check(unsigned int ChipAddr)
{ 
    unsigned char Flash_ID;
	Flash_wb(ChipAddr, 0x90);				//ID ENTRY
	_nop_();
	*(&Flash_ID)=ReadFlashIO(ChipAddr, 0);
	if(Flash_ID != SSTID) 
		return 0;
	*(&Flash_ID)=ReadFlashIO(ChipAddr, 1);
	Flash_wb(ChipAddr, 0xf0);				//ID EXIT
	_nop_(); 
	return  Flash_ID;                 //返回ID号
}
/****************************************************************************/
//初始化函数
//输入参数num:FLASH的片数
//输出参数Flash_page:输出页地址大小
unsigned char Flash_Init(unsigned int ChipAddr, unsigned char *PageCount, unsigned char *ChipCount)
{  
	unsigned char Flash_page=0;
#if FlashChipCount > 1
	unsigned char i, ChipType, FlashSta=0;
	FlashALE = 0;
	*ChipCount = 0;
	for(i=0;i<FlashChipCount;i++)
	{
		ChipType = Flash_check(ChipAddr);	//取FLASH ID号
		FlashSta >>= 1;
		if(ChipType == 0)     //为0时标识错误状态位
			FlashSta |= 0x80; 
		else                 //正常时执行
		{
			(*ChipCount)++;
			if(Flash_page == 0)//第一片赋芯片ID
				Flash_page = ChipType;
			else if (Flash_page != ChipType)//不是第一片且芯片ID不一致
				return DifferFlashERR;				//存在不同型号芯片
		    if(FlashSta != 0)
				return JumpFlashERR;				//存在跳空芯片
		}
		ChipAddr += 1<<12;    //A12——A14为片选地址位 片选位加1
	}
#else
	FlashALE = 0;
	Flash_page = Flash_check(ChipAddr);	//取FLASH ID号
	if(Flash_page == 0)
		return NoFlashERR;	//第1片Flash缺或故障
	*ChipCount = 1;
#endif
	switch (Flash_page)
	{
		case SST39SF040ID:
			Flash_page = 0x80;    //返回128页
			break;
		case SST39SF020ID:
			Flash_page = 0x40;    //返回64页
			break;
		case SST39SF010ID:
			Flash_page = 0x20;    //返回32页
			break;
		default:
			Flash_page = 0;
	}
	*PageCount = Flash_page;
#if FlashChipCount > 1
	if(FlashSta & (1>>(FlashChipCount-1)))
		return NoFlashERR;		//第1片Flash缺或故障
	else
#endif
		return FlashOK;			//初始化成功返回0
}
       
/*************************************************************************************/
//片擦除程序
// Flash_chipseletaddr:片选地址(0x0000,0x1000,0x2000,0x3000,0x4000.....)
#ifdef FLASH_EN_ALLEraseChip
void Flash_EraseEntirChip(unsigned int ChipAddr)
{	
	Flash_wb(ChipAddr, 0x80);	//ERASE
	Flash_wb(ChipAddr, 0x10);	//CHIPERASE
}
#endif
/*************************************************************************************/
//扇区擦除程序
//page:要擦除的页地址
// Flash_chipseletaddr:片选地址(0x0000,0x1000,0x2000,0x3000,0x4000.....)

void Flash_EraseOneSector(unsigned char page,unsigned int ChipAddr)				//ok
{
	
	Flash_wb(ChipAddr, 0x80);	//ERASE
	WriteFlashIO(ChipAddr, 0x5555, 0xaa);
	WriteFlashIO(ChipAddr, 0x2aaa, 0x55);
//	WriteFlashIO(ChipAddr, page, 0x30);//SECTORERASE
	Flash_WAddrH(page);
	XBYTE[(page & 0x0fff) | ChipAddr] = 0x30;
}

/************************************************************************/
//写函数
//*bytedata:写缓冲  page:页地址   addr:便移地址   len:写字节长度
// Flash_chipseletaddr:片选地址(0x0000,0x1000,0x2000,0x3000,0x4000....
void Flash_ProgramData (unsigned char *bytedata, unsigned char page,unsigned  int addr, unsigned int len,unsigned int ChipAddr)
{   
	unsigned int tempaddr;
    while(len--)
	{
		Flash_wb(ChipAddr, 0xA0);	//PROGRAM
#ifdef FlashChipAtP2Port
		Flash_WAddrH(page);
		tempaddr = (addr & 0x0fff) | ChipAddr;
#else
		Flash_WAddrH(addr>>12);
		tempaddr = addr | ChipAddr;
#endif
		WriteIO(tempaddr, *bytedata);

		Delayus(6);
		CheckToggleReady(tempaddr); //查询是否完成写操作
		if(addr == 0x0FFF)  //偏移地址大于4095页地址加1
		{
			addr = 0;
	    	page++;
		}
		else
			addr++;
        bytedata++;
	}	
}
#endif

/**********************************************************************************/
//指定页地址和便移地址读函数
//*bytedata:读缓冲  page:页地址  addr:便移地址   len:数据字节长度
// Flash_chipseletaddr:片选地址(0x0000,0x1000,0x2000,0x3000,0x4000.....) 
void Flash_ReadData (unsigned char *bytedata, unsigned char page,unsigned  int addr, unsigned int len,unsigned int ChipAddr)
{
	Flash_WAddrH(page);
	while(len--)
	{
		*bytedata=ReadFlashIO(ChipAddr,addr);
    	bytedata++;
		if(addr == 0x0FFF)  //偏移地址大于4095页地址加1
		{
			addr = 0;
			Flash_WAddrH(++page);
		}
		else
			addr++;
	}
}	

⌨️ 快捷键说明

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