上一篇讲到内部Flash的读写,本篇讲述使用D-Flash模拟EEPROM。其实使用P-Flash也可以模拟,只不过D-Flash的Page更小(擦除复写占用更少时间),而且不会占用代码空间。
最近刚换工作,一直比较忙,更新会比较慢。若是需要源码可自行下载:https://download.youkuaiyun.com/download/u010875635/11435913
没有积分可以自己新建工程,下面的代码基本可以直接使用。
本篇关于Flash读写就不在赘述,跟PFlash除了Sector大小和指令不同,其余一致,后面直接贴出代码。
模拟EEPROM其实就是模拟其单字节读写功能,原理就是要修改某个Sector内某个字节的数据时,先读出这个扇区内所有数据(256Bytes)到数组,然后擦除这个Sector,再在RAM中修改那个字节的数据,最后将这个数组写回该扇区。修改多字节数据原理相似。
另外大家可以想一下,若是要往EEPROM中写入跨Sector的数组怎么办?(需要判断数组地址范围)
使用范例:
main.c
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#include "Typedefs.h"
#include "gpio.h"
#include "System.h"
#include "flash.h"
#include "EmulationEEPROM.h"
UINT32 m_maincount=0;
void main(void)
{
/* put your own code here */
int result;
UINT32 index = 0;
UINT32 globalDFlashAddr1 = 0x100000,globalDFlashAddr2 = 0x100002,globalDFlashAddr3=0x13F800;
UINT32 globalAddr1 = 0x7F4000,globalAddr2 = 0x7F4002,globalAddr3=0x7db460;
UINT8 datas1[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
UINT8 datas2[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
UINT8 readDatas[100];
McuDrivers_System_Init();
McuDrivers_GPIO_Init();
EnableInterrupts;
//for(index = 0;index<129;index++)
// HDL_Flash_PFlash_ProgramMultiSectors(globalAddr2+index*8,datas,sizeof(datas));
//HDL_Flash_PFlash_EraseOneSector(0x7F4000);
// HDL_Flash_PFlash_EraseMultiSectors(globalAddr2,globalAddr2+1001);
//IFsh1_EraseSector(globalAddr2);
//HDL_Flash_PFlash_ProgramMultiSectors(globalAddr1,datas,sizeof(datas));
//HDL_Flash_PFlash_ProgramMultiSectors(globalAddr3,datas2,sizeof(datas2));
//HDL_Flash_DFlash_EraseMultiSectors(globalDFlashAddr1,globalDFlashAddr1+1000);
//for(index = 0;index<33;index++)
// HDL_Flash_DFlash_ProgramMultiSectors(globalDFlashAddr1+index*16,datas1,sizeof(datas1));
//HDL_Flash_DFlash_EraseMultiSectors(globalDFlashAddr1,globalDFlashAddr1+1000);
//HDL_Flash_DFlash_ProgramMultiSectors(globalDFlashAddr2,datas1,sizeof(datas1));
result = HAL_EEE_ChangeValue(globalDFlashAddr1,datas1,sizeof(datas1));
result = HAL_EEE_ChangeValue(globalDFlashAddr1+10,datas1,sizeof(datas1));
HAL_EEE_GetValue(globalDFlashAddr1,30,readDatas);
for(;;)
{
m_maincount++;
if(m_maincount>100000)
{
m_maincount = 0;
PORTB_PB0 ^=1;
}
_FEED_COP(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
EmulationEEPROM.h
#ifndef _HAL_EmulationEEPROM_H_
#define _HAL_EmulationEEPROM_H_
#include "Typedefs.h"
//get value
int HAL_EEE_GetValue(UINT32 startGlobalAddr, UINT8 newDataLength, UINT8 * pNewData);
//change value
int HAL_EEE_ChangeValue(UINT32 startGlobalAddr, UINT8 * pNewData,UINT8 newDataLength);
#endif
EmulationEEPROM.c
#include "EmulationEEPROM.h"
#include "flash.h"
#define DFLASH_SECTOR_ADDR_MASK 0xFFFFFF00 //256 bytes
#define DFLASH_SECTOR_SIZE 256U
#define PROGRAM_DFlash_Phrase_SIZE 8U
#define PROGRAM_DFlash_Phrase_MASK 0xFFFFFFF8
//get value
int HAL_EEE_GetValue(UINT32 startGlobalAddr, UINT8 newDataLength, UINT8 * pNewData)
{
UINT16 i;
UINT8 *far readTmpData;
//读取DFlash中内容
for(i=0;i<newDataLength;i++)
{
readTmpData = (UINT8 *far)(startGlobalAddr+i);
pNewData[i] = (*readTmpData);
}
}
//change value
int HAL_EEE_ChangeValue(UINT32 startGlobalAddr, UINT8 * pNewData,UINT8 newDataLength)
{
UINT32 sectorStartAddr = startGlobalAddr&DFLASH_SECTOR_ADDR_MASK;
UINT8 dataContainer[DFLASH_SECTOR_SIZE]={0};
UINT16 *far readTmpData;
UINT16 i;
volatile int result = 0;
//读取DFlash中此扇区内容
for(i=0;i<DFLASH_SECTOR_SIZE;i+=2)
{
readTmpData = (UINT16 *far)(sectorStartAddr+i);
dataContainer[i] = ((*readTmpData)>>8)&0xFF; //高位在前
dataContainer[i+1] = (*readTmpData)&0xFF;
}
//更新要写入的内容
for(i=startGlobalAddr-sectorStartAddr;i<startGlobalAddr-sectorStartAddr+newDataLength;i++)
dataContainer[i] = pNewData[i-startGlobalAddr+sectorStartAddr];
result = HDL_Flash_DFlash_EraseMultiSectors(sectorStartAddr,sectorStartAddr);
result = HDL_Flash_DFlash_ProgramMultiSectors(sectorStartAddr,dataContainer,DFLASH_SECTOR_SIZE);
return result;
}
flash.h
#ifndef _HDL_FLASH_H_
#define _HDL_FLASH_H_
#define FLASH_BOOT_SEQUENCE_ERROR (-2)
#define FLASH_ADDRESS_ERROR (-3)
#define FLASH_ERASE_ERROR (-4)
#define FLASH_PROGRAM_ERROR (-5)
#define FLASH_VERIFICATION_ERROR (-6)
#define FLASH_DATALENGTH_ERROR (-8)
#define FLASH_NOTAVAIL_ERROR (-9)
#define FLASH_PROTECTED_ERROR (-10