如何查找STM32F103RET的设备ID

时间:2015-03-28 23:10:05

标签: stm32 libopencm3

我被告知每个STM32F103RET设备都带有一个唯一的设备ID。如果检索ID的过程是什么?我正在运行一个系统,其中我与多个STM borads进行通信。为了区分每个STM板,我可以使用这个唯一的Id。 感谢

2 个答案:

答案 0 :(得分:6)

您可以在STM32F103 Reference Manual中找到此信息。更具体地说,您想阅读 30.2唯一设备ID寄存器(96位)章节。

因此,您的设备ID包含在只读寄存器中,名为 U_ID 。该寄存器地址为0x1ffff7e8。它的长度为96位,因此可以使用3个读取操作(例如)读取(每个32位长)。当然,你不能把它放在一个变量中。所以你应该想出一些将它存储在内存中的方法。它可以是数组,也可以是结构等。

我可能会使用结构来实现此目的,使用参考手册中描述的偏移:

#include <stdint.h>

struct u_id {
    uint16_t off0;
    uint16_t off2;
    uint32_t off4;
    uint32_t off8;
};

如何阅读取决于您(取决于您使用的是哪种框架,例如libopencm3 MMIO32 macro为此。一般情况下,我会这样做:

#define MMIO16(addr)  (*(volatile uint16_t *)(addr))
#define MMIO32(addr)  (*(volatile uint32_t *)(addr))
#define U_ID          0x1ffff7e8

/* Read U_ID register */
void uid_read(struct u_id *id)
{
    id->off0 = MMIO16(U_ID + 0x0);
    id->off2 = MMIO16(U_ID + 0x2);
    id->off4 = MMIO32(U_ID + 0x4);
    id->off8 = MMIO32(U_ID + 0x8);
}

您还需要一个比较两个ID的功能。您可以使用memcmp()或某些自定义函数。在这种情况下,我更喜欢自定义的:

#include <stdbool.h>

/* Returns true if IDs are the same */
bool uid_cmp(struct u_id *id1, struct u_id *id2)
{
    return id1->off0 == id2->off0 &&
           id1->off2 == id2->off2 &&
           id1->off4 == id2->off4 &&
           id1->off8 == id2->off8;
}

你可以这样使用它:

int main(void)
{
    struct u_id id1 = { 0x0, 0x1, 0x2, 0x3 };
    struct u_id id2;
    bool same_id;

    uid_read(&id2);
    same_id = uid_cmp(&id1, &id2);

    printf("%s\n", same_id ? "equal" : "not equal");
    return 0;
}

更新

据我了解你的情况:

  1. 您的每个电路板都应向您的主板发送一些interrupt(更具体地说,发送到主板上的GPIO引脚)。
  2. 一旦主板收到中断,它就会启动传输(请求)到中断来自的板(可能使用I2CSPIUART或类似的东西在板之间进行通信)
  3. 然后客户委员会用它的设备ID回复。
  4. 按顺序处理中断,因此将逐个获取设备ID。
  5. 下图说明了使用I2C总线进行ID传输的情况。

    Fig. 1 - Boards connections

    对于板1,您将执行GPIO1中断处理程序,用于板2 - GPIO 2中断处理程序。因此,您知道哪一个要求设备ID。因此,将一次获得一个设备ID。从这里你可以弄清楚如何存储这些ID。我建议使用常规数组:

    struct u_id device_ids[2];
    

    以下是显示如何填充此数组的伪代码:

    void gpio1_isr(void)
    {
        uint8_t i2c_buf[12];
    
        i2c_get(i2c_buf);
        memcpy(&device_ids[0], i2c_buf, 12);
    }
    
    void gpio2_isr(void)
    {
        uint8_t i2c_buf[12];
    
        i2c_get(i2c_buf);
        memcpy(&device_ids[1], i2c_buf, 12);
    }
    

    isr代表Interrupt Service Routine,与中断处理程序相同。

    如果你确定你的两个客户端板已准备好进行I2C传输,而主板会要求它们提供ID,那么你可以摆脱2条GPIO线,只需使用主板上的I2C事务到客户端。你想要的。

答案 1 :(得分:0)

打开记事本并写下:

openocd -f interface/jlink.cfg -f board/olimex_stm32_h103.cfg -c "init" -c "stm32f1x.cpu mdw 0x1FFFF7E8 3" -c "exit"

@pause

然后将其另存为“。bat” 文件,然后运行它!