UART问题解析
一、先破误区结构体指针数组 →绝对不能直接放结构体变量先看你的代码// 结构体指针数组 struct UART_Device *g_uart_devs[] {g_stm32_uart1};1. 先分清 3 个东西核心代码写法是什么比喻struct UART_Device结构体类型图纸房子设计图g_stm32_uart1结构体变量实体真实的房子设备g_stm32_uart1结构体指针地址房子的门牌号struct UART_Device *[]结构体指针数组一本通讯录2. 关键结论结构体指针数组里面的每个格子只能存「门牌号指针 / 地址」不能直接把「房子结构体变量」塞进数组里struct UART_Device *g_uart_devs[] {g_stm32_uart1};翻译成人话我创建了一个通讯录指针数组里面只记了1 个门牌号这个门牌号指向g_stm32_uart1这个真实的串口设备。3. 为什么要这么写嵌入式必知省空间指针只有 4 字节32 位单片机结构体很大存地址更高效方便操作拿到门牌号指针就能直接找到房子设备调用它的功能统一管理所有设备的门牌号都放一起方便查找二、核心这个数组 GetUARTDevice函数 →如何互相配合我用 **「通讯录 查通讯录」** 的比喻结合你的代码一步一动讲联动逻辑前置准备两者配合的基础1. 你先造了一个「真实设备」房子// 实体结构体变量实实在在的uart1设备自带名字、方法、私有数据 static struct UART_Device g_stm32_uart1 { .name stm32_uart1, .init stm32_uart_init, .send stm32_uart_send, .recv stm32_uart_recv, .priv_data g_stm32_uart1_data, };2. 你把「设备的门牌号」放进「通讯录数组」// 指针数组 通讯录只存设备的地址门牌号 struct UART_Device *g_uart_devs[] {g_stm32_uart1};✅ 此时通讯录状态g_uart_devs[0] 门牌号 → 指向g_stm32_uart1设备正式配合上层调用GetUARTDevice函数// 指针数组 通讯录只存设备的地址门牌号 struct UART_Device *g_uart_devs[] {g_stm32_uart1};函数开始工作和数组完美联动struct UART_Device *GetUARTDevice(char *name) { int i 0; // 第一步遍历通讯录指针数组看有几个门牌号 for(i0; i(sizeof(g_uart_devs) / sizeof(g_uart_devs[0])); i) { // 第二步拿出通讯录里的第i个门牌号 → 找到对应的房子 // 第三步比对房子的名字 和 你要找的名字 if(0 strcmp(name, g_uart_devs[i]-name)) // 第四步名字匹配把这个门牌号返回给上层 return g_uart_devs[i]; } return NULL; }逐步骤联动拆解最关键步骤 1函数找数组 → 「我要查通讯录了」for循环先计算数组长度知道通讯录里有1 个门牌号。步骤 2数组给函数 → 「给你第一个门牌号」g_uart_devs[0]把g_stm32_uart1这个指针交给函数。步骤 3函数用指针 → 「通过门牌号找到房子看它的名字」g_uart_devs[i]-name→ 通过指针门牌号访问设备结构体的name成员。步骤 4名字匹配 → 函数把指针返回上层return g_uart_devs[i];→ 把这个设备的 ** 门牌号指针** 还给上层。最终结果上层拿到指针 → 就能调用这个设备的init/send/recv方法三、可视化它们的关系一眼看懂【上层应用】 ↓调用 GetUARTDevice(stm32_uart1) 【查找函数】 ↓遍历 【指针数组 g_uart_devs】 ↓存的是g_stm32_uart1 指针 【实体设备 g_stm32_uart1】 包含名字、init、send、recv、私有数据四、扩展以后加 UART2它们怎么配合你只需要加 2 行代码函数完全不用改这就是配合的强大之处// 1. 新增uart2实体设备 static struct UART_Device g_stm32_uart2 {...}; // 2. 把uart2的门牌号加入通讯录数组 struct UART_Device *g_uart_devs[] {g_stm32_uart1, g_stm32_uart2};✅ 查找函数自动遍历 2 个门牌号依旧能精准找到设备。五、终极总结两句话记住1. 结构体指针数组只能存结构体的地址指针 / 门牌号不能直接存结构体变量作用统一管理所有设备的地址相当于设备通讯录2. 数组 查找函数 的配合逻辑数组是花名册记所有设备的门牌号函数是查花名册的人函数通过遍历数组 → 拿到设备指针 → 比对名字 → 返回匹配的设备指针一句话秒懂数组负责把所有设备的「门牌号」集中存放函数负责拿着你给的名字去数组里挨个查门牌号找到对应设备就把地址还给你