STM32微控制器有一个96位的产品唯一身份标识,在任何情况下都是唯一且不允许修改这个96位的产品唯一身份标识,可以以字节(8位)为单位读取,也可以以半字(16位)或者全字(32位)读取。
想要读取唯一ID,就需要知道它的存储地址,在不同系列的MCU中地址是有差别的,我们查询了部分MCU的资料并将其总结如下:
//读取FlashSize
uint16_t cpuGetFlashSize(void)
{
return (**(volatile u16*)(0x1FFF7A22));
// return (*(volatile u32*)(0x1FFF7A20))>>16;
}
//读取ChipID
void cpuidGetId(void)
{
mcuID[0] = *(volatile u32*)(0x1FFF7A10);
mcuID[1] = *(volatile u32*)(0x1FFF7A14);
mcuID[2] = *(volatile u32*)(0x1FFF7A18);
}
Send_data3 = ((CpuID[0]) >> 24)|0x00;
Uart1Write(&Send_data3, 1);
Send_data3 = (CpuID[0] >> 16)|0x00;
Uart1Write(&Send_data3, 1);
Send_data3 = (CpuID[0] >> 8)|0x00;
Uart1Write(&Send_data3, 1);
Send_data3 = (CpuID[0] )|0x00;
Uart1Write(&Send_data3, 1);
Send_data3 = ((CpuID[1]) >> 24)|0x00;
Uart1Write(&Send_data3, 1);
Send_data3 = (CpuID[1] >> 16)|0x00;
Uart1Write(&Send_data3, 1);
Send_data3 = (CpuID[1] >> 8)|0x00;
Uart1Write(&Send_data3, 1);
Send_data3 = (CpuID[1] )|0x00;
Uart1Write(&Send_data3, 1);
Send_data3 = ((CpuID[2]) >> 24)|0x00;
Uart1Write(&Send_data3, 1);
Send_data3 = (CpuID[2] >> 16)|0x00;
Uart1Write(&Send_data3, 1);
Send_data3 = (CpuID[2] >> 8)|0x00;
Uart1Write(&Send_data3, 1);
Send_data3 = (CpuID[2] )|0x00;
Uart1Write(&Send_data3, 1);
通过串口发送到PC就可以看到了。
串口发送程序;
printf("CPUID IS 0X%X %X %X.\r\n", mcuID[0], mcuID[1], mcuID[2] );
printf("Flash size is %d KB\r\n",cpuGetFlashSize());
也可以通过 STLink Utility 查看
利用STM32的ID编码结合来进行产品加密,产品唯一的身份标识非常适合:
● 用来作为序列号(例如USB字符序列号或者其他的终端应用)
● 用来作为密码,在编写闪存时,将此唯一标识与软件加解密算法结合使用,提高代码在闪存存储器内的安全性。
● 用来激活带安全机制的自举过程
96位的产品唯一身份标识所提供的参考号码对任意一个STM32微控制器,在任何情况下都是唯一的。用户在何种情况下,都不能修改这个身份标识。
这个96位的产品唯一身份标识,按照用户不同的用法,可以以字节(8位)为单位读取,也可以以半字(16位)或者全字(32位)读取。
基地址:0x1FFF F7E8
每个CPU 出厂的时候都
配置的一个ID,96 位的.这个唯一码可以利用作软件加密.......
static u32 CpuID[3];
static u32 Lock_Code;
void GetLockCode(void)
{
//获取CPU唯一ID
CpuID[0]=*(vu32*)(0x1ffff7e8);
CpuID[1]=*(vu32*)(0x1ffff7ec);
CpuID[2]=*(vu32*)(0x1ffff7f0);
//加密算法,很简单的加密算法
Lock_Code=(CpuID[0]>>1)+(CpuID[1]>>2)+(CpuID[2]>>3);
}
示例:
STM32使用 CPUID加密算法,很简单的加密算法 Lock_Code=(CpuID[0]>>1)+(CpuID[1]>>2)+(CpuID[2]>>3); | |||||||
CpuID[0] | CpuID[1] | CpuID[2] | Lock_Code | CpuID[0]>>1 | CpuID[0]>>2 | CpuID[0]>>3 | |
1号CPU | 0668FF30 | 3037564E | 43023216 | 17A29B6D | 3347F98 | C0DD593 | 8604642 |
2号CPU | 066AFF30 | 3037564E | 43024449 | 17A39DB4 | 3357F98 | C0DD593 | 8604889 |
3号CPU | 066CFF30 | 3037564E | 43021551 | 17A497D5 | 3367F98 | C0DD593 | 86042AA |
4号CPU | 066BFF30 | 3037564E | 43024716 | 17A41E0D | 335FF98 | C0DD593 | 86048E2 |
5号CPU | 066CFF30 | 3037564E | 43023851 | 17A49C35 | 3367F98 | C0DD593 | 860470A |
6号CPU | 066DFF37 | 3235564E | 43152737 | 1826FA14 | 336FF9B | C8D5593 | 862A4E6 |
参考:
https://blog.csdn.net/ybhuangfugui/article/details/52597133
https://blog.csdn.net/foxclever/article/details/80294516