基于STM32与Proteus的鸡蛋分类分装系统仿真设计与实现
简介本资源是一套基于STM32的鸡蛋重量分类与自动分装系统仿真方案面向嵌入式初学者、课程设计学生及自动化控制实践者解决农产品分级分装中的典型机电协同控制问题。压缩包共286个文件总计23.22MB涵盖Keil工程源码c/h/o/d等核心源文件、Proteus 8.15仿真工程pdsprj、编译输出文件hex/axf/map及配套仿真视频wmv其中C语言源码实现HX711称重采集、双传送带逻辑调度、三舵机机械臂动作时序与双电机推箱控制Proteus模型完整复现0LED显示、红外到位检测、继电器驱动及按键交互流程。已有59人学习下载资源附带可直接运行的仿真视频直观展示重量识别、等级判定、数量累加、满箱推送等全流程动作代码结构清晰、模块划分合理便于理解STM32外设驱动与多任务协同逻辑。1. 项目缘起从“捡鸡蛋”到“分鸡蛋”的自动化构想几年前我参与过一个农业自动化的小项目其中有一项任务就是处理鸡蛋。当时看着工人手动将大小不一、颜色各异的鸡蛋分拣到不同篮子里效率低不说还容易因为磕碰造成损耗。那时我就想能不能用我们熟悉的单片机做个简单的分类装置这个想法一直埋在心里。后来随着对STM32和Proteus仿真工具的深入使用我发现完全可以在电脑上先把这个想法“跑通”验证核心逻辑的可行性再考虑实物制作。这就是今天要和大家分享的这个“基于STM32的鸡蛋分类和分装仿真”项目的由来。它本质上是一个机电一体化系统的虚拟原型验证。我们通过在Proteus 8.15这个强大的电子设计自动化软件里搭建一个包含STM32微控制器、传感器、执行机构电机、舵机和指示电路的完整系统模型来模拟现实中的鸡蛋检测、判断和分拣过程。最终我们会得到一个可以交互运行的仿真电路并能录制一段演示视频直观地展示整个分类分装流程。这对于学生做课程设计、工程师验证算法逻辑、或者爱好者学习STM32与传感器联合控制来说都是一个非常有趣且实用的练手项目。2. 仿真系统核心架构与元件选型解析在动手画原理图之前我们必须先想清楚整个系统需要哪些部件以及它们之间如何协同工作。一个典型的鸡蛋分类分装系统可以抽象为“感知-决策-执行”三个环节。感知层的核心是传感器。鸡蛋分类的依据通常有重量、尺寸通过视觉或机械测量、颜色甚至表面瑕疵。在仿真环境中我们优先考虑易于模拟和实现的维度。重量测量可以通过压力传感器或称重传感器模拟但在Proteus中直接模拟复杂的力学信号比较麻烦。一个更取巧且有效的方法是使用红外对管或光电传感器来模拟尺寸检测。我们可以假设鸡蛋在传送带上通过一个检测门大鸡蛋会遮挡更长时间或完全遮挡两对传感器而小鸡蛋可能只遮挡一对或时间较短。在Proteus中我们可以用LDR光敏电阻配合LED或者直接用红外发射-接收对管来模拟通过STM32的ADC模数转换器读取光照变化产生的电压值从而判断“遮挡”状态。为了增加仿真趣味性和逻辑复杂性我们还可以加入一个颜色传感器模块如TCS3200的简化模型通过模拟I2C或自定义IO口读数来区分红皮蛋和白皮蛋。决策层毫无疑问是我们的STM32微控制器。我选择的是STM32F103C8T6也就是常说的“蓝屏核心板”主控。它资源适中72MHz主频64KB Flash20KB RAM拥有丰富的定时器、ADC、通信接口完全足以处理多路传感器输入和复杂的控制逻辑。它的仿真模型在Proteus 8.15中也非常成熟稳定。决策逻辑就是一段嵌入式C代码持续轮询或中断触发读取传感器数据根据预设的阈值比如ADC值大于某数表示“大鸡蛋”I2C读取的RGB比例判断颜色做出分类决策然后触发相应的执行机构。执行层负责将决策转化为动作。这里需要两个部分传送带驱动用一个直流电机模拟通过STM32的PWM脉冲宽度调制输出控制一个电机驱动芯片如L298N来调节传送带的启停和速度。在仿真中我们可以用Proteus的直流电机模型并用一个滑动变阻器或虚拟仪器来直观显示PWM占空比与速度的关系。分拣臂驱动这是分类动作的关键。通常使用舵机Servo Motor来实现。STM32通过一个普通IO口输出PWM信号周期20ms脉宽0.5ms-2.5ms对应0-180度角度控制舵机转动到特定角度从而将鸡蛋推入或拨入对应的收集槽。Proteus中有现成的舵机模型响应非常直观。此外还需要人机交互界面。我们可以用几个LED灯来指示系统状态如电源、运行、故障用LCD1602液晶屏来实时显示当前检测到的鸡蛋类型和分类计数。最后用按键来模拟启动、停止、复位等操作。整个系统的数据流是这样的上电初始化 - 等待启动按键 - 传送带电机以低速运行 - 传感器检测到鸡蛋 - STM32读取并处理传感器数据 - 判断鸡蛋类别如“大红蛋”、“小白蛋” - 控制对应通道的舵机动作将鸡蛋推入指定区域 - LCD更新计数 - 循环。所有这一切都将在Proteus的蓝色图纸上实时上演。3. Proteus 8.15仿真环境搭建与电路设计实操有了架构我们就可以在Proteus 8.15中“搭积木”了。首先确保你的Proteus软件已经安装并破解成功能够正常使用STM32和各类元件的仿真模型。第一步创建新工程与选取元件。新建一个工程命名为“Egg_Sorter_STM32”。在元件库中我们需要搜索并放置以下关键元件微控制器STM32F103C8(注意在Proteus中可能直接搜STM32F103C8模型通常包含C8T6)。传感器模拟尺寸检测使用一对LDR和LED或者搜索IRLED和PHOTOTRANSISTOR光电晶体管来模拟红外对管。将LED的阳极通过一个220Ω电阻接VCC阴极接地LDR或光电晶体管的一端接VCC另一端通过一个10kΩ的上拉电阻接地中间节点接STM32的某个ADC通道引脚如PA0。当LED光路被“鸡蛋”后面我们会用其他图形代替遮挡时接收端电压会变化。颜色检测由于TCS3200的仿真模型可能不常见我们可以用一个简化的方法放置一个POT-HG滑动变阻器和一个BUTTON按键。滑动变阻器模拟颜色传感器输出的不同电压值接ADC按键模拟检测触发。或者更高级一点可以用一个虚拟的“电压源”由程序控制输出来模拟传感器信号。执行机构电机驱动搜索L298N这是一个双H桥电机驱动芯片。将STM32的两个PWM引脚如PA8, PA9接L298N的IN1、IN2控制一个直流电机MOTOR。电机的两端接L298N的OUT1、OUT2。别忘了给L298N的电源引脚VCC VS接上合适的电压如12V用于电机5V用于逻辑。舵机搜索SERVO-MOTOR。将其信号线通常为橙色或白色接STM32的一个具有定时器输出功能的引脚如PA6-TIM3_CH1红色接VCC5V棕色接地。人机交互LCD搜索LM016L即1602字符液晶。按照标准接法RS, RW, E, D0-D7分别接到STM32的一组GPIO上我习惯用PB0-PB7作为数据口PB8-PB10作为控制口。LED和按键用LED和BUTTON元件即可注意LED串联限流电阻330Ω。辅助元件RES电阻、CAP电容用于电源滤波和复位电路。CRYSTAL晶振为STM32提供8MHz外部时钟。还需要POWER和GROUND符号。第二步绘制原理图与网络标号。将所有元件放置到图纸上开始连线。Proteus支持用网络标号Net Label代替实际连线让图纸更清晰。例如将STM32的PC13引脚画一小段线然后放置一个网络标号KEY_START在按键的一端也放置同样的标号KEY_START它们就在电气上连接了。 关键连接点STM32的PA0ADC接LDR与电阻的分压点用于模拟尺寸检测。STM32的PA1ADC接滑动变阻器的滑臂用于模拟颜色信号输入。STM32的PA6PWM接舵机信号线。STM32的PA8,PA9PWM接L298N的IN1, IN2。STM32的一组GPIO如PB0-PB10按前述方式接LCD1602。为STM32设计最小系统电路复位电路10k上拉电阻0.1uF电容到地中间接NRST、8MHz晶振电路两个20pF负载电容、Boot0和Boot1引脚通过10k电阻下拉到地选择从主Flash启动。电源部分可以放置多个POWER符号命名为5V、12V、3.3V。用VOLTAGE REGULATOR如7805来模拟从12V到5V的转换。STM32的VDD引脚接3.3V这个3.3V可以用AMS1117-3.3从5V转换而来。第三步模拟“鸡蛋”与运动场景。这是Proteus仿真的精髓也是最具挑战和创意的一步。鸡蛋本身不是一个标准电子元件。我们有几种方法模拟方法一使用动画元件。Proteus的“元件模式”下有一个类别叫“Animation”。里面有一些可以移动的图形比如POT-HG是滑块但不太像鸡蛋。我们可以自己绘制一个简单的椭圆形图形保存为自定义元件但让它具备物理属性比较困难。方法二巧用已有元件。更实用的方法是我们不仿真鸡蛋的物理移动而是仿真“传感器被触发”这一事件。例如我们可以放置一个SWITCH开关在传送带路径上用一个按时间顺序自动闭合/断开的“脚本”或“电压源”来控制这个开关模拟鸡蛋经过时遮挡传感器的动作。但这不够直观。方法三推荐使用“激励源”和“电压探针”进行信号级仿真。对于教学和逻辑验证我们可以暂时抛开具体的物理外形专注于信号流。我们用一个PULSE脉冲电压源来模拟“鸡蛋到达”信号。将这个脉冲源的输出同时接到一个模拟尺寸的ADC通道和一个模拟颜色的ADC通道或通过一个简单的模拟电路进行“调制”使两个通道的信号特征不同。在STM32程序中我们就根据这两个ADC通道在脉冲高电平期间采样到的数值来判断“鸡蛋”的类型。同时我们可以用Proteus的“虚拟仪器”中的OSCILLOSCOPE示波器来观察这些模拟信号的波形非常直观。 为了视觉效果我们可以在传感器位置画一个圆圈代表检测点用文字标注“检测区”。执行结果用LED的亮灭或LCD屏上的文字变化来体现。仿真视频的录制就可以聚焦于STM32的代码运行、传感器信号变化、LCD显示更新以及舵机动作的联动过程。绘制完成后务必仔细检查所有连线、电源和地网络确保没有短路或未连接的情况。一个清晰、规范的原理图是成功仿真的基础。4. STM32固件开发从传感器数据处理到多任务调度电路搭好了接下来就是让STM32“活”起来的代码部分。我们使用Keil MDK或者STM32CubeIDE进行开发。这里我以标准外设库或HAL库为例勾勒出程序的核心框架。第一步工程创建与基础配置。使用STM32CubeMX工具可以极大简化初始化过程。新建工程选择STM32F103C8Tx芯片。在图形化界面中配置时钟树选择外部高速晶振HSE将系统时钟SYSCLK配置到最大72MHz。引脚分配ADC1的通道0PA0和通道1PA1配置为单端输入。定时器TIM3的通道1PA6配置为PWM Generation CH1用于舵机。预分频器和周期值需要计算系统时钟72MHz如果我们希望PWM频率为50Hz周期20ms则定时器时钟可以分频到1MHz。那么预分频器PSC设为7172MHz/(711)1MHz自动重载值ARR设为199991MHz/50Hz -1 19999这样产生的PWM周期就是20ms。脉宽在500-2500之间对应0-180度。定时器TIM1或TIM4的通道1、2如PA8, PA9配置为PWM Generation用于驱动L298N控制电机速度。频率可以设为10kHz左右通过改变占空比调节速度。用于LCD的GPIO如PB0-PB10配置为推挽输出模式。用于按键的引脚如PC13配置为上拉输入模式。用于状态LED的引脚配置为推挽输出。生成工程代码选择MDK-ARM V5或IDE。第二步核心模块驱动编写。在生成的工程中我们主要编写以下几个模块ADC数据采集与滤波// 获取尺寸和颜色传感器的ADC值示例 uint16_t Get_Size_ADC_Value(void) { uint32_t sum 0; for(uint8_t i0; i10; i) { // 采样10次 sum HAL_ADC_GetValue(hadc1); // 假设尺寸传感器接在ADC1通道0 HAL_Delay(1); } return (uint16_t)(sum / 10); // 返回平均值简单滤波 } // 颜色传感器类似可能接在通道1由于是仿真传感器信号可能很“干净”但实际中必须加入滤波如均值、中值、卡尔曼滤波来抗干扰。舵机角度控制函数// 设置舵机角度angle范围0-180 void Servo_Set_Angle(TIM_HandleTypeDef *htim, uint32_t Channel, uint8_t angle) { uint16_t pulse 500 angle * (2500-500) / 180; // 将角度映射到500-2500us脉宽 // 根据定时器配置将脉宽时间转换为比较寄存器值 // 假设定时器时钟1MHz则1us对应计数1次 __HAL_TIM_SET_COMPARE(htim, Channel, pulse); }电机速度控制// 设置电机速度speed范围0-100百分比 void Motor_Set_Speed(TIM_HandleTypeDef *htim, uint32_t Channel, uint8_t speed) { uint16_t compare (htim-Instance-ARR 1) * speed / 100; __HAL_TIM_SET_COMPARE(htim, Channel, compare); // 同时需要设置L298N的另一个控制引脚电平来决定方向 HAL_GPIO_WritePin(MOTOR_IN1_GPIO_Port, MOTOR_IN1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(MOTOR_IN2_GPIO_Port, MOTOR_IN2_Pin, GPIO_PIN_RESET); // 正转 }LCD1602显示驱动编写LCD_Write_StringLCD_Set_Cursor等函数用于显示“Type: Large Red”, “Count: 12”等信息。第三步主程序逻辑与状态机设计。主循环不宜使用阻塞式延时等待最好采用状态机State Machine或基于定时器中断的调度方式。typedef enum { SYS_IDLE, SYS_RUNNING, SYS_SORTING, SYS_FAULT } SysState_t; SysState_t sysState SYS_IDLE; EggType_t currentEggType TYPE_UNKNOWN; int main(void) { // HAL初始化外设初始化 HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_ADC1_Init(); MX_TIM1_Init(); MX_TIM3_Init(); // ... 其他初始化 LCD_Init(); LCD_Show_String(0, 0, Egg Sorter Ready); while (1) { switch(sysState) { case SYS_IDLE: if(HAL_GPIO_ReadPin(KEY_START_GPIO_Port, KEY_START_Pin) GPIO_PIN_RESET) { HAL_Delay(50); // 消抖 if(HAL_GPIO_ReadPin(KEY_START_GPIO_Port, KEY_START_Pin) GPIO_PIN_RESET) { sysState SYS_RUNNING; Motor_Set_Speed(htim1, TIM_CHANNEL_1, 30); // 启动传送带 LCD_Show_String(0, 1, Running... ); } } break; case SYS_RUNNING: // 模拟传感器检测在仿真中这可能由一个虚拟信号源触发 // 我们可以在一个定时器中断里模拟“鸡蛋到达”事件 // 或者用一个按键模拟传感器触发 if(模拟鸡蛋到达信号) { sysState SYS_SORTING; Motor_Set_Speed(htim1, TIM_CHANNEL_1, 0); // 暂停传送带 // 读取传感器数据 uint16_t sizeADC Get_Size_ADC_Value(); uint16_t colorADC Get_Color_ADC_Value(); // 根据阈值判断类型 currentEggType Classify_Egg(sizeADC, colorADC); // 执行分拣 Execute_Sorting(currentEggType); // 更新显示计数 Update_Count_Display(currentEggType); // 短暂延时后恢复传送带 HAL_Delay(300); Motor_Set_Speed(htim1, TIM_CHANNEL_1, 30); sysState SYS_RUNNING; } break; case SYS_FAULT: // 处理错误如电机堵转、传感器异常 Motor_Set_Speed(htim1, TIM_CHANNEL_1, 0); LCD_Show_String(0, 1, FAULT! Check Sys ); break; } // 其他后台任务如按键扫描、显示刷新 Key_Scan(); } }Classify_Egg函数内部就是一系列的阈值判断。Execute_Sorting函数则根据currentEggType调用Servo_Set_Angle控制对应的舵机转动到特定位置比如大蛋左转小蛋右转红蛋左转白蛋右转。5. 联合调试、问题排查与仿真视频录制将编译好的.hex或.elf文件加载到Proteus中STM32元件的程序属性里点击运行激动人心的时刻就到了。但通常不会一帆风顺。常见问题一程序加载后无任何反应。检查点首先确认Proteus中STM32的晶振频率设置是否与代码中SystemClock_Config配置的一致都是8MHz。Proteus中双击STM32元件在“Program File”路径是否正确Clock Frequency是否设为8MHz或72MHz取决于你代码中是否使用了PLL倍频。检查点查看复位电路是否正常。在Proteus中可以右键点击STM32选择“Goto Schematic Model”检查其复位引脚NRST的接线应该是通过一个上拉电阻接VDD一个电容接地。检查点最简单的先点一个LED灯写一段最简单的闪烁程序测试确保最基本的IO和时钟是正常的。常见问题二ADC采样值不对或不变。检查点在Proteus中用鼠标右键点击ADC输入引脚连接的模拟节点如LDR和电阻的中间点选择“Place Voltage Probe”。运行仿真时这里会显示实时电压值。看看电压是否随你的“鸡蛋”激励源变化。检查点在代码中确保ADC已经校准并启动。使用HAL库时调用HAL_ADC_Start(hadc1)启动转换然后调用HAL_ADC_PollForConversion(hadc1, timeout)等待转换完成再读取值。检查点STM32的ADC参考电压在Proteus中默认是VDD3.3V。确保你的模拟信号电压在0-3.3V之间。常见问题三舵机不转动或转动角度异常。检查点用Proteus的虚拟示波器OSCILLOSCOPE连接到舵机的信号线上。观察波形是否为标准的50Hz PWM波周期20ms且高电平脉宽是否在0.5ms到2.5ms之间变化。检查点检查定时器配置。PWM模式是否正确通常为PWM模式1通道极性是否正确高电平有效。比较寄存器CCR的值是否根据你的角度计算正确。检查点舵机模型是否需要额外的电源确保其VCC引脚接了5V。常见问题四LCD1602不显示或显示乱码。检查点这是最常出问题的地方。首先检查接线尤其是RS、RW、E三个控制线的时序。RW引脚通常接地只写模式。在代码中写入命令或数据后必须给E引脚一个下降沿脉冲。仔细检查你的LCD_Write函数里的延时Proteus仿真对时序要求比较严格延时太短可能导致操作失败。可以适当增加HAL_Delay的微秒级延时。检查点初始化序列是否正确1602有固定的上电初始化流程复位、功能设置、显示设置等一个步骤都不能少。当所有功能调试正常整个系统可以流畅地模拟“检测-判断-分拣-计数”流程后就可以录制仿真视频了。Proteus自带录像功能在“Debug”菜单下选择“Start VSM Video Capture”可以录制整个设计页面的动态。录制时建议先给电路图一个全景。然后聚焦到STM32和关键传感器、执行器部分。运行仿真用鼠标操作虚拟仪器如示波器、电压探针展示关键信号变化。特写LCD屏幕上的计数变化和状态提示。最后展示舵机动作和LED状态指示的联动。 录制完成后用视频编辑软件加上简单的文字说明和背景音乐一个生动的项目演示视频就诞生了。这个视频不仅是成果展示更是你学习和解决问题过程的最好记录。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →