系统架构设计:硬件架构选型与软件分层

好,咱们进入第二章。这一章我打算聊聊系统架构设计。说实话,很多刚入行的工程师容易一上来就画框图、选芯片,结果做到一半发现资源不够用,或者外设驱动打架。我早期也吃过这个亏,所以今天咱们把这块掰开揉碎了讲。

硬件架构选型:MCU、传感器、执行器

先说说MCU选型。剃须刀自清洁系统,说白了就是个带液位检测、电机控制和定时逻辑的小型嵌入式系统。我个人的习惯是,先列需求,再选型。

MCU的核心需求:

  • 至少2路PWM输出(控制清洁电机和烘干风扇)
  • 2路ADC(检测液位传感器和温度)
  • 1路UART(调试用,量产时可以去掉)
  • 若干GPIO(按键、LED指示灯)
  • 工作温度范围:-20℃~85℃(浴室环境要考虑)

我建议选用Cortex-M0内核的MCU,比如STM32G030或者国产的GD32E230。为什么?因为这类芯片性价比高,8K RAM、64K Flash足够用,而且开发工具链成熟。我在项目中遇到过用STM32F103做类似产品的情况,说实话有点浪费,F103的CAN和USB接口根本用不上。

避坑指南: 我曾经选了一款带触摸功能的MCU做清洁控制,结果发现触摸模块在潮湿环境下误触发严重。后来老老实实换回了机械按键+防水硅胶帽的方案。所以,别为了炫技选不熟悉的外设。

传感器选型:

  • 液位传感器: 我推荐用电容式非接触液位传感器,比如XKC-Y25。为什么不用浮球式?因为清洁液有泡沫,浮球容易被卡住。电容式的贴在容器外壁就行,维护成本低。
  • 温度传感器: 用DS18B20,单总线通信,一根线搞定。注意要加4.7K上拉电阻,这个我经常忘。
  • 霍尔传感器: 检测仓门是否关闭。用A3144,便宜又皮实。

执行器选型:

  • 清洁电机: 微型直流减速电机,额定电压5V,带编码器反馈。编码器用来检测堵转,这个很重要。
  • 烘干风扇: 无刷直流风扇,PWM调速。注意选静音型的,不然用户投诉。
  • 电磁阀: 控制清洁液排放。用2W-025-08型,常闭式,断电自动关闭。

软件分层架构设计

软件架构这块,我坚持一个原则:分层清晰,模块独立。你想想看,如果所有代码都堆在main.c里,后期维护就是噩梦。我见过一个项目,一个文件写了3000行,改个定时器参数要找半天。

我习惯分三层:

层级 职责 示例文件
应用层 业务逻辑、状态机、用户交互 app_clean.c, app_ui.c
中间层 协议解析、数据缓存、算法 mid_protocol.c, mid_filter.c
驱动层 MCU外设操作、传感器读写 drv_motor.c, drv_adc.c

应用层 负责状态机。比如自清洁流程:待机→注液→清洗→排液→烘干→完成。每个状态对应一个函数,状态切换用switch-case实现。嗯,这里要注意,状态机里不要做延时阻塞,否则按键响应会卡死。

中间层 我一般放协议解析。比如上位机通过UART下发指令,格式是:0xAA 0x55 CMD LEN DATA CHECKSUM。解析完再回调应用层的处理函数。这样做的好处是,换通信协议时只改中间层,应用层不用动。

驱动层 就是直接操作寄存器。比如PWM初始化:

void drv_motor_init(void) {
    // 使能定时器时钟
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
    // 配置GPIO为复用功能
    GPIOA->AFR[0] |= (0x01 << 4);  // PA0 -> TIM2_CH1
    GPIOA->MODER |= (0x02 << 0);   // 复用模式
    // 配置PWM参数
    TIM2->PSC = 71;   // 72MHz / 72 = 1MHz
    TIM2->ARR = 999;  // 1MHz / 1000 = 1KHz
    TIM2->CCR1 = 0;   // 初始占空比0%
    TIM2->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;  // PWM模式1
    TIM2->CCER |= TIM_CCER_CC1E;  // 使能输出
    TIM2->CR1 |= TIM_CR1_CEN;     // 启动定时器
}

个人经验: 驱动层函数命名我习惯用 drv_模块_动作 的格式,比如 drv_motor_set_speed(50)。这样在应用层调用时,一眼就能看出在操作什么。

通信协议选择

剃须刀自清洁系统内部通信不多,主要是MCU和传感器、执行器之间的点对点通信。我推荐用以下方案:

  • I2C: 用于和EEPROM通信,存储用户设置(比如清洁时长、烘干温度)。AT24C02就够用,2Kbit容量。
  • 单总线: DS18B20温度传感器,一根线搞定数据读写。注意时序要求严格,建议用定时器模拟,别用delay。
  • UART: 调试用,波特率115200。量产时可以把TX/RX引脚复用为GPIO,省成本。

如果产品需要和手机APP通信(比如显示清洁进度),我建议用蓝牙BLE。选TI的CC2541或者国产的PHY6212,透传模式,MCU通过UART发AT指令控制。我在项目中用过这种方式,开发周期短,稳定性也不错。

注意: 蓝牙模块的天线布局要远离电机,否则电磁干扰会导致连接断开。我吃过这个亏,后来在PCB上加了屏蔽罩才解决。

好了,系统架构这块就聊这么多。下一章咱们深入讲讲状态机的具体实现,包括怎么处理异常情况——比如清洁液不够了怎么办?电机堵转了怎么恢复?这些实战经验到时候一并分享。