如何获取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]);
    
}


转载于:https://www.cnblogs.com/xiumusheng/p/10870074.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C代码,接口简单明了,在本机测试通过可以正常读写stm32 串口设备默认是 ttyUSB0 int DemoPro(unsigned char *pdata,int len) { int ret=0; stm32isp.fd=stm32isp.open(); printf("fd:%d\n",stm32isp.fd); while(1){ if(TestLink()!=0) {ret= 1;break;} //握手失败 if(GetVersionAndCmd()!=0) {ret= 2;break;} //获取版本失败 printf("ver:%d.%d\n",stm32isp.ver>>4,stm32isp.ver&0x0f); if(stm32isp.ver!=0x22) {ret= 3;break;} //下载器的版本不对,暂时只针对2.2版本的程序 if(GetProtectState()!=0) {ret= 4;break;} //其实读取不了是不是保护的状态的 if(GetStm32TypeId()!=0) {ret= 5;break;} //获得stm32的型 printf("stm32 type:%X\r\n",stm32isp.typeid); if(ReadMemory(0x1FFFF7E8,12,(unsigned char*)stm32isp.onlyId)!=0) //读取唯一id,读取失败则解锁再读取 { printf("read id eror\n"); if(UnRdProtect()!=0) {ret= 6;break;} continue; } else printf("stm32id:%08X%08X%08X\n",stm32isp.onlyId[0],stm32isp.onlyId[1],stm32isp.onlyId[2]); if(EraseFlash()!=0) { //擦除失败 就擦除读保护 printf("Erase Chip error\n"); if(UnRdProtect()!=0) {ret= 7;break;} continue; } //if(WriteMemory(0x8000000,sizeof(testcode),testcode)!=0) {ret= 8;break;} //printf("Write Rom ok\n"); //if(EnRdProtect()!=0) {ret= 9;break;} //printf("read protect\n");1 //if(EnWrProtectX(0,2)!=0) {ret= 10;break;} //printf("write protect ok\n"); if(WriteBin2Flash(pdata, len)!=0) {ret= 8;break;} if(VerifyRom(pdata, len)!=0) {ret= 9;break;} if(EnWrProtectX(0,64)==0) { //写入写保护之后 系统会重启 if(TestLink()!=0) {ret= 1;break;} //握手失败 }else {ret= 10;break;} if(RunProgram(0x8000000)!=0) {ret= 11;break;} break; } stm32isp.release(stm32isp.fd); return ret; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值