📄 flash.c
字号:
/*
*CopyRight Reserved? 凯拓科技版权所有 http://www.ktopcn.com
*文件名:flash.c
*描述:提供Flash操作的上层程序。
*
*版本:v1.0
*作者:ktop
*日期:2004/11/17
*/
#define FLASH_C
#include "flash.h"
//与Flash容量相关的变量
static const uchar scucFlashSizeAttr[] = {FLASH_4M, FLASH_8M, FLASH_16M, FLASH_32M};
static const uint scuiBlockSize[] = { 256, 512, 512, 1024,};
static const uchar scucFlashDef[3][2]= { //与操作FLASH相关的变量。
MEM_TO_BUFF1, MEM_TO_BUFF2,
BUFF1_TO_MEM_WITH_ERASE, BUFF2_TO_MEM_WITH_ERASE,
BUFF_1_WRITE, BUFF_2_WRITE,};
//与写操作相关定义
static uint suiBufAddr[2]; //两个缓冲所对应的FLASH实际页地址。
/*
*函数性质:公共
*入口:无
*出口:无
*功能:刷新缓冲,将缓冲中的数据写入到FLASH中。以免断电数据丢失。
*/
void FlushFlash(void)
{
uchar i;
for (i = 0; i < 2; i++)
{
WriteBuffToFlash(scucFlashDef[WRITE_FROM_BUF][i], suiBufAddr[i]);
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{ //等待写入完成。
CLRWATCHDOG();
}
}
}
/*
*函数性质:公共
*入口:页地址ulFlashAddr
*出口:无
*功能:将给定地址的Flash数据读入到缓冲中。
*/
void UpDateFlashBuf(ulong ulFlashAddr)
{
uchar i;
uint uiPageAddr = ulFlashAddr/PAGE_SIZE;
for (i = 0; i < 2; i++)
{
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{ //等待读入完成。
CLRWATCHDOG();
}
ReadFlashToBuff(scucFlashDef[READ_TO_BUF][i], uiPageAddr + i);
suiBufAddr[i] = uiPageAddr + i;
}
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{ //等待读入完成。
CLRWATCHDOG();
}
}
/*
*函数性质:公共
*入口:存储器地址ulAddr, 数据缓冲地址pData, 数据长度uiLen
*出口:无
*功能:从Flash中读出给定个数的数据,并将读得的数据存放到pData中。
*/
void ReadFlashMem(ulong ulAddr, uchar *pData, uint uiLen)
{
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{
CLRWATCHDOG();
}
ContinueReadFlash(ulAddr/PAGE_SIZE, ulAddr%PAGE_SIZE, pData, uiLen);
}
/*
*函数性质:公共
*入口:存储器地址ulAddr,数据缓冲地址pData, 数据长度uiLen
*出口:无
*功能:将pData所指向的缓冲数据写入到指定的存储器地址,数据个数由uiLen决定。
*/
void WriteFlashMem(ulong ulAddr, uchar *pData, uint uiLen)
{
uint uiPageAddr;
uint j;
uint i;
uchar ucCurBuf;
uiPageAddr = ulAddr/PAGE_SIZE;
j = ulAddr%PAGE_SIZE; //得出本页偏移地址。
while(uiLen) //写数据
{
i = PAGE_SIZE -j;
i = (i <= uiLen) ? i:uiLen; //计算出本次需要写入的数据长度。
if (suiBufAddr[0] ==uiPageAddr) //当前正使用缓冲1
{
ucCurBuf = 0;
if (suiBufAddr[1] != (uiPageAddr + 1) ) //判断并读入缓冲2
{
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{
CLRWATCHDOG();
}
ReadFlashToBuff(scucFlashDef[READ_TO_BUF][1], uiPageAddr + 1);
suiBufAddr[1] = uiPageAddr + 1;
}
WriteFlashBuff(scucFlashDef[WRITE_BUF][0], j, pData, i);//写数据入缓冲1
}
else if (suiBufAddr[1] == uiPageAddr)
{
ucCurBuf = 1; //当前正使用缓冲2
if (suiBufAddr[0] != (uiPageAddr + 1) ) //判断并读入缓冲1
{
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{
CLRWATCHDOG();
}
ReadFlashToBuff(scucFlashDef[READ_TO_BUF][0], uiPageAddr + 1);
suiBufAddr[0] = uiPageAddr + 1;
}
WriteFlashBuff(scucFlashDef[WRITE_BUF][1], j, pData, i);//写缓冲1
}
else
{ //当前的两个缓冲均不是需要写入的页,读入需要写入的页
suiBufAddr[0] = uiPageAddr;
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{
CLRWATCHDOG();
}
ReadFlashToBuff(scucFlashDef[READ_TO_BUF][0], uiPageAddr);
continue;
}
j += i;
if (j >= PAGE_SIZE)
{
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{
CLRWATCHDOG();
} //写入到Flash
WriteBuffToFlash(scucFlashDef[WRITE_FROM_BUF][ucCurBuf], suiBufAddr[ucCurBuf]);
}
uiLen -= i; //修改各数据指针
uiPageAddr += j/PAGE_SIZE;
j = j%PAGE_SIZE;
pData += i;
}
}
/*
*函数性质:公共
*入口:存储器地址ulAddr,数据缓冲地址pData, 数据长度uiLen
*出口:无
*功能:将pData所指向的缓冲数据写入到指定的存储器地址,数据个数由uiLen决定。
*/
/*void WriteFlashMem(ulong ulAddr, uchar *pData, uint uiLen)
{
uint j;
while(uiLen)
{
j = ulAddr%PAGE_SIZE;
j = PAGE_SIZE -j;
j = (j <= uiLen) ? j:uiLen; //计算出需要写入的数据长度。
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{
CLRWATCHDOG();
} //忙,则一直等待
ReadFlashToBuff(MEM_TO_BUFF1, ulAddr/PAGE_SIZE); //读数据入缓冲。
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{
CLRWATCHDOG();
} //忙,则一直等待
WriteFlashWithBuff(BUFF1_TO_MEM, ulAddr/PAGE_SIZE, ulAddr%PAGE_SIZE,
pData, j);
ulAddr += j; //修改数据地址及各指针
uiLen -= j;
pData += j;
}
}*/
/*
*函数性质:公共
*入口:无
*出口:FLASH容量,如果为4M位,则返回0
*功能:读取Flash容量。
*/
uchar GetFlashSize(void)
{
uchar i;
uchar j;
i = (ReadFlashStuReg() & 0x3C);
for (j = 0; j < sizeof(scucFlashSizeAttr); j++)
{
if (i == scucFlashSizeAttr[j])
{
return j;
}
}
return 0xff; //读芯片出错,返回非法值。
}
/*
*函数性质:公共
*入口:无
*出口:无
*功能:整片擦除FLASH。
*/
void EraseAllFlash(void)
{
uint i;
i = scuiBlockSize[GetFlashSize()];
for (; i > 0; i--)
{
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{
CLRWATCHDOG();
}
FlashBlockErase(i-1); //擦除块。
}
}
/*
*函数性质:公共
*入口:无
*出口:无
*功能:初始化FLASH,将FLASH中的数据读入到缓冲中。
*/
void FlashMemIni(void)
{
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{
CLRWATCHDOG();
}
ReadFlashToBuff(scucFlashDef[READ_TO_BUF][0], 0);
while(!(ReadFlashStuReg() & FLASH_BUSY) )
{
CLRWATCHDOG();
}
ReadFlashToBuff(scucFlashDef[READ_TO_BUF][1], 1);
suiBufAddr[0] = 0;
suiBufAddr[1] = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -