STM32F103學(xué)習(xí)筆記(8)——讀取芯片UID和MAC地址

一翼闹、簡介

在嵌入式設(shè)備開發(fā)過程中有時會需要為設(shè)備設(shè)置唯一的ID用以標(biāo)識設(shè)備唯一,比如要求同一總線上的所有設(shè)備ID不能重復(fù)蒋纬,要求設(shè)備具體唯一的MAC地址等等猎荠。每個STM32微控制器都自帶一個96位的唯一ID,這個ID在任何情況下都是唯一且不允許修改的蜀备,這96位的ID可以以字節(jié)(8位)為單位讀取关摇,也可以以半字(16位)或全字(32位)讀取。不同型號的STM32芯片首地址不同碾阁,UID首地址也不同输虱。

在ST的相關(guān)資料中,對其功能的描述有3各方面:

  • 用作序列號(例如 USB 字符串序列號或其它終端應(yīng)用程序)
  • 在對內(nèi)部 Flash 進(jìn)行編程前將唯一 ID 與軟件加密原語和協(xié)議結(jié)合使用時用作安全密鑰以提高 Flash 中代碼的安全性
  • 激活安全自舉過程等

由上圖可知瓷蛙,在STM32F1xx的數(shù)據(jù)手冊中關(guān)于UID的描述有(從0x1FFFF7E8地址開始的12個字節(jié)96bit)

在不同系列的MCU中地址是有差別的悼瓮,如下圖:

二、獲取芯片UID

uint32_t GetUid(uint8_t* pUid)
{
    uint32_t chipId[3] = {0};
        
    //獲取CPU唯一ID
    #if 0//STM32F1系列
    chipId[0] =*(volatile unsigned long *)(0x1ffff7e8); //按全字(32位)讀取
    chipId[1] =*(volatile unsigned long *)(0x1ffff7ec);
    chipId[2] =*(volatile unsigned long *)(0x1ffff7f0);
    #endif
    
    #if 1//STM32F4系列
    chipId[0]=*(volatile unsigned long *)(0x1fff7a10);
    chipId[1]=*(volatile unsigned long *)(0x1fff7a14);
    chipId[2]=*(volatile unsigned long *)(0x1fff7a18);
//  /* printf the chipid */
//  printf("\r\n芯片的唯一ID為: %X-%X-%X\r\n",
//              chipId[0],chipId[1],chipId[2]);
//  printf("\r\n芯片flash的容量為: %dK \r\n", *(uint16_t *)(0X1FFF7a22));
    #endif
    
    //按字節(jié)(8位)讀取
    pUid[0] = (uint8_t)(chipId[0] & 0x000000FF);
    pUid[1] = (uint8_t)((chipId[0] & 0xFF00) >>8);
    pUid[2] = (uint8_t)((chipId[0] & 0xFF0000) >>16);
    pUid[3] = (uint8_t)((chipId[0] & 0xFF000000) >>24);
    
    pUid[4] = (uint8_t)(chipId[1] & 0xFF);
    pUid[5] = (uint8_t)((chipId[1] & 0xFF00) >>8);
    pUid[6] = (uint8_t)((chipId[1] & 0xFF0000) >>16);
    pUid[7] = (uint8_t)((chipId[1] & 0xFF000000) >>24);
    
    pUid[8] = (uint8_t)(chipId[2] & 0xFF);
    pUid[9] = (uint8_t)((chipId[2] & 0xFF00) >>8);
    pUid[10] = (uint8_t)((chipId[2] & 0xFF0000) >>16);
    pUid[11] = (uint8_t)((chipId[2] & 0xFF000000) >>24);

    return (chipId[0]>>1)+(chipId[1]>>2)+(chipId[2]>>3);
}
uint8_t uid[12] = {0};
GetUid(uid);
for(uint8_t i = 0; i < 12; i++)
{
    printf("%02x", uid[i]);
}

三艰猬、獲取MAC地址

/**
 @brief 獲取MAC地址
 @param pMac - [out] MAC地址
 @return 無
*/
void GetMacAddress(uint8_t *pMac)
{
    uint32_t uid = 0;
    uint8_t chipId[15] = {0};
    int i = 0;

    mcuId = GetChipId(chipId);

    for(i = 0; i < 12; i++)         // 獲取ID[12]
    {
        chipId[12] += chipId[i];    
    }
    for(i=0; i<12; i++)             // 獲取ID[13]
    {
        chipId[13] ^= chipId[i];    
    }

    pMac[0] = (uint8_t)(uid & 0xF0);
    pMac[1] = (uint8_t)((uid & 0xFF00) >> 8);
    pMac[2] = (uint8_t)((uid & 0xFF0000) >> 16);
    pMac[3] = (uint8_t)((uid & 0xFF000000) >> 24);
    pMac[4] = chipId[12];
    pMac[5] = chipId[13];  
}
uint8_t mac[6] = {0};
GetMacAddress(mac);
for(uint8_t i = 0; i < 6; i++)
{
    printf("%02x", mac[i]);
}

雖然這個96位的ID是唯一的横堡,但是MAC地址卻只有48位,因?yàn)榱慨a(chǎn)有不同批次冠桃,而且采購的很隨機(jī)的話這個ID號也是不唯一的命贴,比較靠譜一點(diǎn)的還是自己在指定FLASH位置定義一個變量,這樣程序就寫死去讀這個地方的值食听,而這個地方的值我們再用別的方式去修改胸蛛,如自己寫個上位機(jī)用串口通信設(shè)置等

MAC地址的前12bit固定樱报,后面的便可以直接如此自定義設(shè)置葬项。

/**
 @brief 獲取MAC地址
 @param pMac - [out] MAC地址
 @return 無
*/
void GetMacAddress(uint8_t *pMac)
{
    pMac[0] = 0x11;    
    pMac[1] = 0x22; 
    pMac[2] = *(volatile uint8_t *)(0X800F000); 
    pMac[3] = *(volatile uint8_t *)(0X800F001);
    pMac[4] = *(volatile uint8_t *)(0X800F002);
    pMac[5] = *(volatile uint8_t *)(0X800F003);
}

使用了正點(diǎn)原子的脫機(jī)下載器,注釋掉該定義變量迹蛤,并在該處設(shè)置滾碼民珍。




? 由 Leung 寫于 2022 年 7 月 29 日

? 參考:STM32 進(jìn)階教程 9 - 芯片維一碼(UID)讀取
    如何獲取STM32 MCU的唯一ID
    讀取STM32芯片的唯一ID和MAC地址
    stm32設(shè)置唯一MAC地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市盗飒,隨后出現(xiàn)的幾起案子嚷量,更是在濱河造成了極大的恐慌,老刑警劉巖逆趣,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝶溶,死亡現(xiàn)場離奇詭異,居然都是意外死亡宣渗,警方通過查閱死者的電腦和手機(jī)抖所,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門梨州,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人部蛇,你說我怎么就攤上這事摊唇。” “怎么了涯鲁?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長有序。 經(jīng)常有香客問我抹腿,道長,這世上最難降的妖魔是什么旭寿? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任警绩,我火速辦了婚禮,結(jié)果婚禮上盅称,老公的妹妹穿的比我還像新娘肩祥。我一直安慰自己,他們只是感情好缩膝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布混狠。 她就那樣靜靜地躺著,像睡著了一般疾层。 火紅的嫁衣襯著肌膚如雪将饺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天痛黎,我揣著相機(jī)與錄音予弧,去河邊找鬼。 笑死湖饱,一個胖子當(dāng)著我的面吹牛掖蛤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播井厌,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼蚓庭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了旗笔?” 一聲冷哼從身側(cè)響起彪置,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝇恶,沒想到半個月后拳魁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡撮弧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年潘懊,在試婚紗的時候發(fā)現(xiàn)自己被綠了姚糊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡授舟,死狀恐怖救恨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情释树,我是刑警寧澤肠槽,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站奢啥,受9級特大地震影響秸仙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜桩盲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一寂纪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赌结,春花似錦捞蛋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至伤靠,卻和暖如春捣域,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宴合。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工焕梅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卦洽。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓贞言,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阀蒂。 傳聞我的和親對象是個殘疾皇子该窗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容