历史上的今天
返回首页

历史上的今天

今天是:2025年07月16日(星期三)

正在发生

2021年07月16日 | 【飞思卡尔 MC9S12】内部D-Flash模拟EEPROM

2021-07-16 来源:eefocus

模拟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 

/*Specifies a user margin read level for all program Flash blocks. */

/* CCOBIX end = 1 */

/* CCOB Params - gpage, level setting (0-2) in CCOB[1] */

/* ACCERR set if invalid level */

 

#define SET_FIELD_MARGIN_LEVEL   0x0E 

/*Specifies a field margin read level for all program Flash blocks (special modes only). */

/* CCOBIX end = 1 */

/* CCOB Params - gpage, level setting (0-4) in CCOB[1] */

/* ACCERR set if invalid level */

 

 

 

/*-------------------------------*/

/* **** P-Flash Only Commands ****/

 

#define ERASE_VERIFY_P_FLASH_SECTION 0x03  

/*Verify that a given number of words starting at the address provided are erased. */

/* CCOBIX end = 2 */

/* CCOB Params - global address, number of phrases in CCOB[2]*/

/* MGSTAT set if fault */

 

#define READ_ONCE                0x04  

/* Read a phrase from a dedicated 64 word area in a hidden region of a programFlash block

   that was previously programmed using the Program Once command. */

推荐阅读

史海拾趣

Babcock Inc公司的发展小趣事

Babcock Inc公司的创立源于创始人对电子技术的深厚热爱和前瞻视野。在创业初期,公司便致力于电子技术的研发与创新,不断积累核心技术和专利。通过持续的技术投入和人才培养,Babcock逐渐在电子行业崭露头角,为后续的快速发展奠定了坚实的基础。

Amkor公司的发展小趣事

Babcock深知技术创新是公司发展的核心动力。因此,公司始终保持着对技术研发的持续投入。通过不断引进先进设备、优化研发流程、加强团队建设等措施,Babcock的技术实力得到了不断提升。同时,公司还注重与高校和研究机构的合作,共同推动电子技术的创新发展。

Cambridge Electronic Industries Ltd公司的发展小趣事

面对日益严峻的环境问题和社会责任,CEI积极响应可持续发展的号召。公司加大了对环保技术的研发投入,推出了多款节能、环保的电子产品。同时,CEI还关注员工福利和社会公益事业,积极参与社会捐赠和公益活动。展望未来,CEI将继续坚持技术创新和可持续发展战略,为电子行业的繁荣和发展做出更大的贡献。

通过以上五个故事,我们可以看到Cambridge Electronic Industries Ltd公司在电子行业里发展起来的艰辛与辉煌。他们凭借技术创新、市场拓展、品质管理和可持续发展等方面的努力,逐渐成为了电子行业的佼佼者。

Diode Laser Concepts公司的发展小趣事

在电子行业日益关注环保的背景下,Diode Laser Concepts公司积极响应,将环保理念融入产品设计和生产过程中。公司采用环保材料,优化生产流程,减少废弃物排放,致力于为客户提供绿色、环保的二极管激光产品。这一举措不仅提升了公司形象,也为公司赢得了更多客户的青睐。

上海双岭电子(Double-peak)公司的发展小趣事

随着科技的不断发展,电子行业面临着日新月异的技术变革。为了保持竞争优势,双岭电子始终坚持创新驱动的发展理念。公司投入大量资金用于研发新技术、新产品,并鼓励员工提出创新性的想法和建议。通过不断的创新实践,双岭电子成功推出了MOS型场效应晶体管和CMOS集成电路等高端产品,进一步巩固了公司在行业中的领先地位。

Frequency Electronics Inc公司的发展小趣事

为了进一步扩大市场份额,高频电子积极实施全球化战略。公司在全球范围内建立了销售网络和服务体系,与众多国际知名企业建立了长期合作关系。同时,高频电子还针对不同地区的市场需求,定制化开发符合当地标准的产品和服务。这些努力使得高频电子的产品和服务能够覆盖全球多个国家和地区,为公司带来了稳定的收入来源和持续增长的动力。

问答坊 | AI 解惑

电容电感滤波原理

整流电路的输出电压不是纯粹的直流,从示波器观察整流电路的输出,与直流相差很大,波形中含有较大的脉动成分,称为纹波。为获得比较理想的直流电压,需要利用具有储能作用的电抗性元件(如电容、电感)组成的滤波电路来滤除整流电路输出电压中的脉 ...…

查看全部问答>

VC++定时器的复位问题

VC++中有可以复位定时器的API吗? killTimer(3);后再SetTimer(3,100,NULL); 可以复位吗? 主要是第一个问题。 谢谢…

查看全部问答>

WinCe6运行程序后系统变慢

    俺的系统很奇怪,运行某些程序,比如摄像头抓取的程序、CorePlayer等之后系统就变慢,焦点从“我的设备”移开时图标会呈现一杠一杠的样子。     这是为啥呢?有人遇到过吗?…

查看全部问答>

关于windows矢量字库的文件格式?

请问windows矢量字库的文件格式,那里有这方面的资料!…

查看全部问答>

Redboot下写入数据在内核读取出来数据不一致?

在Redboot下更新zImage文件,写入到1M,启动内核后,使用dd if=/dev/mtdblock1 of=kernel.img bs=512 count=4578 读取nand flash该区域内容,使用ultraedit比较zImage和kernel.img,数据有不一样的地方,只是个别字节不一样。 同样,在内核下写入c ...…

查看全部问答>

如何使用VC实现多路视频采集

以前只搞过VFW单路视频采集   现在要实现多路采集一下没什么想法了 希望各位多多指教  给点思路   谢谢 …

查看全部问答>

哪位大虾用过hs5104解码

hs5104解码如何判断引导码…

查看全部问答>

STM32,IO默认状态???

                                 有谁知道IO的默认状态,刚上电,还没有初始化IO时钟,这时IO是什么样的状态?…

查看全部问答>

[TI原创]LM3S1138 测量频率、多路电压测量、信号发生

刚刚睡醒,到坛子里面逛逛,发个帖子,读书的时候弄的测量外界信号频率、多路电压测量、方波信号发生全部交互采用上位机方式实现,硬件电路未作前级的信号调理,主要是软件上实现基本功能,能够实现扩展,给需要的人参考需要设置电脑分辨率为1152*8 ...…

查看全部问答>