【0基础嵌入式学习日志】Day01:C语言结构体、头文件与故障码实操记录
2026/6/25 13:42:53 网站建设 项目流程

【0基础嵌入式学习日志】Day01:C语言结构体、头文件与故障码实操记录

一、学习背景

最近开始系统学习嵌入式软件开发。作为0基础入门阶段,第一天主要围绕C语言工程结构、头文件引用、结构体变量、故障码定义以及GCC编译流程进行实操。

本次练习的目标不是写复杂程序,而是理解一个嵌入式小工程最基本的组织方式:

  • include目录用于存放头文件;
  • src目录用于存放源文件;
  • build目录用于存放编译后的可执行文件;
  • 通过gcc命令完成编译和运行。

二、工程目录结构

本次练习的工程目录如下:

Embedded_14Days/day01 ├── include │ └── fault_code.h ├── src │ └── main.c └── build 其中: fault_code.h:用于定义系统故障码; main.c:主程序文件; build:存放编译生成的可执行文件。 在 include/fault_code.h 中,我定义了几个常见的故障码: ```c#ifndef FAULT_CODE_H#define FAULT_CODE_H#define FAULT_NONE 0x0000#define FAULT_UART_TIMEOUT 0x0001#define FAULT_CAN_ERROR 0x0002#define FAULT_LED_ERROR 0x0004#define FAULT_SENSOR_ERROR 0x0008#define FAULT_OVER_TEMP 0x0010#define FAULT_LOW_VOLTAGE 0x0020#endif

这里使用了宏定义来表示不同类型的故障。

例如:

#define FAULT_UART_TIMEOUT 0x0001

表示串口超时故障,对应二进制最低位。

这种写法在嵌入式开发中很常见,因为一个变量可以通过不同的 bit 位同时表示多个故障状态。

四、主函数代码

在 src/main.c 中,主程序大致完成了以下功能:

定义系统状态结构体;
初始化传感器数据和故障码;
模拟产生故障;
判断系统是否存在对应故障;
打印运行结果。

代码如下:

#include<stdio.h>#include"system_type.h"#include"fault_code.h"staticvoidSystemData_Init(SystemData*sys){sys->state=SYS_STATE_INIT;sys->radar.x=0;sys->radar.y=0;sys->radar.speed=0;sys->radar.valid=0;sys->led.led_zone=0;sys->led.led_state=0;sys->sensor.voltage=0.0f;sys->sensor.current=0.0f;sys->sensor.temperature=0.0f;sys->fault_code=FAULT_NONE;}staticvoidSystemData_Print(constSystemData*sys){printf("System state: %d\n",sys->state);printf("Radar x: %d\n",sys->radar.x);printf("Radar y: %d\n",sys->radar.y);printf("Radar speed: %d\n",sys->radar.speed);printf("Radar valid: %d\n",sys->radar.valid);printf("LED zone: %d\n",sys->led.led_zone);printf("LED state: %d\n",sys->led.led_state);printf("Sensor voltage: %.2f V\n",sys->sensor.voltage);printf("Sensor current: %.2f A\n",sys->sensor.current);printf("Sensor temperature: %.2f C\n",sys->sensor.temperature);printf("Fault code: 0x%04X\n",sys->fault_code);}intmain(void){SystemData sys;SystemData_Init(&sys);sys.state=SYS_STATE_RUNNING;sys.radar.x=120;sys.radar.y=-50;sys.radar.speed=30;sys.radar.valid=1;sys.led.led_zone=2;sys.led.led_state=1;sys.sensor.voltage=12.5f;sys.sensor.current=1.2f;sys.sensor.temperature=35.6f;sys.fault_code|=FAULT_UART_TIMEOUT;sys.fault_code|=FAULT_CAN_ERROR;sys.fault_code|=FAULT_OVER_TEMP;sys.fault_code|=FAULT_LOW_VOLTAGE;SystemData_Print(&sys);return0;}

五、编译过程

在终端中进入 day01 目录,然后使用下面的命令进行编译:

gcc src/main.c-Iinclude-obuild/day01_test

这条命令的含义如下:

gcc:调用GCC编译器;
src/main.c:指定要编译的源文件;
-Iinclude:告诉编译器去 include 目录中查找头文件;
-o build/day01_test:指定输出文件的位置和名称。

编译完成后,运行程序:

./build/day01_test

六、遇到的问题

在编译过程中,我遇到了一个错误:

error: ‘FAULT_UART_TIMEOUT’ undeclared

最开始我以为是头文件没有被正确包含,后来检查发现是宏定义名字写错了。

错误写法类似:

FAULT_VART_TIMEOUT

正确写法应该是:

FAULT_UART_TIMEOUT

这个问题说明,在C语言中,宏定义名称必须完全一致。一个字母写错,编译器就无法识别。

七、今天的收获

通过今天的实操,我主要掌握了以下几点:

理解了嵌入式C工程中 include、src、build 目录的基本作用;
学会了使用头文件管理宏定义;
理解了结构体在系统状态管理中的作用;
学会了使用 gcc 命令编译带头文件目录的C程序;
认识到代码命名必须保持一致,尤其是宏定义和变量名。
八、总结

今天的内容虽然比较基础,但已经初步接触到了嵌入式软件开发中的工程化思想。相比只写单个C文件,把头文件、源文件和编译输出分开管理,更接近真实项目的开发方式。

后续计划继续学习C语言指针、数组、函数封装、Makefile以及常见外设通信接口,为后面的STM32、RTOS和驱动开发打基础。
工程目录如图

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询