找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 19819|回复: 5
收起左侧

STC单片机唯一的序列号MCU ID号读取程序-模拟串口通讯示例 - GetMCUID

[复制链接]
ID:91442 发表于 2015-10-29 12:54 | 显示全部楼层 |阅读模式
STC MCU都具有唯一的MCU ID号,一般保存在RAM的0xF1-F7区域,对于15系列,同时会保存在ROM的最后7个字节中。因此,可以通过字符指针,获取MCU ID值,用于程序的加密。

// 读取 STCMCU 的唯一性ID的例程
#define ID_ADDR_RAM 0xF1        //ID号的存放在RAM区的地址为0F1H
#define ID_ADDR_ROM 0x0FF9      //4K程序空间的MCU(如STC15F204EA, STC15F104EA)
unsigned char UID[8];
#define RAMID 0
#define ROMID 1
char *GetMCUID(unsigned char nType);

 //获取 MCU ID.
char *GetMCUID(unsigned char nType)
{
    unsigned char idata *iptr;
    unsigned char code *cptr;
    unsigned char i;
    unsigned char bb[8];
   
    if (nType == RAMID) {
        iptr = ID_ADDR_RAM;         //从RAM区读取ID号
        for (i=0; i<7; i++) {       //读7个字节
            UID[i] =*iptr++;      
            sprintf(bb, "%02x",(int)UID[i]); //***在 Keil C51中,如果想得到正确的2字符十六进制数输出,必须使用(int)形式做转换。
            SendStr(bb);
        }
    }
    else {
        cptr = ID_ADDR_ROM;         //从程序区读取ID号
        for (i=0; i<7; i++) {       //读7个字节
            UID[i] =*cptr++; 
            sprintf(bb, "%02X",(int)UID[i]);
            SendStr(bb);
        }
    }
    UID[7]=0;
   
    return UID;
}
实际运行的结果如下:

可以看出,RAMID都是0,但是ROM ID 是正确的。
目前的疑问是:RAM无法读取,获得的数据会发生变化。ROM区则读取正确稳定。程序使用 Keil C51 V954a 编译,采用小内存模式。问题原因未找到。
Program Size: data=100.6 xdata=0 code=2397 
 
查看该程序的M51链接内存配置文件,可以看到内存分配如下:
 TYPE    BASE      LENGTH    RELOCATION   SEGMENT NAME
            -----------------------------------------------------
            * * * * * * *   D A T A   M E M O R Y   * * * * * * *
            REG     0000H     0008H     ABSOLUTE     "REG BANK 0"
                    0008H     0018H                  *** GAP ***
            BIT     0020H.0   0001H.1   UNIT         _BIT_GROUP_
            BIT     0021H.1   0000H.5   UNIT         ?BI?STCUARTDEMO
                    0021H.6   0000H.2                *** GAP ***
            DATA    0022H     0038H     UNIT         _DATA_GROUP_
            DATA    005AH     0022H     UNIT         ?DT?STCUARTDEMO
            IDATA   007CH     0001H     UNIT         ?STACK 
目前最大的怀疑是Timer0ISR用作模拟串口,在使用时多次中断,导致堆栈增长损坏了idata区域。STC15F204EA的堆栈是向上增长的,以便初始化的栈底值最小,使用PUSH指令增加一些 数据存储时,SP的值会增大。这样可能导致IDATA的数据区0xF1-0xF7(MCUID)区被破坏。但因为无法实际做在线仿真,不能验证此原因。
回复

使用道具 举报

ID:7485 发表于 2015-10-30 17:01 | 显示全部楼层
RAM掉电不就没有了吗?
回复

使用道具 举报

ID:104984 发表于 2019-5-9 03:57 | 显示全部楼层
ahshmj 发表于 2015-10-30 17:01
RAM掉电不就没有了吗?

上电冷启动由ISP固件写入的
回复

使用道具 举报

ID:104984 发表于 2019-5-9 03:59 | 显示全部楼层
固件版本6.6.4C的单片机RAM ID可读,6.6C版本的读出来都是0
回复

使用道具 举报

ID:475845 发表于 2019-11-20 14:11 | 显示全部楼层
您好,我大致按着你的这个例子,在sprintf这里的时候,不知道为什么输出的都是错的,还有你的UID【7】=0是什么意思呢
回复

使用道具 举报

ID:881715 发表于 2021-11-16 15:34 | 显示全部楼层
cryophysics 发表于 2019-5-9 03:59
固件版本6.6.4C的单片机RAM ID可读,6.6C版本的读出来都是0

请问大神这个单片机的固件版本号是怎么看出来的呀
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表