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 1char *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)区被破坏。但因为无法实际做在线仿真,不能验证此原因。
|