向单片机flash中烧录自定义数据的方法

发布者:书卷气息最新更新时间:2018-05-05 来源: eefocus关键字:单片机  flash  烧录  自定义数据 手机看文章 扫描二维码
随时随地手机看文章

引言
    答题器项目生产时,需要在程序烧录时附带生产信息(生产时间、软件版本等)。后续若答题器出问题时,能知道是哪个批次生产的答题器,方便定位问题。

技术可行性
    答题器所用芯片nrf51822flash共256KByte,flash根本用不完,我们可以取一块没用到的flash,烧录时把生产信息也写进去。

一 HEX文件格式详解
    非常感谢这篇文章,写的非常透彻:http://www.forwhat.cn/post-240.html
    全文摘录如下:
------------------------------------摘录开始-----------------------------------------
    Hex文件是可以烧录到MCU中,被MCU执行的一种文件格式。如果用记事本打开可发现,整个文件以行为单位,每行以冒号开头,内容全部为16进制码(以ASCII码形式显示)。Hex文件可以按照如下的方式进行拆分来分析其中的内容:
例如 “:1000080080318B1E0828092820280B1D0C280D2854”可以被看作“0x10 0x00 0x08 0x00 0x80 0x31 0x8B 0x1E 0x08 0x28 0x09 0x28 0x20 0x28 0x0B 0x1D 0x0C 0x28 0x0D 0x28 0x54”
   第一个字节 0x10表示本行数据的长度;
   第二、三字节 0x00 0x08表示本行数据的起始地址;
   第四字节 0x00表示数据类型,数据类型有:0x00、0x01、0x02、0x03、0x04、0x05。
       '00' Data Rrecord:用来记录数据,HEX文件的大部分记录都是数据记录
       '01' End of File Record: 用来标识文件结束,放在文件的最后,标识HEX文件的结尾
       '02' Extended Segment Address Record: 用来标识扩展段地址的记录
       '03' Start Segment Address Record:开始段地址记录
       '04' Extended Linear Address Record: 用来标识扩展线性地址的记录
        '05' Start Linear Address Record:开始线性地址记录

   然后是数据,最后一个字节 0x54为校验和。
    校验和的算法为:计算0x54前所有16进制码的累加和(不计进位),检验和 = 0x100 - 累加和
   在上面的后2种记录,都是用来提供地址信息的。每次碰到这2个记录的时候,都可以根据记录计算出一个“基”地址。对于后面的数据记录,计算地址的时候,都是以这些“基”地址为基础的。
   HEX文件都是由记录(RECORD)组成的。在HEX文件里面,每一行代表一个记录。记录的基本格式为:
           Record mark ‘:’
           Length

Load offset

Record type

INFO or DATA

CHKSUM

1 byte

1 byte

2 bytes

1 byte

n bytes

1 byte

   看个例子:

:020000040008F2

:10000400FF00A0E314209FE5001092E5011092E5A3

:00000001FF      

   对上面的HEX文件进行分析:
   第1条记录的长度为02,LOAD OFFSET为0000,RECTYPE为04,说明该记录为扩展段地址记录。数据为0008,校验和为F2。从这个记录的长度和数据,我们可以计算出一个基地址,这个地址为(0x0008 << 16)。后面的数据记录都以这个地址为基地址。
   第2条记录的长度为10(16),LOAD OFFSET为0004,RECTYPE为00,说明该记录为数据记录。数据为FF00A0E314209FE5001092E5011092E5,共16个BYTE。这个记录的校验和为A3。此时的基地址为0X80000,加上OFFSET,这个记录里的16BYTE的数据的起始地址就是0x80000 + 0x0004 = 0x80004.
   第3条记录的长度为00,LOAD OFFSET为0000,TYPE = 01,校验和为FF。说明这个是一个END OF FILE RECORD,标识文件的结尾。
在上面这个例子里,实际的数据只有16个BYTE:FF00A0E314209FE5001092E5011092E5,其起始地址为0x0004.
------------------------------------摘录结束-----------------------------------------

二 创建自己的HEX格式文件,并烧录检验

    根据HEX文件格式详解,我们可以创建自己的hex格式 文件,方法很简单:

        step1:新建文本文件test.txt

        step2:向test.txt文件中写入hex格式数据

        step3:把文本文件.txt后缀强制转为.hex文件

        step4:如下图所示

                     

    根据"HEX文件格式详解"我们知道,这三行的意思是:向地址为0x04FC00的flash中写入8字节数据:0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88

    烧录进51822,用KEIL的DEBUG模式查看:

                

    BINGO!!!!!!!!!

