0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于APM32F407如何制作I2C EEPROM(AT24C02型号)的MDK-Keil下载算法

Geehy极海半导体 ? 来源:Geehy极海半导体 ? 2025-04-11 11:06 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

前言

最近在做的一个项目中,需要经常把一些参数下载到I2C EEPROM中,然后MCU上电去读取。如果在产品量产过程中,可以使用烧录治具往EEPROM写入一次即可。但是在调试开发阶段,需要经常修改这些数据,调试起来非常不方便。

我调试的环境是MDK-Keil,于是网上了解了下如何制作Keil的下载算法,下面介绍下基于APM32F407如何制作I2C EEPROM(AT24C02型号)的Keil下载算法,这样在我们下载代码时可以一键把数据烧录到EEPROM中。

对于 Keil 的下载算法文件相关的详细介绍可以到官方在线文档进行了解,这些文档详细介绍了下载算法的实现细节。文档链接如下:

https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/flashAlgorithm.html

1. Keil如何调用下载算法

Keil的下载算法,我的理解就是可以通过Keil去调用该下载算法,然后可以去编程各种存储设备,比如MCU内部的Flash,通过MCU外设连接外扩的SPI Flash或者I2C EEPROM等器件。

要想通过Keil IDE的下载按钮一键编程这些存储设备,那么需要有对应器件的下载算法才能去编程。对于Keil来说通过调试界面指定相应的下载算法 xxx.FLM 文件,然后就可以被调用了,如下图:

64372730-15f6-11f0-9310-92fbcf53809c.jpg

??Keil 在调试下载阶段,会把算法文件加载到芯片的内部 RAM 里面,加载的芯片内部的RAM地址和大小可以在上面的配置截图进行设置。然后就可以在 RAM 中执行这个下载算法文件的擦除、编程等函数,从而实现对存储设备下载程序或者在调试阶段读取数据等操作。

大致流程如下图:??

6445ed88-15f6-11f0-9310-92fbcf53809c.jpg

主要是分为两步:

通过SWD/JTAG调试接口,把下载算法加载到RAM。

执行下载算法的擦除、编程等函数,从而对内部Flash进行编程或者通过MCU的片上外设对外扩的SPI FLASH/I2C EEPROM执行编程操作。

另外,前面说到会把下载算法文件加载到 RAM 运行,而且我们可以设置加载到任何的 RAM 地址运行,那么对下载算法生成的代码必须是与位置无关的代码,这样才能加载到任意 RAM 地址运行。

2.Keil下载算法函数和执行流程

2.1 下载算法需要实现哪些函数

根据官方文档介绍,要制作一个新的下载算法需要实现函数有:

6453f75c-15f6-11f0-9310-92fbcf53809c.jpg

一共有7个函数,而且这些函数的原型已经规定好了的,只需要我们根据不同的存储设备实现具体的功能即可。

其中有 mandatory 修饰的函数,是制作一个新的下载算法必须要实现的函数是,而 optional 修饰的函数则可根据需要实现还是不实现。

2.2 擦除流程

6461627a-15f6-11f0-9310-92fbcf53809c.jpg

加载算法到芯片 RAM。

执行初始化函数 Init。

执行擦除操作。其中擦除操作会根据Keil的配置选项,选择是擦除整个芯片还是扇区擦除。

执行 Uinit 函数。

擦除完成。

2.3 编程流程

编程流程,就是把编译出来的可执行程序下载到Flash或者其他存储器。

646f7f86-15f6-11f0-9310-92fbcf53809c.png

对于所有 AXF 文件内容,执行 Init 初始化函数

判断 Flash 算法是否在FLM文件中。不在则编程结束,返回失败。如果编程算法存在,则执行下面操作:

(1)加载算法到RAM

(2)执行Init函数

(3)加载应用程序(待编程的数据)到RAM Buffer中

(4)执行Program Page编程函数

(5)执行Uninit函数

编程完成。

2.4 校验流程

校验就是把 AXF 文件中需要下载到Flash的数据,与实际下载到Flash的数据读出来进行比较。

648059aa-15f6-11f0-9310-92fbcf53809c.jpg

判断 Flash 算法是否在FLM文件中,不在则操作失败。如果编程算法存在,则执行下面操作:

(1)加载算法到RAM

(2)执行Init函数

(3)判断FLM文件是否存在校验算法。

存在则加载应用程序到RAM,然后执行FLM文件中的校验算法

不存在则计算和比较CRC值。把下载到Flash的数据读出来计算的CRC值,与 加载 axf 文件的数据到RAM中计算的CRC值进行比较。

执行Uninit函数

执行完 Uninit 函数后面的步骤,不是很理解,这后面的步骤是不是和调试有关的,在下载代码时并没有关系?

3. 制作Keil环境的I2C EEPROM下载算法

下面我基于APM32F407,制作AT24C02 EEPROM存储芯片的下载算法。

对于下载算法的制作流程,官网已经给出了详细的步骤,下面的步骤是从官网翻译过来的。一个新的下载算法制作步骤:

ARM:CMSIS Pack文件夹(通常为 C:KeilARMPackARMCMSIS version Device_Template_Flash)中的内容复制到新文件夹。

重命名项目文件NewDevice.uvprojx以表示新的闪存 ROM 设备名称,例如MyDevice.uvprojx

使用 uVision 打开项目。从工具栏中,使用下拉菜单选择目标”来定义处理器架构。Cortex-M适用于所有 Cortex-M0/M0+、M3 和 M4 设备。该配置假定采用小端微控制器。如果是大端微控制器,请使用Project - Options for Target - Device选择正确的处理器内核。

打开对话框“项目-目标选项-输出” ,然后更改“可执行文件名称”字段的内容以表示设备,例如MyDevice

调整文件FlashPrg中的编程算法。

调整文件FlashDev中的设备参数。

使用Project - Build Target生成新的Flash 编程算法。输出文件(例如MyDevice.FLM)必须添加到DFP中。

上面的步骤就是官网给出的,下面我们就根据官网给出的步骤制作一个新的下载算法。

3.1 准备下载算法模板

下载算法的模板,我们在安装Keil的时候就有了的。官网说在 keil 的安装目录下能找到,但是我安装的是 5.36 版本,Keil安装目录没有找到,而是在C:Users你的用户名目录AppDataLocalArmPacksARMCMSIS5.8.0Device_Template_Flash 这个目录找的的下载算法模板。

648e4b82-15f6-11f0-9310-92fbcf53809c.jpg

我们把该目录复制一份备用,然后记得把该文件夹的只读属性去掉。

3.2 Keil环境设置

1、把复制的模板工程的工程名,可以根据我们基于什么芯片制作下载算法修改一下工程名称,这样更具有辨识度。

2、修改选择的目标芯片。

649e982a-15f6-11f0-9310-92fbcf53809c.jpg

我是基于APM32F407制作下载算法文件,所以选择M4内核就行。

3、修改编译生成的下载算法文件的名称。

64b07d60-15f6-11f0-9310-92fbcf53809c.jpg

4、添加APM32F407的外设驱动库以及I2C EEPROM的读写驱动文件

由于我们是要实现 I2C EEPROM 的下载算法,在编写这些下载算法函数之前,我们必须要先确保I2C EEPROM 的驱动可以正常读写。I2C EEPROM 的驱动可以从我们实现的例程验证可行之后,然后挪过来使用即可。

64bf0c9a-15f6-11f0-9310-92fbcf53809c.jpg

3.3 修改FlashPrg.c文件中的编程算法函数

这一步是最重要的,我们实现Keil编程算法主要就是要实现 FlashPrg.c 文件中的各个下载算法函数。根据前面的介绍,一个新的下载算法必须要实现的函数有:Init/EraseSector/ProgramPage/Uninit这4个函数,其他函数可以根据需要是否实现。下面我们来一一实现这些函数。

1、Init函数的实现

/*

* Initialize Flash Programming Functions

* Parameter: adr: Device Base Address

* clk: Clock Frequency (Hz)

* fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)

* Return Value: 0 - OK, 1 - Failed

*/

int Init (unsigned long adr, unsigned long clk, unsigned long fnc)

{

/* 系统初始化 */

//SystemInit(); // 如果使用了库文件的该函数会导致下载是0x08000000地址校验失败,但是实际测试又是下载进去了。不知道什么原因

I2C_Init();

return 0;

}

在该函数中,我们可以初始化编程存储器的一些操作,比如配置时钟,GPIO的初始化等等。

2、扇区擦除和整片芯片擦除函数

/*

* Erase complete Flash Memory

* Return Value: 0 - OK, 1 - Failed

*/

int EraseChip (void)

{

volatile int i = 0;

unsigned char tmepbuf[EE_PAGE_SIZE];

unsigned char adr = 0;

for(i = 0; i < EE_PAGE_SIZE; i++)

{

tmepbuf[i] = 0xFF;

}

for (i = 0; i < EE_SIZE / EE_PAGE_SIZE; i++)

{

ee_WriteBytes(tmepbuf, adr, EE_PAGE_SIZE);

adr += EE_PAGE_SIZE;

}

return 0;

}

/*

* Erase Sector in Flash Memory

* Parameter: adr: Sector Address

* Return Value: 0 - OK, 1 - Failed

*/

int EraseSector (unsigned long adr)

{

volatile int i = 0;

unsigned char tmepbuf[EE_PAGE_SIZE];

adr -= I2C_EEPROM_ADDR;

for(i = 0; i < EE_PAGE_SIZE; i++)

{

tmepbuf[i] = 0xFF;

}

ee_WriteBytes(tmepbuf, adr, EE_PAGE_SIZE);

return 0;

}

实际上对于EEPROM芯片,不需要擦除就能写入数据的。不过为了示例,我们也实现这两个擦除函数好了。对于EERPOM来说,擦除就是往它写入0xFF数据即可。

3、ProgramPage 页编程函数实现

#define I2C_EEPROM_ADDR 0x01000000

/*

* Program Page in Flash Memory

* Parameter: adr: Page Start Address

* sz: Page Size

* buf: Page Data

* Return Value: 0 - OK, 1 - Failed

*/

int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf)

{

volatile int i = 0;

adr -= I2C_EEPROM_ADDR;

for(i = 0; i < sz/EE_PAGE_SIZE; i++)

{

ee_WriteBytes(buf+EE_PAGE_SIZE*i, adr+EE_PAGE_SIZE*i, EE_PAGE_SIZE);

}

if(sz%EE_PAGE_SIZE)

{

ee_WriteBytes(buf+EE_PAGE_SIZE*i, adr+EE_PAGE_SIZE*i, sz%EE_PAGE_SIZE);

}

return (0);

}

直接调用EEPROM的驱动写函数即可。另外 I2C_EEPROM_ADDR 这个宏定义,是为了在我们的应用代码中,定义数据时选择哪一块区域存储EEPROM的数据,地址是我们可以随意定义的。但是不能与MCU的外设地址,以及Flash、RAM等地址重合就行。

4、Uninit函数实现

该函数根据前面的Keil执行各编程流程,一般是退出编程时会被调用的,我们可以在该函数进行恢复的操作。该函数是必须实现的,如果不需要做任何动作,那么我们保持该函数为空函数就行。

/*

* De-Initialize Flash Programming Functions

* Parameter: fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)

* Return Value: 0 - OK, 1 - Failed

*/

int UnInit (unsigned long fnc) {

/* Add your Code */

return (0); // Finished without Errors

}

3.4 修改FlashDev.c文件的设备参数

在FlashDev.c文件中有一个名为FlashDevice的结构体常量,这个结构体的信息是给 Keil 提供编程设备的信息的,比如编程的起始地址,总大小,一个扇区的大小,设备类型等等信息。我们根据自己的需要编程的设备类型修改即可。

struct FlashDevice const FlashDevice = {

FLASH_DRV_VERS, // Driver Version, do not modify!

"APM32F407_I2C_EEPROM_AT24C02", // Device Name

EXTSPI, // Device Type

0x01000000, // Device Start Address. EEPROM的编程地址。

0x00000100, // Device Size in Bytes

8, // Programming Page Size

0, // Reserved, must be 0

0xFF, // Initial Content of Erased Memory

6000, // Program Page Timeout 6000 mSec

6000, // Erase Sector Timeout 6000 mSec

// Specify Size and Address of Sectors

0x000008, 0x000000, // Sector Size 8B (32 Sectors)

// 0x010000, 0x010000, // Sector Size 64kB (2 Sectors)

// 0x002000, 0x030000, // Sector Size 8kB (8 Sectors)

SECTOR_END

};

3.5 生成算法文件

我们实现了 FlashPrg.c 文件的编程算法函数之后,直接编译就可以生成 xxx.FLM 算法文件了。

在编译之前,我们需要检查生成的代码是位置无关码。在Keil设置如下:

64cd7776-15f6-11f0-9310-92fbcf53809c.jpg

C/C++和Asm选项卡都要检查是否已经勾选了上面的配置。

点击编译即可生成Keil下载算法文件。

64dd1d84-15f6-11f0-9310-92fbcf53809c.jpg

4. 新制作的下载算法文件使用和测试

1、把生成的下载算法文件放置到Keil安装的目录 C:Keil_v5ARMFlash 下待使用

64ea2506-15f6-11f0-9310-92fbcf53809c.jpg

2、Keil环境配置下载算法

64fd0a54-15f6-11f0-9310-92fbcf53809c.jpg

3、APM32F407_I2C_EEPROM算法测试验证。

我们使用下载算法下载数据到EERPOM,然后再通过应用程序读出来进行对比写进去的数据是否一致,就可以知道EEPROM下载算法是否起作用。

我们找一个 APM32F407 EEPROM 的例程进行测试。

(1)首先在例程里面定义下面待烧录到EEPROM的数据:

const uint8_t EEPROM_FLM_Test1[16] __attribute__((at(0x01000000))) = {

0xCB,0xFF,0x01,0x02,0x03,0xAA,0x06,0x07,

0x08,0x09,0x10,0xA1,0xA2,0xA3,0xA4,0xBB

};

const uint8_t EEPROM_FLM_Test2[16] __attribute__((at(0x010000A0))) = {

0x12,0x34,0x01,0x02,0x03,0xAA,0x06,0x07,

0x08,0x09,0x10,0xA1,0xA2,0xA3,0xA4,0xBB

};

其中我们规定这些数组必须链接到 0x01000000 起始的地址,这是因为我们制作的 EEPROM 的下载算法编程地址就是在该范围,这个地址会在下载算法内部转换为EEPROM 编程的 0 地址,比如说 0x01000000 起始地址,对应的就算EEPROM的0地址。

(2)然后编译下载代码到Flash和EEPROM即可。

下载代码时,检测的0x01000000地址需要下载数据,Keil就会自动调用EEPROM的下载算法把数据编程到EEPROM了。

如下在下载程序没有报错,下载完成。

650e3e32-15f6-11f0-9310-92fbcf53809c.jpg

然后运行代码,把EEPROM的数据读出来,对比是否一致。

65214cc0-15f6-11f0-9310-92fbcf53809c.jpg

《APM32芯得》系列内容为用户使用APM32系列产品的经验总结,来自21ic论坛极海半导体专区。在此特别鸣谢!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 算法
    +关注

    关注

    23

    文章

    4715

    浏览量

    95725
  • EEPROM
    +关注

    关注

    9

    文章

    1089

    浏览量

    83936
  • I2C
    I2C
    +关注

    关注

    28

    文章

    1541

    浏览量

    128151
  • keil
    +关注

    关注

    69

    文章

    1223

    浏览量

    169967
  • 极海半导体
    +关注

    关注

    0

    文章

    166

    浏览量

    4825

原文标题:APM32芯得 EP.51 | 基于APM32F407制作I2C EEPROM的MDK-Keil下载算法

文章出处:【微信号:geehysemi,微信公众号:Geehy极海半导体】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    国产优秀替代_APM32F407替代STM32F407记录

    的事情。 本文记录一下我使用APM32F407替代STM32F407制作的一个小demo(使用SPI外设读取W25Q128)。该demo使用原开发板电路
    的头像 发表于 05-10 11:22 ?2.2w次阅读
    国产优秀替代_<b class='flag-5'>APM32F407</b>替代STM32<b class='flag-5'>F407</b>记录

    APM32F407工具链使用教程

    APM32F407工具链使用教程
    的头像 发表于 10-31 17:14 ?1721次阅读
    <b class='flag-5'>APM32F407</b>工具链使用教程

    《电子发烧友电子设计周报》聚焦硬科技领域核心价值 第7期:2025.04.7--2025.04.11

    I2C EEPROMAT24C02型号)的MDK-Keil下载算法 https://www.e
    发表于 04-11 19:51

    AT24C02

    AT24C02
    发表于 01-24 16:00 ?13次下载

    I2C—读写EEPROM

    开发板,即可接收STM32串口发送给电脑的调试信息。 【*】 引脚分配 EEPROMAT24C02): EEPROM芯片的I2C接口与STM32的
    发表于 12-13 15:12 ?23次下载

    AT24C02与单片机连接的电路图免费下载

    这次利用单片机通过软件模拟I2C总线协议, 并对基于I2C协议的AT24C02 EEPROM进行读写操作, 具体说明与功能见代码注释。
    发表于 09-19 17:20 ?12次下载
    <b class='flag-5'>AT24C02</b>与单片机连接的电路图免费<b class='flag-5'>下载</b>

    EEPROM存储芯片AT24C02芯片手册

    EEPROM存储芯片AT24C02芯片手册(嵌入式开发培训需要学多久)-EEPROM存储芯片AT24C02芯片手册
    发表于 07-30 13:20 ?184次下载
    <b class='flag-5'>EEPROM</b>存储芯片<b class='flag-5'>AT24C02</b>芯片手册

    【STM32Cube_13】使用硬件I2C读写EEPROMAT24C02

    本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件I2C外设读取EEPROM数据(以AT24C02为例)。
    发表于 12-08 10:36 ?19次下载
    【STM32Cube_13】使用硬件<b class='flag-5'>I2C</b>读写<b class='flag-5'>EEPROM</b>(<b class='flag-5'>AT24C02</b>)

    STM32单片机基础13——使用硬件I2C读写EEPROMAT24C02

    本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件I2C外设读取EEPROM数据(以AT24C02为例)。1. 准备工作硬件准备开发板首先需要准备一个开发板,这里我
    发表于 12-23 19:05 ?16次下载
    STM32单片机基础13——使用硬件<b class='flag-5'>I2C</b>读写<b class='flag-5'>EEPROM</b>(<b class='flag-5'>AT24C02</b>)

    STM32f103系列i2c读写文件at24c02

    STM32f103系列i2c读写文件at24c02免费下载
    发表于 03-04 09:43 ?26次下载

    使用APM32F407替代STM32F407制作的demo

    b.在原工程下添加APM32F407的中断控制函数文件。将“APM32F
    的头像 发表于 05-10 14:37 ?5098次阅读

    使用I2C读取24cxx串行EEPROM

    Read 24cxx serial EEPROM with I2C
    发表于 06-30 15:10 ?1次下载
    使用<b class='flag-5'>I2C</b>读取<b class='flag-5'>24</b>cxx串行<b class='flag-5'>EEPROM</b>

    Linux驱动开发-编写(EEPROM)AT24C02驱动

    AT24C02是IIC接口的EEPROM存储芯片,这颗芯片非常经典,百度搜索可以找到非常多的资料,大多都是51、STM32单片机的示例代码,大多采用模拟时序、裸机系统运行。当前文章介绍在Linux
    的头像 发表于 09-17 15:29 ?4387次阅读
    Linux驱动开发-编写(<b class='flag-5'>EEPROM</b>)<b class='flag-5'>AT24C02</b>驱动

    APM32F103XE_I2C_加入六轴传感器后,I2C通讯EEPROM会挂

    APM32F103XE_I2C_加入六轴传感器后,I2C通讯EEPROM会挂
    发表于 11-09 21:03 ?0次下载
    <b class='flag-5'>APM32F103XE_I2C</b>_加入六轴传感器后,<b class='flag-5'>I2C</b>通讯<b class='flag-5'>EEPROM</b>会挂

    APM32F407 EVAL 原理图

    APM32F407 EVAL 原理图
    发表于 11-09 21:04 ?13次下载
    <b class='flag-5'>APM32F407</b> EVAL 原理图