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

本文介绍如何利用飞思卡尔MC9S12微控制器的D-Flash来模拟EEPROM。相较于P-Flash,D-Flash具有更小的Page大小,因此在擦除和复写时效率更高,且不占用代码空间。内容包括模拟EEPROM的基本原理和操作流程,以及提供相关代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇:【飞思卡尔 MC9S12】内部Flash读写

上一篇讲到内部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
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值