STM32读取芯片唯一码UID
1 使用方法
STM32通过读取芯片唯一ID号来实现程序的保护,防止被抄袭。按照用户不同的用法,可以以字节(8位)为单位读取,也可以以半字(16位)或者全字(32位)读取。在这里要提醒读者,要注意大端小端模式。
通过 datasheet(STM32用户指南)来了解,打开书签,找到跟 ID有关的,终于找到了“Unique deviceID register (96 bits)”,那就是它了,错不了。



通过阅读datasheet,初步了解到,想获取 Device ID,只需要从这个地址“0x1FFF F7E8”开始12字节96bit,读取即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
typedef enum { STM32F0_, STM32F1_, STM32F2_, STM32F3_, STM32F4_, STM32F7_, STM32L0_, STM32L1_, STM32L4_, STM32H7_, } MCUTypedef;
uint32_t ID_Addr_Table[]={ [STM32F0_] = 0x1FFFF7AC, [STM32F1_] = 0x1FFFF7E8, [STM32F2_] = 0x1FFF7A10, [STM32F3_] = 0x1FFFF7AC, [STM32F4_] = 0x1FFF7A10, [STM32F7_] = 0x1FF0F420, [STM32L0_] = 0x1FF80050, [STM32L1_] = 0x1FF80050, [STM32L4_] = 0x1FFF7590, [STM32H7_] = 0x1FF0F420 };
void Get_ChipID2(void) { uint32_t id[3] = {0}; uint8_t size = sizeof(ID_Addr_Table)/sizeof(ID_Addr_Table[0]); uint32_t UID_BASE = 0x1FFF7A10 for(uint8_t i = 0; i < size; i++) { if(ID_Addr_Table[i] == UID_BASE) { id[0]=*(uint32_t*)(ID_Addr_Table[i]); id[1]=*(uint32_t*)(ID_Addr_Table[i]+4); id[2]=*(uint32_t*)(ID_Addr_Table[i]+8); printf("\r\n芯片的唯一ID为: %08X-%08X-%08X\r\n",id[0], id[1], id[2]); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
void getSTM32SeriesID(void) { uint32_t UIDw[3]; uint32_t HalVersion = HAL_GetHalVersion(); uint32_t REVID = HAL_GetREVID(); uint32_t DEVID = HAL_GetDEVID(); UIDw[0] = HAL_GetUIDw0(); UIDw[1] = HAL_GetUIDw1(); UIDw[2] = HAL_GetUIDw2(); printf("\r\n芯片的HAL库版本号为: %d\r\n", HalVersion); printf("\r\n芯片修订标识符为: %d\r\n", REVID); printf("\r\n芯片标识符为: %d\r\n", DEVID); printf("\r\n芯片的唯一ID为: %08X-%08X-%08X\r\n", UIDw[0], UIDw[1], UIDw[2]); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
void Get_ChipID(void) { CPU_ID[0] = *(__IO uint32_t *)(0X1FFFF7F0); CPU_ID[1] = *(__IO uint32_t *)(0X1FFFF7EC); CPU_ID[2] = *(__IO uint32_t *)(0X1FFFF7E8); printf("\r\n芯片的唯一ID为: %08X-%08X-%08X\r\n",CPU_ID[0], CPU_ID[1], CPU_ID[2]); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
void Get_UID(void) { uint8_t UID[12]; uint8_t MAC[12]; uint8_t i = 0; for(i=0; i < 8; i++) { MAC[i] = *(uint8_t *)(0x1FFFF7E8 + i); UID[i] = MAC[i]; } UID[8] = *(uint8_t *)(0x1FFFF7E8 + 8); UID[9] = *(uint8_t *)(0x1FFFF7E8 + 9); UID[10] = *(uint8_t *)(0x1FFFF7E8 + 10); UID[11] = *(uint8_t *)(0x1FFFF7E8 + 11); MAC[4] += UID[8]; MAC[5] += UID[9]; MAC[6] += UID[10]; MAC[7] += UID[11]; printf("\r\n UID: %0.2X-%0.2X-%0.2X-%0.2X\r\n",UID[8],UID[9],UID[10],UID[11]); printf("\r\n MAC: %X-%X-%X-%X\r\n", MAC[4], MAC[5], MAC[6], MAC[7]); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
void Get_UID2(void) { uint8_t i = 0; for(i=0; i<12; i++) { MAC[i] = *(uint8_t *)(0x1FFFF7E8 + i); printf(" %0.2X", MAC[i]); } if(MAC[0] == 0x30 && MAC[1] == 0xFF && MAC[2] == 0x69 && MAC[3] == 0x06 && MAC[4] == 0x4D && MAC[5] == 0x50 && MAC[6] == 0x35 && MAC[7] == 0x35 && MAC[8] == 0x39 && MAC[9] == 0x25 && MAC[10] == 0x08 && MAC[11] == 0x43) { printf("\r\n pass ok \r\n"); } else { printf("\r\n error \r\n"); } }
|
注意:STM32单片机的存储方式为小端模式。
一般的大小端:
地址从小到大,先放低字节,再放高字节:小端模式
地址从小到大,先放高字节,再放低字节:大端模式