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)區被破壞。但因為無法實際做在線仿真,不能驗證此原因。
|