嵌入式软件工程师_面试题练习_01 一、C语言1、嵌入式开发中#define 宏定义和 const 常量有什么区别分别适合什么场景const 的作用域是 “定义所在的代码块”全局 const 默认内部链接需加 extern 才能跨文件但这不是本质区别。#define 是预编译阶段文本替换无类型检查可能导致歧义如#define SQUARE(x) x*x调用 SQUARE (12) 会出错const 是编译阶段的常量有类型会分配内存可被取地址支持调试。#define 适合 “宏函数”如#define MIN(a,b) ((a)(b)?(a):(b))、寄存器地址定义如#define GPIOA_BASE 0x40010800const 适合 “有类型的固定值”如const float PI 3.1415f、数组大小定义C99 后支持。2、简述指针在单片机开发里的常用场景举 1-2 个实际例子。指针的核心价值是 “直接操作内存地址”这在嵌入式中至关重要。操作寄存器如*(volatile uint32_t*)0x40010800 0x01;直接向 GPIOA 地址写值函数传参通过指针修改外部变量如void UART_Receive(uint8_t* data)接收串口数据到外部数组。3、位运算 、|、^ 在操作寄存器时分别有什么作用举例说明如何用位运算单独置位某一 IO 口。“非” 是~题目中的^是 “异或”异或的作用对某一位取反。假设 GPIOA 的 ODR 寄存器地址为0x4001080C要将第 5 位置 1输出高电平(volatile uint32_t)0x4001080C | (1 5);用|置位不影响其他位置 0(volatile uint32_t)0x4001080C ~(1 5);用~清零取反(volatile uint32_t)0x4001080C ^ (1 5);用^切换电平。4、结构体在嵌入式工程中一般用来做什么说说结构体对齐简单概念。结构体不是 “方法”而是 “自定义数据类型”用于将 “相关联的不同类型数据” 打包如传感器数据温度、湿度、时间戳。结构体对齐概念为了 CPU 高效访问结构体成员的地址会被 “对齐” 到其类型大小的整数倍如 int 占 4 字节地址需是 4 的倍数。例如struct { char a; int b; } s; 实际大小是 8 字节a 占 1 字节补 3 字节对齐b 占 4 字节而非 5 字节。5、嵌入式代码里为什么常看到 volatile 关键字它的作用是什么volatile 的作用是 “告诉编译器该变量可能被意外修改如中断、硬件寄存器禁止编译器优化如缓存到寄存器每次访问必须从内存读取”。中断服务函数中修改的全局变量如volatile uint8_t flag 0;主函数循环判断 flag 是否被中断置 1、硬件寄存器如串口接收数据寄存器需实时读取最新值。volatile 不影响地址访问而是禁止编译器将变量缓存到寄存器。二、STM32基础外设1、STM32 GPIO 八种工作模式分别是什么每种简单适用场景举出 3 个常用模式举例。输入浮空、上拉、下拉、模拟输出推挽、开漏、复用推挽、复用开漏。LED 用推挽输出可直接驱动、按键用上拉输入默认高电平按下接地变低、ADC 采集用模拟输入禁用数字电路这三个是最常用的。2、按键软硬件消抖原理分别是什么单片机里软件消抖常用什么思路硬件消抖是物理层面如 RC 电路软件消抖是延时 10-20ms 后重读电平。软件消抖除了简单延时实际开发中更常用 “定时器中断 状态机”避免阻塞主程序但基础阶段简单延时思路正确。3、NVIC 中断优先级分组是什么抢占优先级和子优先级区别两个中断同时到来怎么判定优先执行抢占优先级更重要数值越小优先级越高同抢占优先级时比较子优先级。STM32 中断优先级分组共 5 组NVIC_PriorityGroup_0 到 4分组决定抢占优先级和子优先级的位数如 Group2 是 2 位抢占 2 位子优先级。4、简述使用 CubeMX 配置一个 LED 点灯的整体步骤从新建工程到生成代码。CubeMX 是图形化配置工具核心步骤为新建工程→选择芯片型号→配置 GPIO 为推挽输出→生成工程代码→在主函数循环中用 HAL_GPIO_WritePin () 翻转电平。5、简述什么是复用功能 IO举串口 USART1 引脚复用的实例。复用 IO 是将引脚功能分配给外设而非通用 GPIO。STM32F103 中 USART1 的 TX发送是 PA9RX接收是 PA10需通过 CubeMX 配置引脚为 “USART1_TX”“USART1_RX” 复用功能。补充输入模式4 种1.浮空输入场景外接上拉 / 下拉电阻的按键、外部中断信号如红外接收、编码器 A/B 相。常用度中等。因为需要外部电阻配合但灵活性高适合对功耗不敏感的场景。2.上拉输入场景无外部上拉电阻的按键、检测外部设备是否连接如传感器默认高电平连接后拉低。常用度高。内置上拉电阻节省外部元件是按键检测的首选模式。3.下拉输入场景无外部下拉电阻的信号检测如外部设备正常工作时输出高电平故障时拉低。常用度中低。使用场景比上拉输入少因为多数外设默认空闲状态为高电平如 TTL 信号。4.模拟输入场景ADC 采集如电压、温度传感器、DAC 输出反馈部分型号。常用度高。ADC 必须用此模式而模拟传感器是嵌入式系统的常见需求。输出模式4 种1.推挽输出场景LED 驱动、继电器控制、TTL 电平通信如与 51 单片机、USB 转 TTL 模块通信。常用度极高。能输出高电平VCC和低电平GND驱动能力强可直接驱动小功率 LED是最常用的输出模式。2.开漏输出场景I2C 通信SDA/SCL 引脚需外部上拉电阻实现 “线与”、多设备电平匹配如 3.3V 单片机驱动 5V 外设通过上拉电阻到 5V。常用度高。I2C 协议是嵌入式系统的常用通信方式开漏输出是其必要条件。3.复用推挽输出场景USART 串口TX 引脚如 STM32 的 PA9 作为 USART1_TX、SPI 通信MOSI 引脚、定时器 PWM 输出如电机驱动、LED 调光。常用度极高。外设的数字信号输出几乎都用复用推挽比如串口通信、PWM 是项目核心功能。4.复用开漏输出场景很少单独使用极端情况如 “USART 串口在 I2C-like 多机通信中需实现总线竞争时的电平拉低”实际几乎不用。常用度极低。因为多数外设USART、SPI需要高电平驱动能力复用推挽已满足需求开漏的复用模式显得冗余。总结最常用的 5 种上拉输入按键、模拟输入ADC、推挽输出LED、开漏输出I2C、复用推挽输出串口、PWM。原因是这些模式覆盖了 “数字输入检测、模拟信号采集、通用数字输出、总线通信、外设信号输出” 等核心需求。较少用的 3 种浮空输入需外部电阻、下拉输入场景有限、复用开漏输出外设几乎不需要。主要因为它们要么增加硬件成本要么适用场景狭窄可被其他模式替代。三、通信协议1、简述 UART 串口异步通信原理起始位、停止位、校验位作用异步通信靠波特率同步无独立时钟线。起始位是 1 个低电平打破空闲高电平通知接收方开始采样停止位是 1-2 个高电平标志一帧结束校验位是对数据位奇偶性校验如奇校验数据位 校验位 1 的个数为奇数减少传输错误。2、I2C 总线线与原理为什么只能开漏 上拉寻址机制简单说明线与是多个开漏引脚并联任何设备输出低电平总线就为低所有设备高阻时上拉电阻拉成高电平。若用推挽多个高电平输出没问题但一个低电平会和其他高电平形成短路所以必须开漏 上拉。寻址机制是主机发送 7 位从机地址 1 位读写位对应从机应答后建立通信。3、SPI 四种时钟极性 CPOL、相位 CPHA 区别简述主从通信流程CPOL时钟空闲极性0 为空闲高电平1 为空闲低电平CPHA采样相位0 在时钟第一个边沿采样1 在第二个边沿采样。四种组合如 CPOL0, CPHA0空闲高上升沿采样。主从流程主机拉低从机片选→发送时钟→主机通过 MOSI 发数据从机通过 MISO 发数据→传输结束拉高片选。4、ADC 模拟输入为什么不能用浮空 / 推挽模式单次转换和连续转换区别浮空输入会因电磁干扰导致电平波动推挽输出会让数字电路的高低电平直接加载到模拟引脚破坏模拟信号。单次转换触发一次转换一次转换完成后停止适合低频率采样如按键电压检测连续转换触发后持续转换适合高频率采样如声音信号采集。5、项目中 UART、I2C、SPI 分别适合什么外设举例选型。UART适合远距离、低速率通信如 GPS 模块、蓝牙模块HC-05。I2C适合多设备、短距离通信如 OLED 显示屏SSD1306、温湿度传感器SHT30DHT11 实际是单总线。SPI适合高速率、全双工通信如 SD 卡、LCD 触摸屏ILI9341、ADC 芯片ADS1256。补充“线与” 其实是电路里的一种连接逻辑。简单说就是把多个设备的 I2C 数据线或时钟线直接连在一起形成一条公共总线。这时候只要总线上有一个设备输出低电平整条总线就会被拉成低电平只有当所有设备都输出高阻态时总线才会被上拉电阻拉成高电平。这种 “多个设备共同控制总线电平低电平优先” 的机制就是 I2C 的线与原理。而开漏输出 上拉电阻正是为了实现这个逻辑。如果用推挽输出当一个设备输出低电平另一个输出高电平时就会形成短路损坏芯片。开漏输出只能拉低电平无法主动输出高电平高电平需要靠外部上拉电阻实现这样就避免了短路问题完美支持多设备线与连接。寻址机制方面I2C 通信时主机先发送一个 7 位的从机地址紧接着是 1 位读写位。总线上所有从机都会接收这个地址并与自己的地址进行比较。如果地址匹配该从机就会发送一个应答信号给主机之后主机和这个被选中的从机就可以进行数据传输了。高阻态可以理解成引脚 “悬空” 的状态。这时候引脚既不输出高电平也不输出低电平相当于和芯片内部的电路断开了连接对外呈现出非常高的电阻。在 I2C 总线里当设备不需要控制总线电平时就会让引脚进入高阻态这时候总线电平就由上拉电阻来决定了。“开漏输出” 里的 “漏” 指的是 MOS 管的漏极。开漏输出的电路结构简单说就是芯片内部的驱动管是 N 沟道 MOS 管这个 MOS 管的漏极直接接到芯片引脚源极接地而漏极没有直接接电源。当要输出低电平时MOS 管导通引脚通过导通的 MOS 管接地呈现低电平当要输出高电平时MOS 管截止引脚就相当于悬空高阻态这时候需要外部接一个上拉电阻到电源引脚才能通过上拉电阻获得高电平。因为输出结构中 MOS 管的漏极是 “开路” 的没有直接连电源所以叫开漏输出。SPI 是串行外设接口比 I2C 快常用 4 根线SCK时钟线主机发、MOSI主机输出从机输入、MISO主机输入从机输出、SS片选线主机选从机低电平有效。四种模式由 CPOL 和 CPHA 决定CPOL 是时钟空闲电平0 为低1 为高CPHA 是数据采样时刻0 在 SCK 第一个边沿采样1 在第二个边沿采样。比如模式 0CPOL0CPHA0空闲时 SCK 低主机在 SCK 上升沿发送数据从机在上升沿采样下降沿时从机发送数据主机采样。主从通讯流程主机拉低目标从机的 SS 线选中它然后通过 SCK 发送时钟同时在 MOSI 上发送数据从机通过 MISO 返回数据通讯结束主机拉高 SS 线释放从机。四、裸机架构与调试1、简述轮询、中断两种裸机程序架构优缺点什么场景选轮询、什么场景用中断高频短耗时、简单 IOLED、简单按键适合轮询突发异步信号串口接收、外部按键触发、传感器瞬时信号、低触发频次外设用中断。轮询优点→逻辑简单、无中断嵌套 / 临界区问题、调试方便缺点→空耗 CPU实时性差。中断优点→CPU 空闲时做别的任务事件来了才处理实时性强缺点→中断嵌套、临界资源冲突、代码调试难度大。2、裸机里状态机编程是什么简单举例用状态机处理按键长按 / 短按。状态机是把按键拆分多个固定状态根据按键电平切换状态和烧录程序、上位机无关。标准按键四态空闲态→按下消抖态→短按判定态→长按判定态靠系统滴答计时切换状态。3、串口作为调试口在裸机项目有哪 4 种常用调试用法标准串口四大调试用途打印变量、日志追踪程序运行流程上位机下发指令控制单片机外设上报传感器采集数据验证采样正确性崩溃打印出错信息定位死机 BUG。4、裸机常见硬件 BUG引脚配置错误、电源不稳、晶振不起振分别排查思路引脚配置错核对寄存器、CubeMX 配置、原理图引脚万用表测引脚电平电源不稳万用表测 VCC 空载 / 带载电压查滤波电容、负载短路晶振不起振示波器测晶振引脚波形、起振电容参数、芯片晶振配置。5、同一个工程里混用轮询 中断架构会出现什么隐患如何规避核心隐患抓准数据丢失、临界资源抢占完整规避共享数据加临界区进入轮询处理共享数据前关中断处理完开中断中断函数精简只做数据标记复杂处理丢到主循环轮询五、FreeRTOS1、什么是 RTOS对比裸机程序RTOS 最大优势是什么简述任务的概念以及任务三态 / 五态分别是什么RTOS 是实时操作系统核心优势是实时性.FreeRTOS 只是 RTOS 的其中一种不能直接划等号。RTOS 对比裸机的完整优势除实时性外还支持多任务并发管理、代码模块化、低功耗、资源隔离裸机靠状态机模拟多任务实时性差、代码耦合高。三态模型基础就绪态、运行态、阻塞态;五态模型就绪态、运行态、阻塞态、挂起态、删除 / 终止态RTOS 中任务就是独立的、可被系统调度的功能单元每个任务拥有独立栈空间各司其职。2、RTOS 中队列 (消息队列) 的作用是什么一般用在什么场景和全局变量传数据相比队列有哪些优点消息队列是 RTOS 提供的数据通信缓冲区用于任务与任务、任务与中断之间传递数据。一般用于传感器数据上报、串口接收数据转发、指令下发、不同业务模块数据交互。对比全局变量的优势面试必背自带数据缓冲不会因为读写冲突丢失数据自带同步机制配合阻塞等待CPU 利用率更高数据拷贝传递多任务访问安全无需频繁手动加临界区支持定长数据、队列满 / 空阻塞策略。3、什么是二值信号量、计数信号量各自典型应用场景举例。二值信号量本质取值只有 0 和 1相当于一把 “互斥锁 / 同步标记”。场景任务同步、中断与任务同步最常用串口中断接收数据用二值信号量唤醒处理任务。计数信号量本质计数值可大于 1支持多个资源、多次触发。场景资源计数、事件计数例如多个外设共享资源、统计脉冲次数、限流控制。4、简单说下 RTOS 里任务优先级的作用高优先级任务、低优先级任务、同优先级任务的调度规则任务优先级作用决定任务被调度的先后顺序优先级越高越优先占用 CPU。高 / 低优先级调度规则高优先级就绪后会抢占低优先级任务高任务进入阻塞低任务才能运行。同优先级规则FreeRTOS 默认时间片轮转调度每个任务分配固定时间片轮流执行。5、裸机和 RTOS 开发思路有什么核心区别项目中什么时候推荐用 RTOS什么时候继续用裸机核心区别裸机是顺序执行 状态机轮询RTOS 是多任务抢占式调度。选型场景总结可直接背诵用裸机功能简单、任务少、逻辑简单、成本敏感、无高实时要求用RTOS功能复杂、多业务并发、高实时性要求、大量延时 / 等待类逻辑、代码需要模块化拆分。六、IOT1、简述 ESP32 相比传统 STM32 单片机核心优势是什么日常项目中它主要适用哪些场景集成 WiFi 蓝牙无需外接模块适合 IoT 联网场景硬件层面ESP32 是双核 32 位处理器传统 STM32 多为单核自带更大 RAM520KB能支撑更复杂的联网协议栈如 MQTT、HTTP。软件层面官方 SDK 集成了完整的 WiFi / 蓝牙驱动、LwIP 协议栈开发联网功能更高效。适用场景补充智能家居还常用于环境监测终端温湿度上传、工业传感器联网、远程控制设备如智能开关。2、ESP32 的 WiFi 两种工作模式Station (站点)、SoftAP (软路由) 分别是什么各自常用场景举例。Station 模式ESP32 作为 “客户端”连接外部 WiFi 热点如家里的路由器从而接入互联网。SoftAP 模式ESP32 自身作为 “WiFi 热点”让其他设备连接自己形成局域网。3、简单说明 TCP 协议特点为什么网络传输优先选用 TCP 而不是普通 UDP核心优势可靠性高不易丢失数据。补充 TCP 协议特点面试必背面向连接通信前需 “三次握手” 建立连接结束后 “四次挥手” 断开。可靠传输通过校验和、重传机制、流量控制、拥塞控制确保数据无差错、按序到达。为什么优先选 TCP对比 UDPUDP 无连接、不可靠丢包不重传适合实时性要求极高但可容忍丢包的场景如语音通话、视频流。IoT 设备通常传输控制指令、传感器数据要求数据准确如 “开灯” 指令不能丢因此优先用 TCP。4、简述 ESP32 实现 WiFi 联网 TCP 客户端的大致执行流程。标准流程精简版初始化 WiFi配置为 Station 模式设置要连接的 WiFi 名称SSID和密码。连接 WiFi调用 SDK 接口如esp_wifi_connect()等待连接成功获取 IP 地址。创建 TCP 客户端基于 LwIP 协议栈创建 socket指定服务器 IP 地址和端口号。连接 TCP 服务器调用connect()接口与服务器建立 TCP 连接。数据收发通过send()发送数据recv()接收服务器数据通信结束后关闭 socket。5、IoT 设备联网常见会遇到哪些问题说出 2 个并简单说排查思路。问题 1WiFi 连接失败排查① 检查 SSID / 密码是否正确区分大小写② 路由器是否开启 DHCPESP32 默认动态获取 IP③ 信号强度是否过低ESP32 远离路由器。问题 2TCP 连接断开 / 数据丢包排查① 服务器 IP / 端口是否正确、服务器是否在线② 网络环境是否有防火墙拦截③ 设备是否频繁进入低功耗模式导致 WiFi 断连。