STC MCU都具有唯一的MCU ID號,一般保存在RAM的0xF1-F7區(qū)域,對于15系列,同時會保存在ROM的最后7個字節(jié)中。因此,可以通過字符指針,獲取MCU ID值,用于程序的加密。
// 讀取 STCMCU 的唯一性ID的例程
#define ID_ADDR_RAM
0xF1 //ID號的存放在RAM區(qū)的地址為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區(qū)讀取ID號 for (i=
0; i<
7; i++) {
//讀7個字節(jié) UID[i] =*iptr++;
sprintf(bb,
"%02x",(
int)UID[i]);
//***在 Keil C51中,如果想得到正確的2字符十六進制數(shù)輸出,必須使用(int)形式做轉換。 SendStr(bb);
}
}
else {
cptr = ID_ADDR_ROM;
//從程序區(qū)讀取ID號 for (i=
0; i<
7; i++) {
//讀7個字節(jié) UID[i] =*cptr++;
sprintf(bb,
"%02X",(
int)UID[i]);
SendStr(bb);
}
}
UID[7]=
0;
return UID;
}
實際運行的結果如下:

可以看出,RAMID都是0,但是ROM ID 是正確的。
目前的疑問是:RAM無法讀取,獲得的數(shù)據(jù)會發(fā)生變化。ROM區(qū)則讀取正確穩(wěn)定。程序使用 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區(qū)域。STC15F204EA的堆棧是向上增長的,以便初始化的棧底值最小,使用PUSH指令增加一些 數(shù)據(jù)存儲時,SP的值會增大。這樣可能導致IDATA的數(shù)據(jù)區(qū)0xF1-0xF7(MCUID)區(qū)被破壞。但因為無法實際做在線仿真,不能驗證此原因。