三 进阶1:HEX文件加入"注释信息"

    我们构建自己的HEX文件时,有时希望像代码一样能添加"注释信息",这样即使很久以后,也能知道这些乱七八糟的二进制数,到底代表什么意思。

    从"HEX文件格式详解"中我们知道,HEX文件格式规律:

        1)必须是一整行,包括: Record mark ‘:’-  Length-Load offset-Record type-INFO or DATA-CHKSUM,从冒号到校验值,不间断;

        2)第一行必须是地址偏移的基地址,如:020000040008F2

        3)最后一行必须表示HEX文件结束,如:00000001FF      

        4)只要我们不破坏这个规律即可

    我们完全可以在一行的结束和整个hex文件结束后添加想要的"注释信息",如下:

 

    hex能烧录,且查看对应的flash值正确,BINGO!!!!!!!!!!!!!!!

    这是一个错误的示范:

 

四 进阶2:修改项目的HEX文件,添加生产信息

    我们会创建HEX文件后,在产品生产过程中,就可以烧录带生产信息的HEX文件。但是这有个弊端,就是产品在生产时需要烧录两个HEX文件(项目程序生成的HEX文件和我们自己构建带生产信息的HEX文件)。增加生产时间,浪费时间金钱。

    怎么修改项目生成的HEX文件,附带上我们需要的生产信息呢?

    方法很简答,如下图:

    


五 进阶3:如何读出HEX烧录进flash的数据

    烧录进去后,读取flash值方法有很多,不同单片机有自己的读取flash方法。

    下面介绍一种简单粗暴的方法:

    1)C语言const关键字:修饰的数据类型是常亮类型,保存在FLASH中,不可修改

    2)所以我们可定义一个const类型的指针,指向我们已知的flash地址,然后直接读出来即可


  1. const uint8_t* pFlashTest = (uint8_t *)(0xFC00);    //指针地址强制为0xFC00

  2. int main (void)

  3. {

  4. uint8_t i,FlashRead[8];

  5. for(i = 0;i < 8;i++)

  6. {

  7. FlashRead[i] = *(pFlashTest + i);            //读出烧录进去的flash数据

  8. }

  9. }

keil的DEBUG模式,测试如下,读取结果和我们写入的一致,BINGO!!!!!!!!!!!!!!!!!!!!

 

 

六 注意事项

    1)注意你写入flash的位置,不能破坏原有程序,也不能超出你芯片的flash范围。


关键字:单片机  flash  烧录  自定义数据 引用地址:向单片机flash中烧录自定义数据的方法

上一篇:飞思卡尔单片机RAM与flash相关问题
下一篇:MSP430定时/计数器TimerA的使用详解(一)

推荐阅读最新更新时间:2024-03-16 16:01

