×
嵌入式 > 技术百科 > 详情

【飞思卡尔 MC9S12】内部D-Flash模拟EEPROM

发布时间:2024-05-20 发布时间:
|

上一篇讲到内部Flash的读写,本篇讲述使用D-Flash模拟EEPROM。其实使用P-Flash也可以模拟,只不过D-Flash的Page更小(擦除复写占用更少时间),而且不会占用代码空间。


最近刚换工作,一直比较忙,更新会比较慢。若是需要源码可自行下载:/zixunimg/eeworldimg/download.csdn.net/download/u010875635/11435913


没有积分可以自己新建工程,下面的代码基本可以直接使用。


本篇关于Flash读写就不在赘述,跟PFlash除了Sector大小和指令不同,其余一致,后面直接贴出代码。


模拟EEPROM其实就是模拟其单字节读写功能,原理就是要修改某个Sector内某个字节的数据时,先读出这个扇区内所有数据(256Bytes)到数组,然后擦除这个Sector,再在RAM中修改那个字节的数据,最后将这个数组写回该扇区。修改多字节数据原理相似。


另外大家可以想一下,若是要往EEPROM中写入跨Sector的数组怎么办?(需要判断数组地址范围)


使用范例:


main.c


#include /* 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

{

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

{

readTmpData = (UINT16 *far)(sectorStartAddr+i);

dataContainer[i] = ((*readTmpData)>>8)&0xFF; //高位在前

dataContainer[i+1] = (*readTmpData)&0xFF;

}

//更新要写入的内容

for(i=startGlobalAddr-sectorStartAddr;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)

#define FLASH_MGSTAT_ERROR (-11)

#define FLASH_BUSY_ERROR (-12)

#define FLASH_SUCCESS (1)

//erase multiple sector

int HDL_Flash_DFlash_EraseMultiSectors(UINT32 startGlobalAddr, UINT32 endGlobalAddr);

//program multiple phrases

int HDL_Flash_DFlash_ProgramMultiSectors(UINT32 globalAddr, UINT8 * pData,UINT16 dataLength);

//erase multiple sector

int HDL_Flash_PFlash_EraseMultiSectors(UINT32 startGlobalAddr, UINT32 endGlobalAddr);

//program multiple phrases

int HDL_Flash_PFlash_ProgramMultiSectors(UINT32 globalAddr, UINT8 * pData,UINT16 dataLength);

#endif


flash.c


#include /* common defines and macros */

#include "derivative.h" /* derivative-specific definitions */

#include "Typedefs.h"

#include "flash.h"

#include "string.h"

/*

默认情况下(ROMHM=0 RAMHM=0)Global Memory Map 如下:

0x000000-0x0007FF Registers 2KB

0x000800-0x000FFF 2K RAM , 扩展空间CS3

0x001000-0x0FDFFF 253*4K Paged RAM

0x0FE000-0x0FFFFF 8K RAM(2*4K)

0x100000-0x13FBFF 255*1K Paged EEPROM

0x100000-0x1003FF 1K (EPAGE 0x00)

……

0x103C00-0x103FFF 1K (EPAGE 0x1F)

---

0x13F000-0x13F3FF 1K (EPAGE 0xFC) --

0x13F400-0x13F7FF 1K (EPAGE 0xFD) | RAM Bufferd

0x13F800-0x13FBFF 1K (EPAGE 0xFE) |

0x13FC00-0x13FFFF 1K EEPROM(EPAGE 0xFF) --

0x140000-0x1FFFFF 扩展空间CS2

0x200000-0x3FFFFF 扩展空间CS1

0x400000-0x7F3FFF 253*16K Paged Flash, 扩展空间CS0

0x700000-0x73FFFF B3(256KB)

0x740000-0x77FFFF B2(256KB)

0x780000-0x79FFFF B1S(128KB)

0x7A0000-0x7BFFFF B1N(128KB)

0x7C0000-0x7F3FFF B0(208KB)

0x7F4000-0x7F7FFF 16KB Flash(PPAGE 0xFD)

0x7F4000-0x7F7FFF B0(16KB)

0x7F8000-0x7FBFFF 16KB Flash(PPAGE 0xFE)

0x7F8000-0x7FBFFF B0(16KB)

0x7FC000-0x7FFFFF 16KB Flash(PPAGE 0xFF)

0x7FC000-0x7FFFFF B0(16KB)

*/

/**** P-Flash and D-Flash Commands ****/

#define ERASE_VERIFY_ALL_BLOCKS 0x01

/* Verify that all program and data Flash blocks are erased. */

/* CCOBIX end = 0 */

/* CCOB Params - NONE */

/* MGSTAT set if fault */

#define ERASE_VERIFY_BLOCK 0x02

/* Verify that a Flash block is erased. */

/* CCOBIX end = 0 */

/* CCOB Params - gpage */

/* MGSTAT set if fault */

#define ERASE_ALL_BLOCKS 0x08

/* Erase all program and data Flash blocks.

An erase of all Flash blocks is only possible when the FPLDIS, FPHDIS, and FPOPEN

bits in the FPROT register and the EPDIS and EPOPEN bits in the EPROM register are

set prior to launching the command. */

/* CCOBIX end = 0 */

/* CCOB Params - NONE */

/* MGSTAT set if fault, FPVIOL / ACCERR set where appropriate */

#define UNSECURE_FLASH 0x0B

/*Supports a method of releasing MCU security by erasing all program and data Flash

blocks and verifying that all program and data Flash blocks are erased. */

/* CCOBIX end = 0 */

/* CCOB Params - NONE */

/* MGSTAT set if fault */

#define SET_USER_MARGIN_LEVEL 0x0D

/*Spec

[1] [2] [3] [4]
飞思卡尔MC9S12内部D-Flash模拟EEPROM


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
FPGA及CPLD应用领域不断拓展