我被告知每个STM32F103RET设备都带有一个唯一的设备ID.如果检索ID的过程是什么?我正在运行一个系统,其中我与多个STM borads进行通信.为了区分每个STM板,我可以使用这个唯一的Id.谢谢
您可以在STM32F103参考手册中找到此信息.更具体地说,您想要阅读第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;
};
Run Code Online (Sandbox Code Playgroud)
如何阅读它取决于您(取决于您使用的框架,例如在libopencm3中,您有MMIO32宏).一般情况下,我会这样做:
#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);
}
Run Code Online (Sandbox Code Playgroud)
您还需要一个功能来比较两个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;
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
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;
}
Run Code Online (Sandbox Code Playgroud)
据我了解你的情况:
下图说明了用于ID传输的I2C总线的情况.

对于板1,您将执行GPIO1中断处理程序,用于板2 - GPIO 2中断处理程序.因此,您知道哪一个要求设备ID.因此,将一次获得一个设备ID.从这里你可以弄清楚如何存储这些ID.我建议使用常规数组:
struct u_id device_ids[2];
Run Code Online (Sandbox Code Playgroud)
这是伪代码,显示如何填充此数组:
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);
}
Run Code Online (Sandbox Code Playgroud)
(isr代表中断服务程序,与中断处理程序相同).
如果您确定您的两个客户端板已经准备好进行I2C传输,而主板会要求它们提供ID,那么您可以摆脱2条GPIO线路,只需使用主板上的I2C事务处理即可.