8051单片机(STC89C52)八个LED灯闪烁
#include STC89C5xRC.h void delay() { int i,j; for(i=0;i 200;i++) for(j=0;j =200;j++) { ; } } int main() { while(1) { P2 = 0xff;//八灯灭 delay(); P2 = 0;//八灯亮 delay(); } }
[单片机]
单片机程序巧用printf
当我们在调试代码时,通常需要将程序中的某个变量打印至PC机上,来判断我们的程序是否按预期的运行,printf函数很好的做到了这一点,它能直接以字符的方式输出变量名和变量的值。 printf函数在使用时,不仅仅要初始化串口,还需要其它的一些设置或者要调用其它的一些函数 否则printf函数将不能按我们想要的方式执行。 由于不同的编译器studio函数不一样,所以使用的方法也不一样,这需要大家去看编译器的help帮助选项,这里我们以STM32、51和AVR整理了几个串口打印程序,供需要的朋友参考。 1、在KEIL下使用printf函数,以STM32为例 在uart.c中添加如下代码 View Code /***
[单片机]
设计高能效 AC-DC 电源不再需要 MCU(和编码)
电网因为诸多原因而被设计成交流电,但几乎每台设备都需要直流电才能运行。 因此,AC-DC 电源几乎无处不在,随着环保意识的加强和能源价格的上涨,此类电源的效率对于降低运行成本和合理利用能源至关重要。 简单地说,效率就是输入功率与输出功率之比。但是,必须要考虑输入功率因数 (PF),即所有 AC 供电设备(包括电源)的有用(实际)功率与总(视在)功率之比。 对于纯阻性负载,PF 将为 1.00(“单位”),但随着视在功率的升高,无功负载会降低 PF,从而导致效率降低。小于 1 的 PF 由异相电压和电流引起,在开关型电源 (SMPS) 等不连续电子负载中常常会出现谐波含量高或电流波形失真的情况。 PF校正 考虑到低
[电源管理]
设计高能效 AC-DC 电源不再需要 <font color='red'>MCU</font>(和编码)
单片机c语言教程:运算符和表达式(位运算符)
学过汇编的朋友都知道汇编对位的处理能力是很强的,但是单片机C语言也能对运算对象进行按位操作,从而使单片机C语言也能具有一定的对硬件直接进行操作的能力。位运算符的作用是按位对变量进行运算,但是并不改变参与运算的变量的值。如果要求按位改变变量的值,则要利用相应的赋值运算。还有就是位运算符是不能用来对浮点型数据进行操作的。单片机c语言中共有6种位运算符。位运算一般的表达形式如下: 变量 1 位运算符 变量 2 位运算符也有优先级,从高到低依次是:“~”(按位取反)→“ ”(左移) →“ ”(右 移) →“&”(按位与)→“^”(按位异或)→“|”(按位或) 表 8-1 是位逻辑运算符的真值表,X 表示变量 1,Y 表示变量 2
[单片机]
程序烧录方式你了解多少?
说起给单片机烧录程序,大家应该都不陌生,我最早接触单片机是从51单片机开始的,型号是STC89C52RC,当时烧录程序就是用的下面这种烧录软件——STC-ISP。 这种方式,通过串口连接单片机,选择一个合适的波特率就可以烧录了。 后来学习STM32,编程时使用KEIL软件自带的下载按钮就能下载程序,方便了不少,但需要额外使用J-Link等下载器。 再后来,接触到产品研发,给已经发布出的产品升级,都是要靠远程无线升级的(想想看,产品已经到客户那里了,当软件需要升级时,要是还使用有线的方式烧录程序,得有多麻烦) 既然给单片机烧录程序的方式有多种,那烧录方式具体怎么分类呢? 可以分为3种: ISP(In-System P
[单片机]
程序<font color='red'>烧录</font>方式你了解多少?
#单片机#歌曲——世上只有妈妈
#include reg52.h #define uchar unsigned char #define uint unsigned int sbit k3=P3^5; sbit sound=P0^4; bit FY=0; //放乐曲时FY=1, 电子琴弹奏时FY=0 uchar Song_Index=0,Tone_Index=0; //放音乐的参数 uchar k, key,flag; uchar code DSY_CODE = {0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0
[单片机]
51单片机实验5:动态数码管
开发板数码管模块电路图如下: 由于74ls138译码器的特点,即只能是一个数码管的阴极电平为0,显然不能使多个数码管同时工作,若想要得到多个数码管同时工作的效果,只能采用动态扫描显示的方式。所谓动态扫描显示,就是利用发光管的余辉和人眼视觉暂留作用,使人感觉好像多个数码管在同时工作。 程序中digdisplay函数利用for循环和switch语句,不断扫描8个数码管,完成位选工作,并对P0口赋值实现段选功能。从而在8个数码管依次输出1~8,并利用延时函数控制输出间隔时间,实现动态输出的功能。 细节: (1)在每位数码管显示之后设置一定时间的延时。 (2)P0口置0(P0=0x00),完成“消影”目的。 #incl
[单片机]
51<font color='red'>单片机</font>实验5:动态数码管
基于AT91M42800A的LED显示系统设计
引 言 :   最近,笔者在某工厂大型生产线上基于现场总线的物流呼叫系统项目中发现,由于所需要显示的信息流比较大,用现有的基于AT89C51芯片组成的LED显示屏控制系统,由于受到微处理器的处理速度、体系架构、寻址范围、外围接口资源等诸多限制,已难以在要求显示较多像素、显示内容帧频较高、动态显示效果复杂的情况下,得到良好的动态视觉效果。针对以上情况,在利用现有资源的基础上,重新设计和研制了一种全新的,由32位高性能ARM微处理器组成的LED显示屏控制图1系统的硬件结构框图系统,并通过RS485接口与现场总线中的上位机进行实时数据通信,实现整个系统的信息显示。 1 系统硬件结构   该系统的硬件组成框图如图1所示。图1中,微处
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved