📄 flash.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 + -