最近在帮学弟学妹们看毕业设计,发现大家普遍在选题和技术实现上有点迷茫。电气工程及其自动化的毕设,不像纯软件项目,它涉及到硬件、软件、控制逻辑,甚至还要考虑现场的电磁干扰,一个环节没处理好,可能整个系统就跑不起来。今天我就结合自己的经验和一些常见案例,梳理一下从选题到落地的全流程,希望能帮你少走点弯路。

电气工程及其自动化毕业设计

1. 毕业设计里那些让人头疼的“坑”

做毕设,尤其是电气类的,最怕的不是代码难写,而是系统“玄学”般的不稳定。下面这几个痛点,估计很多人都遇到过:

  • 传感器数据“跳舞”:比如用PT100测温度,读数忽高忽低,可能不是传感器坏了,而是模拟信号在传输中被干扰了,或者供电不稳。
  • 通信“对不上暗号”:单片机发了一串数据,上位机死活收不到,或者收到一堆乱码。常见于RS485/Modbus通信中,波特率、数据位、停止位、校验位任何一项设置不匹配,通信就会失败。
  • 控制逻辑“跑飞”:写好的PLC梯形图或单片机程序,在实验室跑得好好的,一接上真实的电机或继电器,偶尔就会执行错误,甚至程序死机。这往往是强电回路对弱电控制部分的干扰造成的。
  • 软硬件“各干各的”:硬件电路焊好了,单片机程序也烧录了,上位机界面也画好了,但三者就是无法协同工作,调试起来像“黑盒”,找不到问题出在哪一层。

2. 技术方案怎么选?主流工具对比

选对工具,事半功倍。这里对比几组常见的技术路线:

嵌入式控制器:Arduino vs STM32

  • Arduino (如 Uno, Mega):优点是生态极好,库函数丰富,上手快,适合快速验证想法和逻辑控制不复杂的项目(如智能家居雏形)。缺点是性能有限,处理复杂运算或多任务时吃力,底层可控性差,不利于深入理解硬件时序和中断。
  • STM32 (如F1, F4系列):基于ARM Cortex-M内核,性能强大,外设丰富(多路ADC、高级定时器、通信接口齐全)。直接寄存器操作或使用HAL库,能让你对MCU有更深掌控,适合需要精确时序控制(如PWM生成、高速采集)、复杂算法或多种通信协议(Modbus, CAN)的项目。学习曲线稍陡,但做毕设的含金量更高。

仿真与测试:Simulink离线仿真 vs 实时HIL测试

  • MATLAB/Simulink 离线仿真:在电脑上完全用数学模型模拟被控对象(如电机、电网)和控制器。优势是安全、成本低、可以方便地调整参数和测试极端情况,非常适合理论验证和算法设计(如设计一个PID控制器)。缺点是模型和实物总有差距,无法完全模拟真实的噪声、延迟和非线性。
  • 硬件在环 (HIL) 测试:这是更高级的工程方法。用真实的控制器(如STM32开发板)运行你的控制程序,而被控对象(如电机模型)仍在Simulink中仿真,两者通过IO板卡实时交换数据。它能在不连接真实被控设备的情况下,极大程度地测试控制器的可靠性和实时性,是走向实际应用的关键一步。LabVIEW配合NI的硬件平台常用来做复杂的HIL测试。

3. 实战示例:基于Modbus RTU的智能电表数据采集系统

光说不练假把式,我们来看一个具体的、可复用的例子。这个系统在很多智能配电、能耗监控的毕设里都能用到。

系统目标:通过STM32读取智能电表(支持Modbus RTU协议)的电压、电流、功率等数据,并通过串口发送给电脑上位机显示。

硬件连接清单与说明

  • STM32F103C8T6最小系统板(核心)
  • RS485转TTL模块(如MAX485芯片模块,负责电平转换)
  • 一款支持Modbus RTU的智能电表(如国内常见的品牌)
  • 12V电源(给电表供电),5V/3.3V电源(给STM32和485模块供电)
  • 连接线若干

接线步骤

  1. 将STM32的USART2_TX (PA2) 连接至485模块的DI脚,USART2_RX (PA3) 连接至485模块的RO脚。
  2. 将STM32的一个GPIO(如PA1)连接至485模块的DE/RE脚(收发使能控制)。
  3. 485模块的A、B端子分别连接至智能电表的RS485接口A+、B-。
  4. 务必将STM32、485模块、智能电表的GND(地线)共地连接,这是通信稳定的基础。
  5. 检查电表的Modbus地址、波特率等参数(通常为9600, 8, N, 1,地址1)。

固件关键代码 (C语言,基于HAL库)

// 1. 宏定义与变量
#define RS485_DE_RE_GPIO_Port GPIOA
#define RS485_DE_RE_Pin GPIO_PIN_1
#define MODBUS_SLAVE_ADDR 0x01 // 电表地址
#define MODBUS_READ_REG 0x03 // 功能码:读保持寄存器
uint8_t txBuffer[8]; // 发送缓冲区
uint8_t rxBuffer[32]; // 接收缓冲区

// 2. 设置485为发送模式
void RS485_SetTxMode(void) {
    HAL_GPIO_WritePin(RS485_DE_RE_GPIO_Port, RS485_DE_RE_Pin, GPIO_PIN_SET); // DE/RE置高,进入发送
}

// 3. 设置485为接收模式
void RS485_SetRxMode(void) {
    HAL_GPIO_WritePin(RS485_DE_RE_GPIO_Port, RS485_DE_RE_Pin, GPIO_PIN_LOW); // DE/RE置低,进入接收
}

