ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于STM32智能药盒定时提醒系统Proteus仿真设计与实现

基于STM32智能药盒定时提醒系统Proteus仿真设计与实现 做嵌入式课设或者毕业设计最怕的不是题目难而是题目看着简单一上手全是坑。如果你正在做或者准备做“基于STM32智能药盒定时提醒服药系统LCD显示Proteus仿真”这个项目我先把话放在这里这个题属于典型的“入门简单、做精难”的类型网上资料多但碎片化严重你在B站和论坛上扒来的代码跟Proteus仿真文件经常对不上一编译全是错一仿真全黑屏。这篇文章我就把这套项目从需求拆解、硬件选型、仿真搭建、代码实现到报告答辩完整地串一遍把我在实际调试中踩过的坑和最终跑通的方案都写出来。内容适合大三、大四做课程设计或者毕业设计的同学也适合想用Proteus仿真快速验证STM32逻辑的爱好者看完以后你至少能少走三天的弯路。1. 项目整体设计与方案选型分析1.1 需求分析智能药盒到底要解决什么问题智能药盒这个题目本质上不是一个硬件题而是一个“产品思维”题。很多同学拿到题就直接开干结果做了一个“能显示时间的LCD”跟药盒一点关系都没有。我带你重新拆一拆需求这才是拿高分的关键。真实的服药场景里有几个痛点第一老年人记忆力衰退经常忘记吃药或者重复吃药第二慢性病患者一天需要吃三四种药每种药的频次和时间都不一样靠脑子根本记不住第三子女不在身边没人监督吃没吃、什么时候吃的完全没有记录。所以一个真正有用的智能药盒至少要解决“按时提醒”和“区分药品种类”这两个核心问题。对应到功能模块上就应该拆成这样需要一个实时的时钟系统RTC或者软件计时需要一组按键用来设置当前时间和每组药的服用时间需要一个显示屏用来显示时间、药号、提醒状态还需要蜂鸣器和LED灯做声光提醒。整个系统的工作流程是开机后显示当前时间和药盒状态用户通过按键进入设置模式设定好各组药的提醒时间主程序进入运行模式实时比对当前时间和设定的提醒时间一旦匹配蜂鸣器响、LED闪、LCD上显示“该吃药了”和药号。这个需求拆解过程你在报告里写清楚评审老师一眼就知道你是真懂还是抄代码。后面所有的硬件选型和软件架构都是围绕这几点展开的。1.2 核心器件选型的取舍为什么是STM32F103C8T6先说主控芯片。这个项目最常选的就是STM32F103C8T6没有之一。为什么先说性能Cortex-M3内核72MHz主频64KB Flash、20KB RAM跑一个时钟加一个LCD1602的显示逻辑绰绰有余就算后面你加上DS1302、DS18B20、舵机、语音模块这个配置也不会紧张。再说工具链Keil MDK对STM32F1系列的支持非常成熟标准外设库StdPeriph_Lib或者HAL库的资料铺天盖地哪怕你是第一次接触ARM照着教程也能把工程跑起来。有同学会问“我用51单片机不行吗”行但得看你的题目要求。如果题目明确写了“STM32”你交一个51的板子上去就算功能全对评审也会觉得你是避重就轻。另外从学习价值上讲51是8位单片机IO直接操作写惯了51的人转到STM32会有一段阵痛期而STM32的时钟树、GPIO配置、中断优先级这些东西才是嵌入式开发的常态。这个项目正好是个过渡的绝佳载体——它不算复杂但足够让你把STM32的GPIO、定时器、外部中断都练一遍。再说显示方案。这个题目里写的是“LCD显示”最常见的搭配是LCD1602也就是字符型液晶。LCD1602的好处是便宜、驱动简单、Proteus里的仿真模型稳定显示两行、每行16个字符对于“时间药号”这种信息刚好够用。OLEDI2C接口的SSD1306显示效果更好但在Proteus里仿真时I2C时序的稳定性不如LCD1602的并口驱动直观不适合这个题目追求稳定复现的定位。TFT彩色屏太浪费了这个功能用不上还会把代码复杂度拉高。所以我建议就选LCD1602后面我会把驱动逻辑讲透。时钟方案比较微妙。STM32内部自带RTC但用起来有坑它的时钟源通常是LSE外部32.768kHz晶振在Proteus仿真里这个晶振模型偶尔会给你“掉链子”跑着跑着时间不走。保险的做法是两种一是直接用STM32的RTC依赖内部LSI时钟精度差点但仿真没问题二是外挂DS1302时钟芯片这是经典的方案Proteus里模型非常成熟代码也好写。我自己的做法是第一版用内部RTC模块化封装好想换DS1302的时候改一个接口就行。后面代码部分我会给出封装思路。1.3 仿真方案的独特价值Proteus到底在仿真什么很多人对仿真的理解有偏差觉得Proteus就是“画个电路图跑一下动画好看”拿去做实物时不值一提。但你换个角度看毕业设计做一个实物药盒焊接、调试、元器件采购的周期至少要一两周而在Proteus里搭仿真半天就能把硬件逻辑跑通代码验证完毕后再去画PCB、买元件出错率会低很多。这个项目本质上是个“逻辑验证型”项目硬件电路非常简单真正的难点在软件逻辑Proteus恰恰是最适合做这件事的工具。另外一个容易忽略的点是Proteus里的STM32仿真跑的是你Keil编译出来的**.hex**文件也就是说它验证的不是C代码本身而是“编译后的机器码外围电路”的协同逻辑。这意味着你在仿真中看到的结果基本就是实物跑起来的结果前提是电路没画错。这就是为什么我强烈建议你在仿真阶段就把代码逻辑完全调通不要带着没验证的代码去打板子。2. 硬件电路原理与Proteus仿真搭建要点2.1 LCD1602显示模块的驱动原理LCD1602是这套系统里的人机交互窗口你必须把它的工作原理吃透。它的控制核心是HD44780芯片这个芯片内部有两个寄存器指令寄存器IR和数据寄存器DR你对它发的所有命令本质上就是往这两个寄存器写东西RS引脚决定你写的是指令还是数据RS0的时候读写的是指令RS1的时候读写的是数据。RW引脚控制读写方向我们正常显示的时候基本只写不读所以RW可以直接接地。E引脚是使能信号一个下降沿也就是从高电平跳变到低电平时LCD锁存当前数据线上的内容。LCD1602有8线模式也有4线模式。8线模式就是DB0-DB7全部接单片机数据一次传一个字节4线模式只用DB4-DB7一个字节分两次传先高四位后低四位。这个项目里STM32的GPIO很富裕我建议用8线模式时序简单代码直观排查问题也容易。Proteus里设置显示对比度的那个电位器接到V0引脚上仿真时可调范围很大如果LCD有显示但看不清第一件事就是动这个电位器。我在实际调试中发现很多同学LCD不显示不是代码问题而是初始化时的时序不对。HD44780有一个固定的上电初始化等待时间从5V电源稳定后至少要等待15ms才能发第一条指令之后还要再等待4.1ms发第二条。如果你用单片机的主频比较高指令发的太快LCD根本反应不过来就会出现反复复位却显示不了内容的情况。所以初始化之前加延时函数是必须的不可省略。2.2 Proteus仿真工程的核心搭建步骤Proteus搭建这个项目我拆成几个关键步骤每一步都有细节要注意。第一步新建工程后从元件库里取元件。你至少需要添加这几个元件STM32F103C8T6、LCD1602、RES电阻、CAP电容、CRYSTAL晶振、BUTTON按键、BUZZER蜂鸣器、LED-RED发光二极管以及POT-HG电位器。有些元件名字在Proteus里是简写比如蜂鸣器Proteus里可能是“SOUNDER”或者“BUZZER”我建议选“BUZZER”这个有源蜂鸣器模型仿真音量直接。找不到芯片时记得在搜索框输入“STM32F103C8”而不是“STM32”不然会过滤掉很多结果。第二步搭最小系统。STM32F103C8T6在Proteus里有两种放置方式一种是直接放芯片需要自己接晶振电路和复位电路另一种是Proteus提供的“STM32最小系统板”封装。我强烈建议用前者自己接因为你的报告里需要这个电路图评审会问。最小系统电路的核心是VDDA、VSSA这些电源引脚全部接3.3V和地NRST复位脚接一个10k上拉电阻到3.3V再串一个0.1uF电容到地这是标准的复位电路PD0和PD1接8MHz晶振两个引脚各接一个20pF电容到地组成晶振起振电路。这整套电路缺一不可你少画一个电容仿真可能都跑不起来。第三步LCD1602连接。RS、RW、E分别接PA0、PA1、PA2数据引脚DB0-DB7接PB0-PB7V0接电位器中间脚电位器两端分别接3.3V和地。这些GPIO的分配不是随便定的要跟你的代码一一对应建议整理成一张表格写报告的时候直接贴进去。第四步按键和蜂鸣器连接。PA3、PA4、PA5接按键到地按键另一端接3.3V也就是低电平触发PA6接蜂鸣器、PA7接LED这两个直接通过限流电阻接地。按键接3.3V的做法是为了利用STM32内部上拉外部不用再加电阻简单省事。这些都连好后最关键的一步来了给芯片加载hex文件。双击Proteus里的STM32芯片在“Program File”那一栏选择你Keil编译生成的hex文件注意路径不能有中文这个坑我后面还会重点讲。加载完成后点左下角的运行仿真就跑起来了。2.3 Keil工程配置从编译到生成Hex的完整闭环Proteus要跑你的程序前提是你得生成hex文件。这里Keil的配置是很多新手的重灾区。首先你不会在Keil的默认安装里直接找到STM32F103C8T6这个型号。你需要先安装器件支持包Device Family Pack。打开Keil自带的Pack Installer在“Device”列表里找到“STMicroelectronics”下的“STM32F1 Series”点安装。如果没有这个选项说明你的Keil版本太老或者MDK升级没做建议直接安装Keil 5.20以上的版本。工程创建流程我快速说一下Project→New μVision Project选择保存路径同样别有中文在器件选择界面输入“STM32F103C8”选中后弹出Manage Run-Time Environment这个界面不用动直接左上角“OK”关掉。然后右键Source Group添加一个main.c文件开始写代码。然后是最容易被忽略的一步配置Output选项。点击魔术棒图标Options for Target在“Output”标签页里勾选“Create HEX File”然后用“C/C”标签页里确认硬件浮点、宏定义没有配错。我见过太多人写了大半天代码编译零错误结果Proteus加载时找不到hex文件就是因为忘了勾这个。还有一点STM32F103C8T6的内部Flash只有64KB如果你的代码优化等级设得太低一个简单工程也可能逼近这个上限。建议在“C/C”选项卡里把Optimization设为“-O2”或者“Level 2”代码量小的时候没有区别但等你加了完整的中文注释、断言、官方的库代码区别就出来了。3. 软件代码架构与核心功能实现3.1 系统状态机设计让程序逻辑清晰可维护智能药盒的程序逻辑绝不能写成一坨在while循环里堆叠的if-else不然过两天你自己都看不懂。我采用的方案是状态机架构。整个系统分成四个状态待机显示状态STATE_DISPLAY、设置模式状态STATE_SETTINGS、运行监控状态STATE_MONITOR和提醒触发状态STATE_ALERT。待机显示状态下LCD显示当前时间、日期和药盒状态摘要设置模式下用户通过按键调整时间和各组药的提醒时间这个状态里有子菜单包括设置小时、设置分钟、设置药号1时间、设置药号2时间等运行监控状态是默认状态程序在死循环里不停比对时间提醒触发状态下蜂鸣器鸣响、LED闪烁、LCD显示醒目的提示语直到用户按下确认键。这个状态机用C语言来实现核心就是一个switch-case结构配合一个状态迁移函数typedef enum { STATE_DISPLAY, STATE_SETTINGS, STATE_MONITOR, STATE_ALERT } SystemState; SystemState currentState STATE_DISPLAY; while (1) { switch (currentState) { case STATE_DISPLAY: displayCurrentStatus(); if (keyPress KEY_MODE) currentState STATE_SETTINGS; break; case STATE_SETTINGS: handleSettingsMenu(); if (keyPress KEY_CONFIRM) currentState STATE_MONITOR; break; case STATE_MONITOR: monitorTimeAndCheckAlarm(); break; case STATE_ALERT: handleAlert(); if (keyPress KEY_CONFIRM) currentState STATE_DISPLAY; break; } }状态机的好处是第一代码可读性强评审老师看一眼状态定义就知道系统设计思路第二功能扩展容易想加一个“用药记录”功能就再加一个STATE_RECORD状态不影响原有的逻辑。这个设计思路在答辩的时候非常加分因为体现的是“软件工程”的意识而不是单纯会调库。3.2 按键扫描与时间设置这个环节连老师都会问按键处理是STM32入门里最基础的模块但这个项目里它是整个系统的输入入口处理不好会让用户崩溃。我用的方法是定时器扫描状态标志或者叫“非阻塞扫描”。按键接法里我提过用的是GPIO读电平的方式。核心逻辑是按键按下时电平变化但机械按键有抖动常见的抖动时间是10-20ms你直接读一次就判断按键按下一定会出现按下一次系统响应好几次的问题。解决方法是延时消抖——检测到电平变化后先延时10ms再读一次如果电平跟之前一致才认定是有效按下。uint8_t KEY_Scan(void) { static uint8_t keyUp 1; if (keyUp (KEY_MODE_PIN 0)) { HAL_Delay(10); keyUp 0; if (KEY_MODE_PIN 0) { return KEY_MODE_PRESSED; } } else if (KEY_MODE_PIN 1) { keyUp 1; } return KEY_NONE; }这里有一个细节keyUp这个静态变量是关键。它保证了只有按键“从松开到按下”这个变化时函数才返回一次有效按键。如果你用了简单的“电平0就返回按下”那只要按键不松开主循环里每跑一圈就触发一次设置时间时数值会狂跳根本停不下来。时间设置流程我建议这样设计按“模式”键进入设置状态LCD第一行显示当前设置项比如“SET HOUR:”第二行显示当前小时数按“加”键数值加1按“减”键数值减1设置完小时按“确认”进入分钟设置依次设置完各药号的提醒时间后按“确认”退出设置状态。这个流程用户很容易理解代码逻辑也清晰。另外设置过程中要做数值边界检查小时不能超过23分钟不能超过59防止用户把时间加到溢出。3.3 定时提醒的核心逻辑时间比对与触发条件提醒功能是这个系统的大脑。设计思路上我们不是用中断去触发提醒而是采用轮询比较的方式。这样更直观也不容易出错。具体实现是写一个函数check_alarm()在运行监控状态下每秒钟调用一次。函数里读取当前的时和分小时变量currentHour和分钟变量currentMinute然后跟所有已设置的提醒时间药号1的小时alarm1Hour、分钟alarm1Minute药号2的设置同理逐一比对。只要时分完全相等就认为到点了把提醒标志位置1。void check_alarm(void) { if ((currentHour alarm1Hour) (currentMinute alarm1Minute) (alarm1Enabled 1)) { activeAlarmId 1; systemState STATE_ALERT; } if ((currentHour alarm2Hour) (currentMinute alarm2Minute) (alarm2Enabled 1)) { activeAlarmId 2; systemState STATE_ALERT; } }这里有个小细节特别重要分钟相等就触发意味着同一分钟内让这个条件成立的时间和当前时间相差不能超过1分钟。如果程序检测频率是每秒一次那么这个“到点”会被检测到大约60次但因为检测到后立刻进入提醒状态、并且设置了提醒触发标志所以不会重复触发。为了绝对安全你还需要一个“本次提醒已触发”的防重入标志否则每分钟的第一个检测周期通过后系统会认为同一分钟内的第二个检测周期也是有效触发就会发生“持续触发、无法确认”的假象。提醒触发后LCD在当前行显示“TAKE MEDICINE 1”或者“TAKE MEDICINE 2”蜂鸣器鸣响、LED闪烁直到用户按确认键才退出。这个过程里LED闪烁是可变频率的我用一个计数器控制让LED每200ms翻转一次看起来很醒目。3.4 LCD显示驱动与屏显规划LCD1602的驱动代码网上很多但很多是直接拷贝的缺少解释。我把它拆成三层底层是引脚操作函数包括lcd_write_command()和lcd_write_data()负责时序中间层是初始化函数lcd_init()负责按照HD44780的要求发送初始化指令序列应用层是lcd_show_string()这样方便调用的功能函数。void lcd_write_command(uint8_t cmd) { LCD_RS_GPIO_PORT-BSRR LCD_RS_PIN; // RS0 命令模式 LCD_DATA_GPIO_PORT-ODR (LCD_DATA_GPIO_PORT-ODR 0xFF00) | cmd; LCD_E_GPIO_PORT-BSRR LCD_E_PIN; // E置高 delay_us(1); LCD_E_GPIO_PORT-BSRR ((uint32_t)LCD_E_PIN 16); // E拉低下降沿锁存 delay_us(50); }初始化序列是HD44780最讲究的地方。我建议按这个顺序延时50ms → 写0x308位模式→延时5ms → 写0x30 →延时5ms → 写0x30 →延时5ms → 写0x388位数据、2行显示、5x7点阵→ 写0x08关闭显示→ 写0x01清屏→写0x06光标右移、不自动滚屏→写0x0C开显示、关光标。每一步中间的延时必须给足尤其是上电早期的几条命令LCD自身还在初始化总线你太快发它接收不了。显示内容的规划上我在第一行放当前时间和状态比如TIME: 12:30 OK或者TIME: 12:30 SET第二行放药盒提醒信息比如MED1:8:00 MED2:12:30或者直接显示REMINDER: MED1。提醒触发时再用第二行显示醒目的TAKE MEDICINE 1配合蜂鸣器保证用户一眼能看到。LCD1602显示不了中文这是它天生的限制所以在Proteus仿真图里不能用中文提示语你可以用英文也可以定义你习惯的提示缩写。这些都是代码里的小细节却是切切实实影响使用体验的地方。3.5 RTC计时与UART调试选项隐藏在每个环节里的“加分项”这个项目要显示“当前时间”所以时间基准是必不可少的。这里我提供两个方案方案一用STM32内部RTC。RTC模块独立于内核运行有自己的一套寄存器。在标准库里面需要先开启电源管理的后备寄存器访问权限PWR和BKP相关然后选择LSI或LSE作为RTC时钟源。要注意的是如果选了LSE外部晶振Proteus仿真里没有真实的32.768kHz晶振模型的情况下RTC时间可能不走这时候切换LSI内部时钟源就好用了。这种方案的好处是省了一个外部芯片缺点是日期比较蛋疼——STM32的RTC只有秒、分、时寄存器闰年和月份逻辑全要自己算。方案二比较简单直观外挂DS1302。DS1302是个工业级经典芯片Proteus里有现成的仿真模型最早接触过的同学可能还记得它的“时钟芯片”标签。DS1302初始化、读写时间和内部RAM的代码网上非常多可靠性也经过验证。我之所以推荐这个方案是因为它把“当前时间哪来的”这个问题完全外包出去了主程序只负责“读时间→比较→显示”逻辑更清晰。UART调试是我每次做嵌入式项目必留的后门。即使显示正常在调试阶段把关键状态变量通过串口打印出来可以快速定位问题。我用ST-Link虚拟串口也可以用Proteus里的Virtual Terminal虚拟终端元件直接连在STM32的USART1引脚上代码里加几句 printf运行时虚拟终端会显示调试信息。这个技巧在仿真阶段尤其好使因为Proteus里你根本不需要外接串口模块。4. 常见问题排查与调试实录4.1 LCD不显示或显示异常先查硬件还是先查代码我在帮人看这个项目的过程中碰到最多的问题就是“LCD显示不出来了”。这里给你一套排查顺序照着做能省很多时间。第一步检查Proteus仿真里的LCD对比度电位器。这是一个物理层的检查你手动拖动调节电位器的滑动端如果显示内容若隐若现说明LCD本身工作正常只是对比度电压不对。LCD1602的V0引脚电压一般要在0.5V到1V之间你把电位器扭到中间位置附近基本都能兼顾。第二步检查接线。确认RS、RW、E、DB0-DB7没接错尤其是RW如果误接了高电平LCD就进入读模式你写什么它都不理。还要检查数据引脚跟电路图代码里定义的是否一致比如你代码里用的是PB0-PB7电路图里却接到了PA0-PA7那显示一定是乱的。第三步检查初始化时序。这是代码层面的重点。我特意用自己的代码做测试发现初始化时如果前面的延时只有1ms确实会出现LCD无法正常工作的现象而把关键位置的延时调整到5ms后一切正常。所以你的HAL_Delay(50)、HAL_Delay(5)这些地方宁可多不能少。第四步检查是否有在写LCD前正确设置RS和E的时序。很多人直接套网上代码结果RS置高和置低的逻辑跟E的触发沿不匹配。你在打方向上是写数据还是写命令必须在函数入口就确定并且RS的电平要在E下降沿之前保持稳定这个时序花了几天调试是真真实实的教训。4.2 Proteus仿真常见的“黑屏”和“跑不动”问题Proteus仿真的黑屏分两种情况一是LCD黑屏二是整个仿真界面完全没有反应。LCD黑屏按上一节的排查顺序来整个仿真没反应重点检查这几块第一个坑是hex文件加载位置。双击STM32芯片看“Program File”的路径是不是备份过里面有中文路径会让文件加载失败芯片显示“No Program File”或者运行时提示内存访问错误。把工程路径改成纯英文再重新编译、重新加载。第二个坑是晶振没接。STM32F103C8T6内部有HSI振荡器如果代码里设置的是默认启动方式内部HSI那你可能不接外部晶振也能跑但如果你在代码或者CubeMX里配置了外部HSE而Proteus里又没有给芯片加8MHz晶振和两个20pF负载电容复位之后会一直卡在启动文件的状态检查里。这是最常见的原因。第三个坑是复位电路的电容阻值不匹配。NRST的10k上拉和0.1uF电容到地是最经典的最小系统配置你换成1k、或者把电容换成10uF可能会发生上电瞬间复位信号不释放芯片一直停留在复位状态整个仿真的现象就是“点了运行什么都没发生”。第四个坑是关于芯片型号。Proteus里的“STM32F103C8”这个型号可能需要到“PIR”这类第三方库才能用不同版本Proteus的元件差异很大。建议使用Proteus 8.9以上版本里面的STM32元件库更完整能直接用自带模型不需要额外装补丁包。4.3 Keil编译报错的几种典型场景编译报错里“未定义标识符”和“找不到头文件”是最常见的新手一半的报错是配置问题而不是代码问题。“找不到头文件”多半是Include Path没配好或者你用的stm32f1xx_hal_conf.h等配置文件不在工程目录里。配置Include Path的方法是魔术棒→C/C→Include Paths把包含头文件的文件夹路径加进去。如果是标准外设库工程通常需要加Libraries\CMSIS\Device\ST\STM32F1xx\Include、Libraries\CMSIS\Include等好几个路径。“未定义标识符”比如GPIO_PIN_0、RCC_APB2Periph_GPIOA报错多半是没加对应的头文件比如stm32f1xx_hal_gpio.h、stm32f1xx_rcc.h。如果你用的是标准库还要确认定义了STM32F10X_MD这个宏否则芯片型号对不上寄存器定义全部无效。这个宏在魔术棒→C/C→Preprocessor Symbols→Define里加。如果你用HAL库的方式编译报“undefined reference toHAL_Delay”之类的链接错误八成是没把延迟函数所在的源文件加进工程或者在启动文件里没有把对应的中断处理函数声明好。HAL库的报错大多集中在链接阶段因为它有一大堆依赖文件缺一个就整体崩。“编译零错误但Proteus运行完全没反应”的情况如果你确认hex加载成功、晶振复位都对那就要看代码里的时钟树配置是否跟Proteus的仿真速度匹配。Proteus仿真器默认按实时运行如果你的主频很高比如72MHz而仿真性能跟不上会出现运行了一秒钟实际上仿真时间只走了0.0001秒的现象。这时候你可以把仿真速度调快或者把已有的128倍默认值改低让仿真器更平滑地运行。5. 报告撰写、答辩讲解与项目扩展思路5.1 设计报告的架构与核心章节怎么写很多同学功能做完了报告却写得七零八落分数直接砸了。一份完整的智能药盒设计报告我给你按标准格式列个提纲你照着填第一章绪论。写背景和意义重点突出“老龄化社会”、“慢性病管理”、“用药安全”这些关键词注意不要大段抄网上的车轱辘话要有自己的理解。比如可以写“我国慢性病患者数量逐年上升多药联用场景下错服、漏服事件频发传统药盒缺乏定时提醒功能因此设计一种成本可控、易于操作、适合老年人使用的智能药盒具有现实意义。”这一段50字就够了别写1200字废话。第二章系统总体方案设计。画系统框图用Visio或者PPT画别用手画拍照阐述STM32F103C8T6选型的理由对比方案表里放上51、STM32、ESP32的优缺点对比。这点很加分说明你做过选型调研。第三章硬件电路设计。每个模块单独一个小节最小系统、LCD显示模块、按键模块、蜂鸣器模块、DS1302/内部RTC接法。每个模块都要有电路原理图引脚分配表必须清晰标注PA几、PB几。第四章软件程序设计。把状态机设计、主程序流程图、各模块驱动函数尤其是LCD初始化和按键扫描的核心代码放上去。流程图建议用标准流程图符号画清晰的逻辑结构能让评审迅速抓住你的设计思路。第五章仿真调试与结果分析。放Proteus仿真截图每个功能场景截一张正常显示图、设置时间界面图、提醒触发状态图。截图旁边写“图5-1 系统正常运行界面”再配上文字说明运行状态。有条件的还可以放一段仿真视频的链接。第六章不用单写“总结”很多论文模板要总结但你可以把它合并到“结论”小节里。写结论的时候不要用“本设计实现了……”这种空话要写“系统经过仿真测试能够在设定时间触发声光提醒LCD显示内容清晰按键响应灵敏达到预期设计目标。局限在于未进行实物验证后续可考虑移植至实物平台并增加远程通信功能。”评委会觉得你既务实又有后续规划意识。5.2 答辩讲解的演示策略答辩环节很多人的问题不是不懂技术而是不会“讲”技术。我用几个关键策略给你演示一下怎么讲。开场30秒你要解决的是“我做了什么”。话术可以是“老师好我这个题目的核心是设计一个智能药盒解决老年人漏服药、重复服药的问题。整个系统由STM32F103C8T6作为主控通过LCD1602显示当前时间和药物信息用按键设置提醒时间到点后蜂鸣器响、LED亮。我用了Proteus做了完整仿真并且对系统进行了模块化测试。”这段话清晰、有逻辑、有落地感。讲硬件时不要去念引脚表而要讲“为什么这么接”。比如被问到“为什么用LCD1602”就回“因为我只需要显示两行文本信息1602的成本和复杂度都最低如果题目要求显示中文我再换成OLED但OLED在Proteus里时序仿真不稳定所以选了1602。”这种对比思维是答辩高分的关键。被问“为什么用状态机”就回“因为系统存在多个运行阶段用if-else堆逻辑会让代码很难维护状态机把每个阶段拆开后续加功能只需要加新的状态不需要改动原有逻辑。”这里如果老师追问“状态机是怎么存储的”你就把枚举变量currentState拿出来讲一遍没问题。被问“如果做实物仿真跟实物的差异在哪些方面”这是个高概率考点。你从三个方面回一Proteus的按键无机械抖动实物的抖动需要完善的消抖处理二LCD的对比度在实物上需要现场调仿真里电位器默认给你调好了三实物要考虑供电方案比如用USB供电或电池供电需要额外的稳压电路。这个回答展示了从仿真到落地的完整思考。最后可以再补一句“这个项目后续我想再加一个GSM模块到点后发短信给子女手机。”这句话点到为止既展示了前瞻性又不会让老师觉得你在吹牛。5.3 从课程设计到真正产品四个值得深挖的扩展方向做一个项目如果不扩展那它的价值就局限在课程分数里。我把这个智能药盒实物化过程中最有价值的几个扩展方向列出来你带入报告和答辩时会有用方向一远程通知。药盒到点提醒老人可能没听到。加ESP8266或者GSM模块把提醒事件推给子女的微信或者短信这才能实现远程监护。STM32F103C8T6的USART2或者USART3正好可以串口接ESP8266代码里在进入提醒状态时多调一个send_reminder_to_wechat()就行。方向二用药记录。系统记录用户每次药物提醒的确认时间存储在EEPROM或者SD卡里定期导出数据。这需要增加一个存储模块和一个数据导出的协议代码上就是在提醒确认时打一个时间戳唯一的难点是当前时间来源要稳定所以这个方向适合换成DS1302方案。方向三多药格设计。当前方案用LCD显示“MED1、MED2”来区分药品种类但物理上只有一个仓。改成4个仓位每个仓位下面放一个微型舵机或者电磁锁提醒时打开对应的格子再配一个红外传感器检测是否取药还能实现“喂药记录”闭环。这个方向对结构设计和步进电机的控制是考验适合想做实物作品毕设的同学。方向四语音提示。蜂鸣器只能发出“嘀嘀”声老年人可能不知道是哪个药。用语音播放模块如WT588F在提醒时播报“请服用白色药片”交互体验会好很多代码量和硬件成本都会上升但这是产品化的必经之路。这些扩展思路不用全部实现在报告“总结与展望”里写出来会让你的项目显得有深度而不是“做完就完”。最后分享几个我自己的实操心得做这个项目最大的教训是在别人代码里打转。刚开始我也图省事从网上下载一个看着差不多的工程想改改就能交结果光是库版本不匹配、引脚定义混乱就折腾了两天最后还是一行一行重写才跑通。所以我的建议是主逻辑尤其是LCD初始化和按键扫描一定要自己写这两块代码量不大但写一遍你对系统的理解会完全不一样。另外一个心得是存储路径的事群里有同学因为工程保存在桌面路径含中文“桌面”Proteus加载不了hex一晚上都觉得是代码问题最后才查出来是路径问题。从建工程那一步开始全部用英文路径这是最省钱的经验。最后一个建议是关于“仿真通过之后”。仿真只是第一步如果你有条件强烈建议买一块STM32F103C8T6最小系统板和一块LCD1602把仿真里的电路一比一搭出来验证一遍。仿真里没有的接线问题、供电噪声、按键抖动实物上都会显现。真到那个阶段你才真正算是迈进了嵌入式开发的门。在这条路上踩过的坑写出来就是这篇文字。希望你能少走弯路一次跑通。
返回列表