H39基于51单片机自动灌装系统proteus设计,keil程序,c语言,AT89C51、设计报告、课题设计
作者:单片机仿真   类别:51单片机仿真    日期:2026-11-01 12:32:03    阅读:21 次   消耗积分:0 分

H39基于51单片机自动灌装系统,用AT89C51控制传送带与灌装两个执行器:LCD1602显示设定瓶数与实际计数,五按键设定0~255,确认后继电器驱动送瓶。数量检测到位即停带开灌装,装满触发后关阀续送,构成四步工序循环,够数自动停机并蜂鸣提示。

H39基于51单片机自动 图1

01 设计任务

功能介绍:

使用51单片机设计一个自动灌装系统,LCD1602 显示设定值与实际计数,传送带 + 灌装两个执行器协同工作,要求如下:

1、参数设定:五个按键"设置/增加/减少/确认",设定需要灌装的瓶数(0~255),LCD 第一行显示设定值、第二行显示实际计数;

2、传送带运行:确认后传送带电机启动,继电器吸合带动模拟传送带送瓶;

3、到位停带 + 灌装:数量检测到瓶子到位,立即停带并打开灌装执行器(仿真用红色 LED 指示);

4、装满检测续行:灌装完成(装满检测触发)后关闭灌装、传送带重新启动,进入下一瓶;

5、够数收工:计数达到设定值自动停机,蜂鸣器响约 0.5 秒提示完成。

 特别注意:前面 H26(汽车里程)、H30(传送带计数)、H31(带存储传送带计数器)都是"测"——数了多少、跑了多远;这一篇是"控"——数到几个就执行什么动作。它有两个执行器(传送带电机、灌装设备)和两个检测信号(到位、装满),本质上是一个四步循环的工序状态机。看懂 moto_control() 那二十几行,工业流水线的控制逻辑就入门了。


H39基于51单片机自动 图2

自动灌装系统proteus仿真整机图

Keil编译0错误0警告

02 硬件:两个检测、两个执行器

先把引脚关系理清楚,这张图上的器件比前几篇都多:

检测输入(两个按钮模拟传感器)

信号引脚上拉含义
装满检测 Check_fullP1.5R4 10K瓶子灌满了(按下=0)
数量检测 Check_numP1.6R5 10K有瓶子经过/到位(按下=0)

执行输出(两个)

执行器引脚驱动电路
传送带电机 MOTOP3.6R9 100Ω → Q2(PNP)→ 继电器 RL1 → +12V
灌装设备(LED 模拟)P2.4R10 100Ω → D2 红色 LED

人机界面

· LCD1602:数据口 P0(配 RP1 排阻上拉),RS/RW/E 接 P2.0~P2.2;

· 五个按键:设置 P3.0、增加 P3.1、减少 P3.2、确认 P3.3;

· 蜂鸣器:P1.7 → R11 1K → Q1(NPN)→ 模拟警铃。

两个细节值得单独说:

一是继电器用 PNP 驱动。 P3.6 输出低电平时 Q2 导通、继电器吸合——所以程序里 #define ON 0 / OFF 1,MOTO=OFF 才是停。这种"低电平有效"的写法必须靠宏名把极性遮住,否则后面读代码的人会被 MOTO=1 到底是开还是停搞晕。这个习惯在 H35、H36 都强调过,工业控制里尤其重要。

二是灌装用 LED 模拟。 真实设备的灌装阀是电磁阀,仿真里一个 LED 就够了——重点是时序:停带 → 开阀 → 装满 → 关阀 → 启动传送带。LED 亮灭就是阀的开闭,看仿真时盯着那盏红灯的节奏,就知道程序有没有写对。

03 五个标志位,一个工序状态机

这份程序的全部"记忆"都在五个 bit 变量里:

五个位变量各管一件事:设定模式标志表示正在改参数;装满标志是定义了但全程没用上的空位;到位标志表示瓶子已经停在灌装位;启动标志表示确认后系统正在跑;蜂鸣器标志表示任务做完了要响一声。几个按键分别负责置位、清零这些标志,主循环再靠它们判断该走哪一步。

对照按键就明白每个的职责:

· 设置键:set_flag=1,同时 start_flag=0——进入设定模式并停掉运行,防止边改参数边跑;

· 增加/减少键:只在 set_flag 为真时生效,Set_num 在 0~255 之间循环;

· 确认键:set_flag=0、Count_num=0、start_flag=1——退出设定、计数清零、系统开跑。"确认"这个动作顺手把计数器归零了,所以每次重新确认都是一轮新的生产任务,不用另外按清零键。

真正干活的是 moto_control(),它每轮主循环都跑一遍,是一个三层判断的工序状态机:

第一层:够数了吗?

到达设定值后的处理是这样走的:先把传送带停掉,再判断设定值是否为 0——为 0 就直接收工、不再做最后一瓶,避免「设定 0 瓶却仍然打开灌装阀」的荒唐动作;设定值非 0 时打开灌装,等装满信号到来才关灌装、清掉到位标志、结束本轮任务,并置起蜂鸣器标志响一声。

这里有个防呆守卫:if(Set_num)。如果设定值是 0,按确认后直接停机、不灌装——否则会出现"设定 0 瓶,但流程还是会打开灌装阀"的荒唐动作。参数为 0 时要有单独的守门条件,这个习惯在 H29(设定 0 分钟按开始无效)也提过。

第二层:没够数,瓶子到位了吗?

到位标志为真就停带、开灌装,等装满信号到来后关灌装、清到位标志、恢复启动标志准备下一瓶;到位标志为假说明瓶子还没送到,传送带保持运行继续送。

第三层:都没触发——MOTO=ON,传送带继续送。

传送带运行、瓶子到位触发数量检测、停带、开灌装、装满检测触发、关灌装、传送带重新启动,如此循环,直到计数等于设定值才整体停机。

注意 check_arrive_flag 的清除时机:它在"装满"之后才清,而不是在"停带"之后清。为什么?因为停带之后程序还要靠这个标志维持"正在灌装"的认知——如果停带就清标志,下一轮循环会认为"没到位",直接把传送带又开起来,灌装阀还没开完就被打断。这类"标志清早了"的 bug 在流水线程序里特别常见,看到设备动作一顿一顿地抖,先查标志清除位置。

04 中断里的边沿检测:怎么"数一下"

计数发生在 T0 中断里(10ms 一次):

用一个静态变量记住上一拍的电平:上一拍已经记下「按下」、这一拍仍然按着,就把静态变量清零(相当于宣告这次按下已经处理过了),此时才计一次数并置到位标志;上一拍没记下、这一拍检测到按下,只把静态变量置一,本拍不计数。这样一次按下只累加一次,等效于给按钮做了软件消抖。

这段代码的本质是用两个状态记住"上一次是什么电平",从而只对"变化"作出反应。把它拆开看:

· temp_check == 0 且检测到按下 → 记下 temp_check = 1,这一拍不计数;

· 下一拍 temp_check == 1 且仍然按着 → 把 temp_check 清零(相当于宣告"这次按下已经处理过了"),此时才计数。

因为 10ms 才进一次中断,人手按一下至少几十毫秒,所以"按下"这件事会被 interrupt 看到多次——如果直接 if(Check_num==0) Count_num++,按住一秒就能加几十次。加了这层边沿状态机,一次按下只计一次,等效于给按钮做了硬件消抖。

这就是软件边沿检测,和 H30 的"T0 计数器初值 0xFFFF 单脉冲捕捉"正好是两条路:

方案实现优点代价
硬件计数器(H30)T0 设为计数器模式,初值差 1 就溢出不占 CPU、响应快要占用一个定时器/计数器,且只能接特定引脚(T0/T1)
软件边沿(H39)定时中断里存上一次电平,比对变化任意 IO 都能用、逻辑可扩展采样周期决定最小脉冲宽度(这里 10ms)

"任意 IO 都能用"是软件方案的最大价值:Check_num 接的是 P1.6,根本不是计数器的输入脚,硬件方案压根用不上。所以实际工程里,几个传感器同时计数,大多是软件扫描 + 边沿判断。

顺带说一个隐患:Count_num 是 int,在中断里 Count_num++、主循环里读它比较。51 是 8 位机,int 的读写分两条指令,理论上主循环可能在"高低字节刚改了一半"时读到错值。这份程序里因为计数变化慢、主循环又一直在读,出问题的概率极低;但严谨的做法是在主循环读之前先关中断、读完再开(EA=0; x=Count_num; EA=1;),或者干脆用 uchar 并保证不超过 255。这种"跨中断共享变量"的原子性问题,答辩时被问到的概率不低。

05 LCD1602:设定界面怎么摆

显示部分没什么花活,但有两个细节:

一是定长三位补零显示。Display_data(hang, lie, num) 把数字拆成百/十/个三位,每位的 ASCII 码是"数字 + 0x30",然后连续写三个字符:

三次写入按百位、十位、个位的顺序来,行号是同一个参数、列号依次加一;定位怎么算的,放到本节后面的定位函数里一起看更清楚。

固定三位、前导补零,所以屏幕上是 Setnum: 003、Measure: 012 这种格式。好处是刷新时永远是三个字符,不用考虑"位数变了要不要清残留"——如果做"消前导零"的格式,从 100 掉到 99 时会剩个"0"在最后一位(H24 讲数显消隐时踩过)。界面定宽定长,是省心的第一原则。

二是忙检测被注释掉了。 看 Busy() 函数:

函数里先把寄存器选择置为命令、读写选择置为读,拉高使能,等两段短延时过去,读回状态位那行已经被注掉,使能拉低后固定返回「不忙」。

这是 Proteus 仿真必须做的妥协:仿真里的 LCD1602 模型在某些时序下不会正确响应忙标志,while(Busy()) 会死等,程序直接卡死。所以仿真版一律屏蔽忙检测、改成固定延时(delay1602() 两次)。

但上实机必须把那一行还原:真 LCD1602 在清屏、写入等操作期间确实会忙,不判忙硬写会丢字符、甚至显示乱码。H33 也讲过这个坑,这里再确认一遍:"仿真屏蔽、实机打开"这两份要留个开关(比如 #define SIM_LCD 1 包一层),别只留注释。另外这段 wdata() 里还有一句多余的 P0 = 0XFF; 紧跟着 P0 = del;——一次写数据送两遍,属于改程序时的残留,不影响功能。

06 按键与 1602 的行列定位

按键扫描用的是 H21 那个通用 KEY_Scan(mode):key_up 标志 + 10ms 延时消抖,mode=1 支持连按、mode=0 不连按。这里是 KEY_Scan(0)——设置参数时按一下加一,按住不放不会疯跑,符合"设定值要精确"的需求。如果想加速调参,把增加/减少改成 KEY_Scan(1) 就能长按连加(H24 的 INC/DEC 长按连调就是另一套更完整的写法)。

1602 的光标定位函数收拾得很干净,值得抄走:

函数主体是两个判断加一次加法:先按行号定基址,再加上列号偏移,把算出的地址当命令发出去,最后发要显示的那个字符。

第一行基址 0x80、第二行 0xc0,列号减一就是偏移——这套地址是 1602 的硬规矩(DDRAM 第一行 0x00~0x27,第二行 0x40 起,命令里再加 0x80 的"写地址"位)。L1602_string 在此基础上按字符串逐字写,b==16 兜住 16 字符宽度,防止写到行尾越界绕回行首。

07 排错清单

1、按确认后电机不转:先看 Set_num 是否为 0(设定 0 是停机状态,不是故障);再查 P3.6 → Q2 基极电阻是否接、继电器是否接 +12V——PNP 驱动时 IO 输出低才导通,用万用表量一下 P3.6 有没有变低;

2、LED 一闪就灭,看不到灌装过程:装满检测(P1.5)如果在仿真里初始就是低电平,程序判断"已经装满"会立刻关阀。平时该是高电平(未满),按下才变低;按钮没接上拉或接反就会出这个现象;

3、传送带一直跑,从不停:查数量检测 P1.6 有没有信号进来。中断里 temp_check 的状态机要求"先看到按下、下一拍再确认",如果信号一直为低(按钮常按/接反),反而刚好触发一次后就卡住了;用 LED 跟着 Check_num 的电平闪一下最快定位;

4、计数按住一次加好几个:边沿检测没生效——检查 temp_check 是否被重复初始化(static 丢了会被每次进中断重置),或者中断周期被改得太长(10ms 合适,100ms 时人手快按可能漏检);

5、灌装完不动了/卡死在灌装:check_arrive_flag 没清或清早了。按 03 节的时序核对:它是"装满后清",不是"停带时清";

6、LCD 花屏或无显示:仿真是 RP1 排阻上拉 P0 没接;实机是忙检测还没打开(//busy_flag = ... 那行还注释着);另外 RV1 对比度电位器没调也会白屏;

7、源码三处小问题,改不改都能跑:① full_flag 定义了全程没用,删掉;② wdata() 里 P0=0XFF; P0=del; 连写两次,留后一句;③ moto_control() 的 else 分支是空的,意味着"未启动"时不会主动把 MOTO 置 OFF,靠上一次状态维持——想更稳就在 else 里补一句 MOTO=OFF; LED=OFF;。

08 总结

把 H26、H30、H31、H39 这四篇连起来看,是一条很清晰的升级路线:

篇目干的事关键能力
H26 里程计数数脉冲、算里程定时器"一开双用"
H30 传送带计数数件数、到值停机单脉冲捕捉 + 定值控制
H31 带存储计数设定值掉电不丢手写 I2C + EEPROM
H39 自动灌装数件数 + 控制执行器动作工序状态机 + 多信号协同

前三篇是"看",这一篇是"做"。多出来的东西只有一个——把计数结果翻译成执行器动作,而这件事靠的是标志位和判断顺序,不是新器件、不是新协议。工业控制的门槛往往就在这里:逻辑不难,顺序很重要。

后面还会继续做类似"流程控制"的设计,把检测、判断、执行这三段的套路走熟。

欢迎关注,持续更新!


09 文件日期修改

如果你想把文件修改为最新的日期,又不想新建工程,那么你可以参考下面的文章。

"如何不打开程序的情况下更改proteus和keil程序的日期?"

工具和仿真文件在一起,见下面的下载链接。


10 资料下载

全套资料包含 Keil 工程(C 语言源码 + hex 文件)、Proteus 仿真工程、设计报告、程序流程图、讲解视频,以及编译截图和仿真截图。下载后可直接打开运行,也可用于课程设计、毕业设计参考。

点我下载全套资料 →

也可以关注公众号「单片机仿真」,回复 H39 获取下载入口。公众号内还有 A / T / H 全系列 400 多个单片机仿真实例,回复「目录」可查看完整清单。

同类设计合集:H 系列单片机仿真合集目录(含设计报告、视频讲解、流程图);全部系列合集总目录

版权所有,转载本站文章请注明出处:proteus单片机
上一篇:H38基于51单片机数码管显示DS18B20温度proteus设计,keil程序,c语言,AT89C51
下一篇:H39基于51单片机自动灌装系统proteus设计,keil程序,c语言,AT89C51、设计报告、课题设计
${comment['nickname']}   ${comment['createtime']}
  
       
${comment.content}
${reply.nickname} 回复 ${comment.nickname}    ${reply.createtime}
     
  
回复内容:${reply.content}