ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

基于STM32的宠物智能饲养盒Proteus仿真设计与实现

基于STM32的宠物智能饲养盒Proteus仿真设计与实现 简介基于STM32的宠物智能饲养盒Proteus仿真项目面向单片机初学者、电子竞赛备赛者及宠物智能硬件爱好者重点解决定时喂食与温湿度监控的联动实训需求。系统以STM32为主控集成定时器、LCD1602显示、继电器投食控制与DHT11温湿度采集可实现智能定时喂食、环境温湿度监测和超限控制。资料包共223个文件主要包括C源文件、H头文件、编译中间文件、Proteus仿真工程、HEX固件以及两段演示讲解视频和补拍视频压缩包整体约32.88MB目录结构清晰便于按代码、仿真、文档分模块查阅。目前已有184人学习浏览。通过该资源用户可获得可直接编译的完整源代码、配套Proteus仿真图、操作演示视频和固件烧录文件适合课程设计、毕业设计或项目复现时边看边做、对照排错能有效缩短开发调试周期。1. 宠物智能饲养盒为什么先放在Proteus里做仿真再动手焊板接到“基于STM32的宠物智能饲养盒”这类题目时大部分人的第一反应是打开购物网站把DHT11、舵机、LCD1602、面包板一次性买齐。真正拖慢进度的往往不是代码而是“假设外设行为都正确”这件事温湿度传感器时序差一个微秒、舵机PWM占空比算错一档、晶振频率与库函数配置不一致每一个问题在实物调试时都要靠示波器一根根线去查。Proteus仿真设计把传感器和执行器的行为模型化逻辑错误在编译前就能暴露出来硬件连接、状态机、时序参数都可以在电脑上先跑通一轮。这套流程对课程设计、毕业设计和刚开始接触嵌入式开发的人尤其合适先在这个环境里验证“这么写到底对不对”再决定要不要投板。下文按硬件搭建、控制逻辑、烧录调试、验收验证四层展开所有代码按STM32F103系列标准外设库编写。2. Proteus仿真元件选型与饲养盒硬件连接设计2.1 按功能块拆出主控、感知、执行、交互四部分再选型智能饲养盒的常见功能配置包括环境温湿度检测、定时或手动喂食、缺水告警、LCD状态显示以及串口调试输出。把这些功能映射到硬件上就得到四个功能块主控、感知、执行、交互。主控负责状态调度和信号处理感知负责采集温湿度和模拟量水位执行负责舵机开仓和指示灯/加热指示灯交互负责LCD显示和按键输入。选型时优先考虑Proteus中是否有对应的行为模型而不只看数据手册。DHT11模型在Proteus中带完整单总线时序模拟行为与实物基本一致舵机SERVO模型能根据PWM高电平时间输出角度配合示波器可以直观验证。LCD1602用LM016L模型虚拟终端VIRTUAL TERMINAL用来替代串口调试助手。这些模型都位于Proteus元件库根目录下导入后直接用导线连接即可不需要额外安装第三方库。2.2 Proteus元件库搜索与参数设置2.2.1 STM32F103R6主控模型与时钟引脚在Proteus 8 Professional中点击Pick Devices搜索“STM32F103R6”可以找到主控模型。R6与C8T6同属F103中密度系列内核和外设一致只是封装与Flash大小不同仿真中不存在实际容量限制适合作为F103系列的统一仿真载体。放置后双击元件弹窗中的Clock Frequency字段要与代码内部晶振配置保持相同通常填写8MHz。晶振电路在仿真中可以简化真实硬件需要在OSC_IN和OSC_OUT之间接8MHz晶振并在两端分别对地接22pF电容Proteus里若不接晶振也能运行但PLL倍频路径依赖时钟配置直接把频率参数填在元件属性里更稳妥。复位电路使用RST引脚接10k上拉电阻到3.3V按键一端接地即可实现低电平复位BOOT0引脚接地让芯片从Flash启动。这一套接法与F103最小系统一致后续移植到立创EDA画板时可以直接复用。2.2.2 DHT11、LM016L、SERVO和电位器的接线差异DHT11在Proteus中搜索后放在原理图四脚模型从左到右为VCC、DATA、NC、GND。DATA引脚建议通过4.7k上拉电阻接3.3V与实物要求一致。数据线引出到STM32的PB12。LM016L即1602字符液晶标准16脚RS接PB0、RW接PB1、EN接PB2D4到D7接PB3到PB6VL脚接1k电位器中间抽头调节对比度。舵机SERVO模型三根线PWM输入接PA8VCC接5VGND共地。水位检测在Proteus中没有现成的液位传感器模型常见做法是用电位器POT-HG模拟水位变化电位器中间抽头接PA1做ADC采集通过分压值近似反映水位高低。这种方式适合仿真阶段验证阈值判断逻辑制作实物时再替换为电极式水位传感器。下表汇总了本设计用到的仿真元件功能块Proteus搜索关键字放置后名称关键参数或接法主控STM32F103R6U18MHz外部时钟温湿度DHT11U2DATA经4.7k上拉接PB12显示LM016LU34位模式RSPB0ENPB2舵机SERVOSV1PWM接PA8水位模拟POT-HGRV1中间抽头接PA1做ADC输入调试串口VIRTUAL TERMINAL——RX接PA9TX接PA10上拉电阻RESR14.7kDHT11数据线上拉2.3 仿真观测点串口虚拟终端与逻辑探针仿真环境里最容易犯的错误是“不知道中间量是否对”解决办法在原理图上预留观测点。USART1的PA9和PA10接入VIRTUAL TERMINAL代码里用printf输出温湿度原始值和喂食触发事件Proteus虚拟终端的波特率设置为9600、8位数据、无校验、1停止位就能直接看到带时间戳的日志。对于DHT11数据线这种关键GPIO可以用Logic Probe逻辑探针直接挂在PB12上运行时探针颜色变化表示电平翻转。舵机PWM输出还可以接虚拟示波器这比看代码里的TIMPulse更直观第五章会专门讲示波器验收方法。3. STM32饲养盒控制逻辑状态机、DHT11时序与舵机喂食3.1 用状态机划分饲养盒行为避免主循环里堆if饲养盒的行为可以从时间维度拆成四类空闲等待、周期检测、投喂动作、环境告警。把这四类行为做成状态机代码可读性比在主循环里连续if else判断标志位高得多。定义如下枚举typedef enum { SM_IDLE 0, // 空闲等待定时或按键触发 SM_DETECT, // 读取DHT11温湿度 SM_FEED, // 舵机开仓再关闭完成一次投喂 SM_ALERT // 温度或湿度越限LCD告警 } SysState; volatile SysState g_state SM_IDLE; volatile uint32_t g_tick_1s 0; // 秒计数由SysTick中断累加 volatile uint8_t g_feed_req 0; // 按键触发投喂主循环按状态分发while (1) { switch (g_state) { case SM_DETECT: dht11_read(g_temp, g_humi); if (g_temp TEMP_MAX || g_humi HUMI_MIN) g_state SM_ALERT; else g_state SM_IDLE; break; case SM_FEED: feed_action(); g_feed_times; // 喂食次数累计用于显示和验收 g_state SM_IDLE; break; case SM_ALERT: lcd_show_alert(); g_state SM_IDLE; break; default: break; } }状态迁移的触发条件放在中断和按键扫描里主循环本身只做状态分发不阻塞等待外设。Code中g_feed_times是喂食计数调试时可以打印到串口验证定时投喂是否按预定周期执行。3.2 DHT11单总线读取40us采样点怎么来的DHT11一次通信包含主机起始信号、从机80us低电平响应、40bit数据、最后50us结束。数据位的区分方式是每个数据位以50us低电平开始随后高电平持续26到28us表示逻辑0持续70us表示逻辑1。因此读取一个bit时等待低电平结束再延时40us后采样引脚电平就能稳定落在两个区间的分界处。static uint8_t dht11_read_bit(void) { uint8_t bitval 0; // 等待50us低电平结束保证采样点对齐到数据位的高电平段 while (!GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN)); delay_us(40); if (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN)) bitval 1; while (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN)); // 等待高电平结束 return bitval; }delay_us(40)是软延时基于72MHz系统时钟做循环递减。需要说明的是Proteus仿真运行速度受宿主机性能影响软延时循环次数在仿真环境与实际硬件上不一定等长调试时应以虚拟示波器测量到的DHT11响应时序为准必要时微调循环次数。读取频率控制在1s一次过高频率会导致DHT11模型返回错误数据。3.3 舵机喂食TIM1高级定时器输出PWM舵机控制采用20ms周期性PWM高电平时间决定转角0.5ms对应0度1.5ms对应90度2.5ms对应180度。这部分使用TIM1的通道1输出PWMTIM1属于高级定时器除了常规的时基和输出比较配置还必须使能主输出MOE否则PA8上没有信号。void servo_init(void) { GPIO_InitTypeDef gpio; TIM_TimeBaseInitTypeDef tim; TIM_OCInitTypeDef oc; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA, ENABLE); gpio.GPIO_Pin GPIO_Pin_8; gpio.GPIO_Mode GPIO_Mode_AF_PP; gpio.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, gpio); tim.TIM_Prescaler 71; // 72MHz分频到1MHz计数周期1us tim.TIM_Period 19999; // 20000us 20ms即50Hz tim.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, tim); oc.TIM_OCMode TIM_OCMode_PWM1; oc.TIM_Pulse 50; // 占空比计数50 0.5ms 0度 oc.TIM_OutputState TIM_OutputState_Enable; TIM_OC1Init(TIM1, oc); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_CtrlPWMOutputs(TIM1, ENABLE); // 高级定时器主输出使能容易遗漏 TIM_Cmd(TIM1, ENABLE); }TIM_Prescaler取71把72MHz时钟分频成1MHz此时TIM_Pulse的值直接等于高电平微秒数。喂食动作可以开环控制先把仓门开到120度保持一段时间让饲料落下再关闭。由于舵机旋转需要时间直接连续写占空比会跳过中间过程稳妥做法是分步更新。TIM_Pulse计数值高电平时间舵机角度饲养盒动作500.5ms0°仓门完全关闭751.5ms90°仓门半开1002.0ms120°仓门近全开下料1252.5ms180°仓门全开void feed_action(void) { // 开仓0度到120度每步间隔10ms步长4us对应约10度 for (uint16_t pulse 50; pulse 100; pulse 4) { TIM_SetCompare1(TIM1, pulse); delay_ms(10); } delay_ms(300); // 保持开仓让饲料下落 // 关仓120度回到0度 for (uint16_t pulse 100; pulse 50; pulse - 4) { TIM_SetCompare1(TIM1, pulse); delay_ms(10); } }喂食期间对DHT11的读取会被阻塞约500ms这在1s级控制周期内可以接受。若后续设计增加多路舵机或伺服电机建议把分步旋转放进SysTick中断服务里用非阻塞方式切换角度。3.4 显示、按键与喂食定时器的时间片划分状态机之外还需要一个秒级定时源。用SysTick配置1ms中断SysTick_Handler里累加g_tick_1s每满1000置检测标志按键扫描则放在主循环中执行配合10ms消抖窗口if (g_tick_1s 1000) { g_tick_1s 0; g_state SM_DETECT; // 每秒检测一次温湿度 } if (KEY_Scan() KEY_FEED) { g_state SM_FEED; // 手动触发一次投喂 }LCD1610的刷新不需要每一轮主循环都执行温湿度变化缓慢每秒刷新一次足够。显示函数这样组织void lcd_show_env(void) { char line[17]; snprintf(line, sizeof(line), T:%dC H:%d%%, (int)g_temp, (int)g_humi); LCD1602_SetCursor(0, 0); LCD1602_WriteString(line); snprintf(line, sizeof(line), Feed:%d, g_feed_times); LCD1602_SetCursor(0, 1); LCD1602_WriteString(line); }g_temp和g_humi定义为全局变量DHT11读取函数更新它们显示函数只读取避免在中断服务函数里调用LCD操作保持显示功能独占一个时间片。4. 从Keil到Proteushex烧录、时钟配置与三个必调仿真参数4.1 Keil5侧配置芯片包装好后生成hex的四个选项代码编辑与编译在Keil5完成。新建项目选择芯片型号时如果找不到STM32F103系列说明芯片支持包没有安装Pack Installer中搜索“STM32F1xx_DFP”进行安装。同时安装过C51和STM32包的环境互不影响C51项目不会出现在Device列表中。工程建好后按先后顺序检查四个编译选项第一Options for Target → Device确认目标芯片为STM32F103R6或同系列中密度型号。第二Output选项卡勾选Create HEX File这样编译后才会生成Proteus需要的.hex文件。第三C/C选项卡Defines中填写STM32F10X_MD, USE_STDPERIPH_DRIVERMD对应中密度产品漏掉这个宏会在编译时报外设寄存器未定义。第四Debug选项卡选择“Use Simulator”或任意调试器都行Proteus只用最终hex文件不依赖调试器设置。编译报错时优先检查Target选项卡里是否勾选了Use MicroLIB。标准库的printf默认走半主机模式重定向fputc到USART1后若还在半主机状态下运行会卡死在BKPT指令勾选MicroLIB能直接绕过这个问题。4.2 Proteus里加载hex并核对晶振参数打开Proteus的原理图双击U1进入Edit Component对话框。Program File字段选择刚刚编译生成的hex文件路径通常在工程目录Objects文件夹下。Crystal Frequency字段填写8000000这必须与代码中的HSE_VALUE保持一致。代码中RCC_PLLConfig的倍频系数若设置为9倍系统时钟就是72MHz这个值只影响代码运行速度Proteus中的频率字段是给仿真模型提供时钟源的。点击左下角运行按钮绿色三角进入运行状态。如果LCD没有反应先不要改代码检查是否所有元件GND网络都连通Proteus的电源端子VCC和VSS需要显式放置网格连线不会自动连接电源符号。DHT11读取失败时在DHT11模型上右键选择“Edit Properties”确认Delay响应时间参数在模型默认值范围内。4.3 三个必调的仿真参数与故障排查表Proteus仿真环境有三个参数会影响运行结果晶振频率、动画帧率、虚拟终端波特率。晶振频率必须与代码匹配否则定时器时基计算全错动画帧率默认比较高仿真速度慢时在System → Set Animation Options里把帧率调低同时关闭“Real Time Simulation”避免宿主机CPU占用过高虚拟终端波特率要与USART1初始化一致代码里配置的9600对应终端中的9600 Baud。故障现象可能原因修改位置仿真一开始就跑飞LED乱闪晶振频率与HSE_VALUE不一致双击STM32模型改Crystal FrequencyLCD无字符但有背光LM016L的VL对比度引脚悬空VL脚接10k电位器中间抽头调电压舵机一直停在0度不动TIM1主输出MOE未使能代码中加TIM_CtrlPWMOutputs(TIM1, ENABLE)第一次读温湿度为0DHT11模型上电后需要时间稳定读前延时500ms或读到0时重试两次虚拟终端显示乱码波特率或数据格式不一致终端设为9600, 8, N, 1仿真速度明显变慢动画面帧率过高System → Set Animation Options调低帧率DHT11仿真模型有一个特殊行为上电后第一次读取往往返回0xFF或0x00因为模型内部的定时器还没有准备好。代码层面只要加一个重试机制连续读失败两次后返回上一次有效值就能规避这个坑。5. 用示波器卡舵机脉宽把仿真验收做成秒级流程5.1 用虚拟示波器看PA8的脉宽和周期Proteus左侧工具栏的虚拟仪器面板里选择OSCILLOSCOPE放置后把A通道的探针连接到PA8引脚。运行时示波器会显示PWM波形按以下三个指标逐项验收周期是否稳定在20ms左右高电平时间是否随角度分步变化喂食动作期间波形是否连续无抖动。周期偏差超过5%时检查TIM_Prescaler和TIM_Period的值。72MHz输入下Prescaler71得到1MHz计数频率Period19999时计数器从0数到19999共20000个时钟周期正好20ms。若代码把Prescaler配成7199计数频率变成10kHz同样的Period对应的周期就变成2秒舵机角度更新会肉眼可见地一卡一卡。验证角度分步变化可以打开舵机模型自带的Angle属性面板运行喂食动作时角度直接从0跳到120度说明PWM从0.5ms直接跳到2.0ms中间缺少过渡步这时候看feed_action里TIM_SetCompare1的调用间隔通常是把Delay_ms写成了Delay_us导致过渡时间过短。5.2 按秒级时间轴记录喂食触发与温湿度刷新最终验收阶段将喂食定时从代码里的一个条件编译宏控制例如#define FEED_INTERVAL_SEC 30仿真运行时用手机计时观察30秒整数倍时舵机是否动作、LCD计数行是否加一。连续验证三个周期确认每次喂食时间差不大于一个秒计数。温湿度刷新则把DHT11读取周期改为2秒观察虚拟终端串口日志中温湿度值更新的间隔。这套流程把仿真验证收敛成了可量化的动作示波器确认PWM参数正确、秒表确认逻辑周期正确、串口日志确认采集链路通畅。三个指标都通过后再考虑把原理图网络表导出做PCB打样仿真阶段积累的晶振配置、上拉电阻位置和串口接线方式可以直接迁移到实物设计。宠物饲养盒本身的低成本特性决定了它适合用这种“仿真先行”的开发路径硬件改版一次的成本和时间远高于在Proteus里多跑几个小时的仿真。本文还有配套的精品资源点击获取
返回列表