如何获取STM32的设备唯一ID

转载请注明出处。

STM32的全系列MCU中均有一个96位的唯一设备标识符。在ST的相关资料中,对其功能的描述有3各方面:

  • 用作序列号(例如 USB 字符串序列号或其它终端应用程序)
  • 在对内部 Flash 进行编程前将唯一 ID 与软件加密原语和协议结合使用时用作安全密钥以提高 Flash 中代码的安全性
  • 激活安全自举过程等

在资料中对其特性的描述是:96 位的唯一设备标识符提供了一个对于任何设备和任何上下文都唯一的参考号码。用户永远不能改变这些位。96 位的唯一设备标识符也可以以单字节/半字/字等不同方式读取,然后使用自定义算法连接起来。

想要读取唯一ID,就需要知道它的存储地址,在不同系列的MCU中地址是有差别的,我们查询MCU的资料并总结如下:

测试DEMO如下:

/*******获取产品唯一ID*********/
#ifdef __STM32F00x_H
#define  ID_ADDR1  0x1FFFF7AC      /*STM32F0唯一ID起始地址*/
#endif
#ifdef __STM32F10x_H
#define  ID_ADDR1  0x1FFFF7E8     /*STM32F1唯一ID起始地址*/
#endif
#ifdef __STM32F2xx_H
#define  ID_ADDR1  0x1FFF7A10         /*STM32F2唯一ID起始地址*/
#endif
#ifdef __STM32F3xx_H
#define  ID_ADDR1  0x1FFFF7AC        /*STM32F3唯一ID起始地址*/
#endif
#ifdef __STM32F4xx_H
#define  ID_ADDR1  0x1FFF7A10        /*STM32F4唯一ID起始地址*/
#endif
#ifdef __STM32F7xx_H
#define  ID_ADDR1  0x1FF0F420        /*STM32F7唯一ID起始地址*/
#endif
#ifdef  __STM32L0XX_H
#define  ID_ADDR1  0x1FF80050        /*STM32L0唯一ID起始地址*/
#endif
#ifdef __STM32L1XX_H
#define  ID_ADDR1  0x1FF80050        /*STM32L1唯一ID起始地址*/
#endif
#ifdef __STM32L4xx_H
#define  ID_ADDR1  0x1FFF7590        /*STM32L4唯一ID起始地址*/
#endif
#ifdef __STM32H7xx_H
#define  ID_ADDR1  0x1FF0F420        /*STM32H7唯一ID起始地址*/
#endif
char ID[40]; 
/*-----------------------------获取设备ID-------------------------------------*/                            
void GET_ID(void)
{
    uint8_t temp[12];
    uint32_t temp0,temp1,temp2;
    temp0=*(__IO uint32_t*)(ID_ADDR1); //产品唯一身份标识寄存器(96位)
    temp1=*(__IO uint32_t*)(ID_ADDR1+4);
    temp2=*(__IO uint32_t*)(ID_ADDR1+8);
    temp[0] = (uint8_t)(temp0 & 0x000000FF);
    temp[1] = (uint8_t)((temp0 & 0x0000FF00)>>8);
    temp[2] = (uint8_t)((temp0 & 0x00FF0000)>>16);
    temp[3] = (uint8_t)((temp0 & 0xFF000000)>>24);
    temp[4] = (uint8_t)(temp1 & 0x000000FF);
    temp[5] = (uint8_t)((temp1 & 0x0000FF00)>>8);
    temp[6] = (uint8_t)((temp1 & 0x00FF0000)>>16);
    temp[7] = (uint8_t)((temp1 & 0xFF000000)>>24);
    temp[8] = (uint8_t)(temp2 & 0x000000FF);
    temp[9] = (uint8_t)((temp2 & 0x0000FF00)>>8);  
    temp[10] = (uint8_t)((temp2 & 0x00FF0000)>>16);
    temp[11] = (uint8_t)((temp2 & 0xFF000000)>>24);
    memset(ID,0,40);    
    sprintf(ID,"%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X",temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[7],temp[8],temp[9],temp[10],temp [11]);
    
}


posted @ 2019-05-15 16:07  朽木生  阅读(3355)  评论(1编辑  收藏  举报