【0基础嵌入式学习日志】Day02:函数封装、结构体指针与传感器阈值判断

发布时间:2026/6/26 2:09:03
【0基础嵌入式学习日志】Day02:函数封装、结构体指针与传感器阈值判断 一、前言今天继续进行嵌入式 C 语言基础学习。Day01 主要完成了最基础的 C 工程结构搭建包括 include、src、build 目录划分头文件定义GCC 编译和 GitHub 上传。Day02 的学习重点是进一步把代码写得更像真实工程包括函数封装、结构体指针传参、传感器数据模拟、故障阈值判断以及 Makefile 自动编译。本次练习的目标不是写复杂功能而是理解嵌入式软件中常见的基本流程系统初始化 → 传感器数据更新 → 故障判断 → 状态输出二、Day02 工程结构本次 Day02 工程目录如下day02├── Makefile├── include│ ├── fault_code.h│ └── system_type.h├── src│ └── main.c└── build└── day02_test其中include用于存放头文件src用于存放源文件build用于存放编译生成的可执行文件Makefile用于自动执行 GCC 编译命令README.md用于记录项目说明。相比 Day01Day02 不再只是简单地把所有代码都写在 main() 函数中而是将不同功能拆分为多个函数使代码结构更加清晰。三、系统状态结构体 system_type.h首先在 day02/include/system_type.h 中定义系统状态结构体#ifndefSYSTEM_TYPE_H#defineSYSTEM_TYPE_Htypedefstruct{intled_state;floatvoltage;floatcurrent;floattemperature;unsignedintfault_code;}SystemStatus;#endif这里定义了一个结构体 SystemStatus用于统一管理系统状态。结构体中包含led_stateLED 状态voltage传感器电压current传感器电流temperature传感器温度fault_code系统故障码。使用结构体的好处是可以将系统相关数据集中管理而不是分散定义多个变量。例如SystemStatus sys;这样 sys 就代表当前系统的整体状态。四、故障码定义 fault_code.h然后在 day02/include/fault_code.h 中定义故障码#ifndefFAULT_CODE_H#defineFAULT_CODE_H#defineFAULT_NONE0x0000#defineFAULT_LOW_VOLTAGE0x0001#defineFAULT_OVER_CURRENT0x0002#defineFAULT_OVER_TEMP0x0004#defineFAULT_SENSOR_ERROR0x0008#endif这些故障码采用宏定义的方式表示。其中FAULT_NONE 表示无故障FAULT_LOW_VOLTAGE 表示低电压故障FAULT_OVER_CURRENT 表示过电流故障FAULT_OVER_TEMP 表示过温故障FAULT_SENSOR_ERROR 表示传感器异常故障。这里使用 0x0001、0x0002、0x0004 这类数值是为了通过不同 bit 位表示不同故障状态。这样一个 fault_code 变量就可以同时记录多个故障。例如fault_code 0x0001 | 0x0002 | 0x0004;最终结果为fault_code 0x0007表示同时存在低电压、过电流和过温故障。五、主程序 main.cDay02 的主程序放在 day02/src/main.c 中。首先引入头文件#includestdio.h#includesystem_type.h#includefault_code.h其中stdio.h 用于使用 printf() 输出信息system_type.h 用于使用 SystemStatus 结构体fault_code.h 用于使用故障码宏定义。六、系统初始化函数第一个函数是系统初始化函数voidsystem_init(SystemStatus*sys){sys-led_state0;sys-voltage12.5f;sys-current1.2f;sys-temperature35.6f;sys-fault_codeFAULT_NONE;}该函数的作用是给系统状态赋初始值。这里使用了结构体指针SystemStatus *sys在函数内部通过sys-voltage访问结构体成员。需要注意的是结构体变量访问成员使用 .结构体指针访问成员使用 -例如sys.voltage用于普通结构体变量sys-voltage用于结构体指针。七、传感器数据更新函数第二个函数是传感器数据更新函数voidsensor_update(SystemStatus*sys){sys-voltage9.5f;sys-current2.5f;sys-temperature72.0f;}该函数用于模拟传感器采集到的新数据。这里故意设置了三个异常值电压 9.5V低于阈值 10.0V电流 2.5A高于阈值 2.0A温度 72.0℃高于阈值 60.0℃。这样后续故障检测函数就可以触发对应故障。八、故障检测函数第三个函数是故障检测函数voidfault_check(SystemStatus*sys){sys-fault_codeFAULT_NONE;if(sys-voltage10.0f){sys-fault_code|FAULT_LOW_VOLTAGE;}if(sys-current2.0f){sys-fault_code|FAULT_OVER_CURRENT;}if(sys-temperature60.0f){sys-fault_code|FAULT_OVER_TEMP;}}该函数主要完成三个判断电压 10.0V → 低电压故障电流 2.0A → 过电流故障温度 60.0℃ → 过温故障其中这句代码比较关键sys-fault_code | FAULT_LOW_VOLTAGE;| 表示在原有故障码基础上增加一个故障位。这样做的好处是可以让一个 fault_code 同时保存多个故障状态而不是只能表示单一故障。九、系统状态打印函数第四个函数是系统状态打印函数voidsystem_print(constSystemStatus*sys){printf(LED state: %d\n,sys-led_state);printf(Voltage: %.2f V\n,sys-voltage);printf(current: %.2f A\n,sys-current);printf(Temperature: %.2f C\n,sys-temperature);printf(Fault code: 0x%04X\n,sys-fault_code);if(sys-fault_codeFAULT_LOW_VOLTAGE){printf(Fault: Low voltage\n);}if(sys-fault_codeFAULT_OVER_CURRENT){printf(Fault: Over current\n);}if(sys-fault_codeFAULT_OVER_TEMP){printf(Fault: Over temperature\n);}if(sys-fault_codeFAULT_NONE){printf(System normal\n);}}该函数主要用于打印系统状态和具体故障信息。这里使用sys-fault_code FAULT_LOW_VOLTAGE判断故障码中是否包含低电压故障。需要注意| 用于设置故障位 用于判断故障位这两个符号是本次练习中非常重要的内容。十、主函数流程最后在 main() 函数中调用前面定义好的函数intmain(void){SystemStatus sys;system_init(sys);sensor_update(sys);fault_check(sys);system_print(sys);return0;}整体流程如下定义系统状态变量 syssystem_init(sys)初始化系统状态sensor_update(sys)模拟传感器数据更新fault_check(sys)根据阈值判断故障system_print(sys)打印系统状态和故障信息这里的 sys 表示取 sys 的地址并传给函数。十一、GCC 编译方式一开始使用 GCC 手动编译gcc day02/src/main.c -Iday02/include-Wall-Wextra-oday02/build/day02_test其中gcc调用 GCC 编译器day02/src/main.c指定源文件-Iday02/include指定头文件目录-Wall开启常见警告-Wextra开启更多警告-o day02/build/day02_test指定输出文件。运行程序./day02/build/day02_test十二、Makefile 自动编译手动输入 GCC 命令比较长因此进一步学习了 Makefile。day02/Makefile 内容如下CCgcc CFLAGS-Wall-Wextra-Iinclude TARGETbuild/day02_test SRCsrc/main.c all:$(CC)$(SRC)$(CFLAGS)-o $(TARGET)run:./$(TARGET)clean:rm-f $(TARGET)这里CC gcc 表示使用 GCC 编译器CFLAGS 表示编译参数TARGET 表示生成的可执行文件SRC 表示源文件all 表示默认编译任务run 表示运行程序clean 表示清理编译结果。进入 day02 目录后可以直接执行make完成编译。执行makerun运行程序。执行makeclean删除编译生成的可执行文件。十三、运行结果程序运行结果如下LED state:0Voltage:9.50V current:2.50A Temperature:72.00C Fault code: 0x0007 Fault: Low voltage Fault: Over current Fault: Over temperature可以看到程序成功检测到了三个故障低电压故障过电流故障过温故障最终故障码为0x0007其含义为0x0001 | 0x0002 | 0x0004 0x0007说明多个故障可以通过一个变量同时表示。十四、遇到的问题和解决方法变量名拼写错误编译过程中遇到过类似错误SystemStatus has no member named ‘failt_code’原因是把fault_code误写成了failt_codeC 语言中变量名必须完全一致一个字母写错都会导致编译失败。修改拼写后程序可以正常编译。Makefile 找不到一开始在工程根目录直接执行make出现错误make: *** No targets specified and no makefile found. Stop.原因是 Makefile 放在 day02 文件夹中而当时终端所在位置是工程根目录。解决方法是先进入 day02 目录cd /root/Embedded_14Days/day02然后再执行makemakerun最终成功完成自动编译和运行。十六、项目源码本次 Day02 学习代码已上传至 GitHubhttps://github.com/jdai10590-afk/Embedded-C-Learning-Projects/tree/main/day02