拓冰建站拓冰建站
首页 / 资讯中心 / 正文

基于51单片机的传送带计数系统设计与仿真实现

简介一套基于51单片机的传送带计数与查询系统仿真毕业设计资料面向电子、自动化等专业本科生及51单片机入门学习者。资源共79个文件压缩包约30.7MB内容覆盖LCD1602字符液晶显示、ST188光电传感器检测、定时器/中断计数、串口查询等关键环节文档与源码比例均衡既有STC89C52/AT89S52、DS18B20、L298等芯片的中文手册也有main.c、lcd1602.c等C程序源码以及Proteus仿真DSN、原理图SchDoc、器件清单xlsx、流程图和答辩技巧文档。已有148人学习下载。包内目录按1.程序、2.原理图、3.仿真、4.流程图、5.器件清单等分模块组织便于对照硬件连接与代码逻辑逐步调试可帮助读者快速完成课设或毕设理解嵌入式系统从硬件设计到软件实现的完整流程。1. 用 51 单片机给传送带加一个计数器价值不止于数数传送带上的工件不断流过光电开关每被遮挡一次就产生一个脉冲基于 51 单片机的传送带计数系统要做的就是把这些脉冲变成可读的数字通过 LCD1602 实时显示并允许操作员随时查询累计值。这个系统在课程设计和工厂小型工位里都很常见它的价值不在于“数数”本身而在于把传感器信号调理、外部中断、显示驱动和按键交互全部串在一条链路上。真正动手做会发现计数逻辑十分钟能写完LCD1602 的时序和传感器去抖才会耗掉大半时间。这篇文章会从硬件选型讲到 Proteus 仿真联调再到掉电保存这类进阶点适合正在做课程设计、或想低成本验证一个计数原型的人。2. 传送带计数系统的硬件架构与 51 单片机选型分析2.1 传感器信号怎么进单片机从机械触点变成中断脉冲传送带计数的源头是传感器。常见的方案有三类对射式光电开关、电感式接近开关、机械触点式限位开关。对射式光电开关在工件通过时阻断光路输出级通常是 NPN 或 PNP 三极管NPN 型在遮光时输出低电平正好匹配 51 单片机的外部中断输入。接近开关则对金属物体产生响应适合传送带上全是金属件的场景。机械限位开关信号抖动最严重需要重点做去抖处理。无论哪种传感器目标都是把“有/无工件”变成单片机可识别的电平跳变。51 单片机的 P3.2 和 P3.3 分别对应外部中断 0 和外部中断 1TRIG 脉冲接到这两个引脚上就可以用硬件中断触发计数逻辑。要注意传感器输出的电平必须被整定在 0~5V 之间如果现场传感器是 12V 供电的输出需要经过光耦或电平转换再进入单片机否则高压会直接损坏 I/O 口。输入方式信号特征适合场景对射式光电开关遮挡时输出低电平脉冲传送带料流检测最常见电感式接近开关金属接近时输出电平变化金属工件计数机械限位开关触点通断抖动明显低速、低成本场景Proteus 仿真阶段不必纠结传感器型号用按键模拟脉冲或直接用信号发生器输出方波效果和真实传感器在逻辑层面一致。仿真中接一个上拉电阻到 P3.2按键按下接地模拟遮挡就能验证中断触发路径。2.2 为什么用 51 而不是直接上 STM32中断响应与生态很多读者会想STM32 资源更丰富为什么不直接用它这个话题在 51 单片机课程设计里反复出现。答案是这个项目的复杂度刚好落在 51 单片机的能力边界内。外部中断 0 的硬件响应时间在几个机器周期内12MHz 晶振下约几微秒对于每秒几十个工件的传送带来说绰绰有余。LCD1602 是慢速并行设备51 的 I/O 直接驱动不需要任何外围芯片。成本上STC89C52RC 这类芯片散买几块钱在 Proteus 里用 AT89C51 模型也完全等价。另一个重要因素是 51 单片机的中断模型足够简单清晰。外部中断 0 的使能只需要三个位IT0 控制触发方式、EX0 控制使能、EA 控制总开关。这种简单性让初学者能把注意力放在“中断服务函数到底怎么被调用”上而不是像 ARM 那样面对复杂的中断控制器。对于需要快速原型验证的工程师51 加 Proteus 仿真的组合也能在半天内把逻辑跑通成本远低于画 PCB 再调试。2.3 Proteus 仿真与实物调试的差异对照仿真做得好不好取决于你是否意识到 Proteus 和真实硬件的差别。Proteus 不会产生真实的电气噪声传感器抖动需要靠手动按键的“物理抖动”来模拟或者用信号源加随机干扰信号。时序问题是真实的LCD1602 的初始化顺序和延时长短在仿真里同样会出错。逻辑错误也是真实的中断里写了死循环仿真里照样跑死。我一般会用仿真验证两件事第一是代码逻辑是否符合预期第二是 LCD 显示时序是否正确。然后带着这两个验证结果去焊实物实物阶段的坑通常只剩电源噪声和传感器安装位置这两个机械层面的问题。换句话说仿真把“代码层面的问题”和“硬件层面的问题”切开这在调试方法论上对新手帮助很大。3. 核心代码实现外部中断计数、LCD1602 时序与查询模式切换3.1 外部中断计数代码配置、去抖和溢出边界在 Keil 里选择 AT89C51 或 STC89C52RC 芯片先写中断配置。外部中断 0 对应 P3.2 引脚IT01 表示下降沿触发IT00 表示低电平触发。传送带传感器输出的是窄脉冲用下降沿触发最合适否则工件长时间停留在检测区域时低电平触发会导致反复计数。#include reg52.h #include intrins.h #define uchar unsigned char #define uint unsigned int sbit RS P2^0; // LCD 寄存器选择 sbit RW P2^1; // LCD 读写选择 sbit EN P2^2; // LCD 使能信号 sbit SENSOR P3^2; // 外部中断0输入接传送带传感器 sbit KEY_QUERY P3^3; // 查询模式切换按键 uint g_count 0; // 当前累计计数值 uint g_hist 0; // 查询用的历史快照 bit g_query 0; // 0-实时模式 1-查询模式 void DelayMs(uint ms) { uint i, j; for (i ms; i 0; i--) for (j 114; j 0; j--); // 12MHz 下约 1ms } void Ext0_ISR(void) interrupt 0 { uchar t; for (t 0; t 30; t); // 软件确认过滤窄毛刺 if (SENSOR 0) // 再次读取低电平有效 g_count; // 累加计数 } void main(void) { IT0 1; // 下降沿触发 EX0 1; // 使能外部中断0 EA 1; // 打开总中断 LCD_Init(); // 初始化 LCD1602 while (1) { if (KEY_QUERY 0) // 检测查询按键 { DelayMs(20); // 软件消除按键抖动 if (KEY_QUERY 0) { g_query ~g_query; // 切换实时/查询模式 if (g_query) g_hist g_count; // 进入查询时保存快照 while (KEY_QUERY 0); // 等待按键释放 DelayMs(10); } } LCD_Show(); // 循环刷新显示 } }中断服务函数里的 for 循环起软件确认作用进入中断后等几毫秒再读一次传感器引脚如果还是低电平才认定这是一次有效计数。这个逻辑能过滤掉大部分按键抖动和脉冲毛刺但要注意如果传感器脉冲宽度本身就小于这个确认窗口脉冲就会被当作毛刺丢掉后面的进阶章节会专门讨论这个问题。g_count 用的是 unsigned int最大 65535传送带单日产量超过这个值时需要改成 unsigned long 并扩充显示缓冲区。按键查询放在主循环而不是中断里这个选择是刻意的。外部中断 0 的自然优先级高于主循环计数脉冲可以随时打断查询处理而查询按键如果放在另一个中断里就可能出现两个中断互相穿插的竞态。主循环扫描的方式虽然简单但在这个场景下反而是最可靠的。3.2 LCD1602 时序初始化0x38 之后必须等LCD1602 的驱动代码是网上搜索量最大的关键词之一但很多人下载了现成代码还是显示黑块原因往往是不理解时序而盲目照抄。LCD1602 是 Hitachi HD44780 协议所有操作都靠 EN 引脚的下降沿锁存数据。RS 决定操作对象RS0 写命令RS1 写数据。RW0 表示写入RW1 表示读取忙标志。void LCD_Cmd(uchar cmd) { RS 0; RW 0; LCD_DATA cmd; EN 1; _nop_(); EN 0; // 下降沿锁存命令 DelayMs(2); // 命令执行需要时间清屏指令应加长 } void LCD_Data(uchar dat) { RS 1; RW 0; LCD_DATA dat; EN 1; _nop_(); EN 0; DelayMs(2); } void LCD_Init(void) { DelayMs(15); // 等待 LCD 模块上电自检 LCD_Cmd(0x38); // 8位数据接口2行5x8点阵 LCD_Cmd(0x0C); // 开显示关光标不闪烁 LCD_Cmd(0x01); // 清屏地址归零 LCD_Cmd(0x06); // 地址自动加1光标右移 }初始化序列的四条指令各有分工0x38 是功能设定告诉液晶屏用 8 位并行模式0x0C 决定显示属性0x01 清屏需要至少 1.64ms 执行时间所以 DelayMs(2) 在 12MHz 下只是勉强够用0x06 设置写入后光标移动方向。每条命令后的延时是为了绕过忙标志查询简化代码代价是整体刷新率变低但这个场景下无所谓。如果你希望显示刷新更快可以用读 BF 忙标志的方式替换延时原理是检测 D7 引脚电平为高表示忙。命令值功能功能设定0x388位数据、2行显示、5x8点阵显示开关0x0C开显示、关光标、不闪烁清屏0x01清屏并复位 DDRAM 地址到 0输入模式0x06地址加 1画面不移动第一行地址0x80DDRAM 地址 0第二行地址0xC0DDRAM 地址 0x40DDRAM 地址是显示的另一个关键点。LCD1602 内部显示缓冲区有地址映射0x80 是第一行首地址0xC0 是第二行首地址。写字符串时从这些起始地址开始后续写的每个字符会因 0x06 的设定自动排到下一个地址。3.3 查询模式的显示逻辑手动转字符串避免引入 printf显示模块要把数字转换成字符。在 51 单片机上直接用 sprintf 会引入庞大的库依赖Keil C51 的标准库会让 HEX 文件体积明显膨胀对仿真没有影响但真实烧录时接近 64KB 上限的芯片会出问题。手写一个转换函数更可控void LCD_Show(void) { uchar i; uint v g_query ? g_hist : g_count; // 查询模式显示历史快照 LCD_Cmd(0x80); // 第一行首地址 LCD_Data(g_query ? H : C); // H 表示查询历史C 表示当前 LCD_Data(N); LCD_Data(T); LCD_Data(:); // 从万位到个位逐位取模转换 LCD_Data((v / 10000 % 10) 0); LCD_Data((v / 1000 % 10) 0); LCD_Data((v / 100 % 10) 0); LCD_Data((v / 10 % 10) 0); LCD_Data((v % 10) 0); }取模运算逐个提取十进制位加 0x30 转成 ASCII 字符。5 位显示应对 0~65535 的整数范围如果想要显示 6 位以上需要在 v 前面加长类型并且把除法链补齐到对应位数。LCD_Cmd(0x80) 保证每次刷新都从行首开始避免残留字符干扰读数。4. Proteus 仿真 51 单片机电路搭建、HEX 烧录与联调排错4.1 在 Proteus 中搭建最小系统与传感器输入模拟打开 Proteus 新建工程从元件库选入 AT89C51、RESPACK-8、LM016LLCD1602 的等效模型、CRYSTAL、电容、按钮和电位器。AT89C51 就是 51 单片机的经典仿真模型LM016L 是 Proteus 里最常用的 1602 液晶模型引脚定义和实物一致。元件Proteus 关键字用途与连接要点AT89C51AT89C51主控晶振 12MHzLCD1602LM016LD0-D7 接 P0RS/RW/EN 接 P2.0-P2.2电阻排RESPACK-8P0 口上拉阻值 4.7k~10k晶振CRYSTAL12MHz两端接 22pF 电容到地按键BUTTONP3.2 模拟传感器P3.3 接查询键电位器POT-HGLM016L 的 V0 脚调节对比度P0 口是开漏输出必须接上拉电阻这是 LCD 花屏最常见的硬件原因。晶振电路在 Proteus 里可以直接用 CRYSTAL 元件两端各接一个电容到地数值选 22pF~30pF。复位电路用经典的 10uF 电容接 VCC、10k 电阻接地RST 引脚取二者连接点。LCD1602 的 V0 脚接电位器中间抽头调节对比度到屏幕出现黑色像素块为止。传感器输入用两种方式验证单次触发用按键按下时 P3.2 被拉低产生下降沿连续脉冲用信号发生器输出方波。DCLOCK 信号源频率设 20Hz正好对应每秒 20 个工件的场景比手动按键更适合测试 LCD 刷新和计数连续性。4.2 加载 HEX 文件并完成基础联调在 Keil 中新建工程芯片选择 Atmel AT89C51把上一章的代码完整粘贴进去Target 选项中勾选 Generate HEX File编译通过后会在输出目录生成 .hex 文件。回到 Proteus 双击 AT89C51 芯片在 Program File 一栏选择生成的 hex晶振频率填 12MHz点击仿真按钮。注意要先停止当前仿真再重新加载 hex否则 Proteus 不会自动刷新固件。启动仿真后LCD 第一行应显示CNT:00000。此时按一下 P3.2 上方的按键计数值从 0 变 1连续按 5 次显示变成CNT:00005。再按 P3.3 查询键显示切换为HNT:00005H 开头代表历史快照。按键在按下瞬间触发中断松开时的上升沿不会触发因为 IT01 只认下降沿。4.3 仿真常见排错LCD 黑块、计数跳变、查询失效第一个坑是 LCD 只显示一排黑块。先调电位器改变 V0 电压黑块变成浅色条纹说明对比度偏了如果无论如何调节都没有字符检查 0x38 之前的延时。Proteus 里 LM016L 初始化比实物更挑剔LCD_Init 开头的 DelayMs(15) 不能省。另一种可能是 P0 没有接排阻数据线呈高阻态指令根本进不了液晶模块。第二个坑是按键按一下计数跳好几下。这在真实硬件上是因为机械触点抖动在仿真里则是信号源或按键模型产生的多次电平跳变。检查中断配置是否写成了 IT00如果采用低电平触发按住按键期间中断函数会被反复进入。正确做法是 IT01 下降沿触发并且保留中断服务函数里那个 for 循环的软件确认。第三个坑是查询按键偶尔失效。主循环里用 while 等待按键释放时如果外部中断频繁触发主循环的执行会被大量打断按键扫描节奏变得不稳定。但在这个系统里查询只是低频操作稍微等一会儿总会响应。真正需要警惕的是把按键扫描写进另一个中断然后跟外部中断 0 竞争优先级那才是彻底失效的根源。5. 让计数器更可靠定量验证、掉电保持与防抖边界在仿真环境里验证系统是否合格不能只靠肉眼观察。给 P3.2 接上 DCLOCK 信号源设置频率 50Hz运行 20 秒理论计数应为 1000 个脉冲。结束后对比 LCD 显示值误差在 0~2 视为通过。如果误差偏大先检查信号源频率是否稳定再看中断里的软件确认延时。50Hz 脉冲周期 20ms软件确认窗口只有几毫秒不会造成漏计但如果信号源频率提高到 2kHz脉冲周期只有 0.5ms中断里的 30 次空循环会吃掉大半个周期计数就会明显偏少。这就是防抖窗口与最大计数频率之间的边界防抖越长抗干扰越强但可计数的最大频率越低。掉电保存是这个项目最常见的进阶方向。STC89C52RC 内部自带 EEPROM用 IAP 指令读写不需要额外硬件。仿真中用 AT89C51 则没有内部 EEPROM需要在 I2C 总线上挂 AT24C02在断电前把 g_count 写入 EEPROM重新上电后读取恢复。写 AT24C02 时要注意每写一个字节需要约 5ms 的内部写入周期期间不能发送其他 I2C 指令。I2C 时序有三个检查点起始信号必须是 SCL 高电平期间 SDA 下降沿每个字节后必须等待 ACK停止信号是 SCL 高电平期间 SDA 上升沿。对照这三个点用示波器看波形能解决大多数读写失败问题。中断优先级的设置也值得单独验证。在 Reg52.h 中PX0 位可以单独提高外部中断 0 的优先级。在传送带上计数脉冲的实时性高于显示刷新如果 LCD 写数据时被打断会导致半个字符残影那就把 PX01 设为高优先级。不过要记住高优先级中断会延迟其他中断响应如果后续加入了定时器用于 ADC 采样需要重新评估这种设置是否还合适。最后给中断服务函数里那个软件确认循环加一个注释写清楚当前晶振频率下它约等于多少毫秒方便后人改频率时同步调整。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门