// 4. 构造Modbus RTU读取命令(例如读取起始地址0x0000的2个寄存器:电压)
void Modbus_BuildReadCmd(uint8_t addr, uint16_t regAddr, uint16_t regNum) {
    uint16_t crc;
    txBuffer[0] = addr; // 从机地址
    txBuffer[1] = MODBUS_READ_REG; // 功能码
    txBuffer[2] = (regAddr >> 8) & 0xFF; // 寄存器地址高字节
    txBuffer[3] = regAddr & 0xFF; // 寄存器地址低字节
    txBuffer[4] = (regNum >> 8) & 0xFF; // 寄存器数量高字节
    txBuffer[5] = regNum & 0xFF; // 寄存器数量低字节
    crc = Modbus_CRC16(txBuffer, 6); // 计算CRC校验
    txBuffer[6] = crc & 0xFF; // CRC低字节
    txBuffer[7] = (crc >> 8) & 0xFF; // CRC高字节
}

// 5. 发送并接收数据的主循环片段
void DataAcquisition_Task(void) {
    RS485_SetTxMode(); // 切换为发送
    Modbus_BuildReadCmd(MODBUS_SLAVE_ADDR, 0x0000, 2); // 读取电压数据
    HAL_UART_Transmit(&huart2, txBuffer, 8, 100); // 发送命令
    RS485_SetRxMode(); // 立即切换为接收
    HAL_UART_Receive(&huart2, rxBuffer, 7, 200); // 接收响应(根据电表协议确定长度)
    // 解析rxBuffer,提取数据...
    // 将解析后的数据通过另一个串口(如USART1)打印给上位机
}

上位机数据解析逻辑(以Python简单示例): 上位机(电脑)通过USB转TTL模块连接STM32的USART1。STM32将解析好的数据(例如已换算为实际值的电压、电流)格式化为字符串发送,如 “V:220.5,I:1.02,P:225.0\n”

import serial
import time

ser = serial.Serial('COM3', 115200, timeout=1) # 根据实际端口修改
while True:
    if ser.in_waiting:
        line = ser.readline().decode('utf-8').strip()
        if line.startswith('V:'):
            try:
                # 简单解析字符串
                parts = line.split(',')
                voltage = float(parts[0][2:])
                current = float(parts[1][2:])
                power = float(parts[2][2:])
                print(f"电压: {voltage}V, 电流: {current}A, 功率: {power}W")
                # 这里可以添加将数据存入数据库或显示在GUI的代码
            except ValueError:
                print("数据解析错误")
    time.sleep(0.1)

4. 工程化考量:稳定可靠才是王道

毕设不能只追求功能实现,系统的健壮性往往是评分的关键。

  • 实时性:对于电机控制、快速保护等场景,中断响应时间至关重要。在STM32中,要将关键任务(如ADC采样、故障检测)放在高优先级的中断服务函数里,并确保中断函数尽量简短。使用定时器触发ADC采样,而非在主循环中轮询,能保证采样间隔恒定。
  • 抗干扰能力:工业环境噪声大。除了在软件上加入数字滤波(如滑动平均、限幅滤波),硬件上更要下功夫:信号线使用双绞线、模拟电源入口加磁珠和滤波电容、关键数字信号线加施密特触发器整形、对长距离RS485通信加终端电阻(120Ω)。
  • 电源管理:系统可能涉及多个电压等级(如24V继电器、5V模块、3.3V MCU)。务必做好电源隔离和稳压。模拟部分和数字部分的电源最好用磁珠或0Ω电阻隔离。给MCU的电源一定要干净,可以在入口加TVS管防止浪涌。

5. 生产环境避坑指南(血泪经验总结)

这些细节在实验室容易忽略,但却是项目成败的关键。

  1. 接地处理是生命线:模拟地(AGND)和数字地(DGND)要单点连接。整个系统要有一个可靠的接地点,避免形成地环路引入干扰。外壳接地(保护地)与信号地要正确处理。
  2. 信号隔离不是可选项:当MCU需要控制交流接触器或大功率电机驱动器时,务必使用光耦或继电器进行隔离。否则,反向电动势或噪声很容易通过IO口烧毁你的核心板。
  3. 看门狗必须开启:无论是STM32的独立看门狗(IWDG)还是窗口看门狗(WWDG),一定要配置好并定期“喂狗”。这是防止程序跑飞导致系统死机的最后一道保险。
  4. 通信协议要加超时与重试:发送Modbus指令后,如果一定时间内没收到回复,要执行重发(比如最多3次)。连续失败后,应进入错误处理状态,而不是一直阻塞等待。
  5. 预留调试接口:在PCB设计或接线时,预留出关键测试点(如电源电压、通信信号),方便用示波器和万用表排查问题。软件里也要预留通过串口打印内部状态(如变量值、标志位)的调试代码,并用宏定义控制其开关。

电气工程及其自动化毕业设计

毕业设计是一个绝佳的工程实践机会。它考验的不仅仅是你学会了多少知识,更是你如何运用这些知识去定义问题、拆解问题并最终解决问题的能力。我的建议是,不要一开始就追求大而全的系统。先从最小可行原型(MVP)开始:用最少的硬件(一块开发板、一个传感器、一个执行机构)和最简单的代码,让核心功能先跑起来。比如,先让STM32读到传感器数据并能在串口助手显示,再考虑加上Modbus通信,然后做上位机显示,最后完善保护逻辑和抗干扰设计。每一步都稳扎稳打,调试透彻,你的毕设之路就会清晰很多。动手搭起来吧,遇到问题解决问题,这才是工程师成长的真正路径。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