ARTICLE DETAIL

资讯详情

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

51单片机+霍尔传感器电机测速与PWM调速系统

51单片机+霍尔传感器电机测速与PWM调速系统 简介这是一套以STC89C51/52单片机为核心的霍尔传感器电机测速装置设计资料面向单片机学习者、课程设计或电子竞赛备赛人群。设计采用霍尔传感器非接触式测量电机转速LCD1602实时显示转速RPM与PWM占空比支持按键调速、开始暂停及正反转控制兼顾原理讲解与动手实践。压缩包共38个文件大小约9.73MB涵盖Proteus仿真文件dsn、C语言源码与hex烧录文件、原理图与PCB图样、docx/pdf使用说明和焊接指南以及图片、视频等辅助素材可完整支撑从仿真到实物制作的流程。资料还给出了磁铁与霍尔元件安装距离等关键注意事项便于快速复现。目前已有117人学习下载适合需要一套可直接参考的测速系统完整方案的使用者。1. 为什么是霍尔传感器测电机转速从资源包反推设计重点电机测速最常见的方案是编码器或红外对管但这套基于单片机 Proteus 仿真的霍尔传感器电机测速装置选择了一条更省硬件的路转轴上贴一颗小磁铁霍尔传感器感应磁通变化输出一个脉冲单片机数脉冲就能换算出转速。资源包是 51 单片机测速领域里比较完整的形态包含02__原理图、04__proteus仿真、03__PCB图布局图焊接图以及带注释的1-程序(注释)源码。主控是 STC89C51/52兼容 AT89S51/52、AT89C51/52外设只有 LCD1602、五个控制按键加复位键、霍尔信号调理和电机驱动。与增量式编码器相比霍尔方案不怕灰尘磁铁安装容错高成本低适合单片机课程设计、电子竞赛训练以及想快速在 Proteus 里跑通“测速调速”闭环的人。2. 霍尔传感器信号链磁铁安装距离、上拉电阻与脉冲输入引脚配置2.1 开关型霍尔器件与电机转轴磁铁的配合霍尔传感器分为线性型和开关型测速场景里绝大多数用开关型。开关型内部有电压比较器和施密特触发器当磁感应强度超过动作阈值输出电平翻转转速测量正是利用磁铁每转一圈让霍尔输出一个脉冲这个特性。它不需要机械接触没有码盘开槽也不容易积累灰尘。磁铁安装是整个信号链里最容易被低估的环节。资源的使用说明里特别提到“磁铁和霍尔元件最近距离在2mm左右”这句话背后是磁通密度随距离急剧衰减。太近了磁铁转动时会擦碰霍尔外壳导致传感器移位甚至损坏太远了磁通密度低于释放阈值某一个脉冲会丢失LCD 上显示的转速就会忽高忽低并且不是匀速跳变。安装时还要注意磁铁极性必须一致。如果为了配重贴了两颗磁铁一颗 N 极朝外、一颗 S 极朝外霍尔在一个旋转周期内会被触发两次转速显示会直接翻倍。这一点在焊接 PCB 和固定电机时最容易忽略。2.2 引脚选择与上拉电阻设计常见开关型霍尔传感器如 A3144内部是开漏输出。开漏结构本身只能把输出拉低高电平必须靠外部上拉电阻提供。51 单片机 P1 口是准双向口虽然有内部弱上拉但驱动能力有限霍尔信号上升沿会变得平缓加上电机换向干扰可能造成单片机多计数一次。实际项目中霍尔输出应当接 P3.5T1或 P3.2INT0并外接 4.7kΩ 到 10kΩ 的上拉电阻到 5V。这样信号边沿够快也能直接配合第 3 章要讲的定时器计数。信号链的关键参数可以按下面这张表对照检查参数项推荐值/设计值说明霍尔器件A3144 或等效开关型霍尔开漏输出必须上拉磁铁间距2mm 左右太近剐蹭太远漏脉冲上拉电阻4.7kΩ ~ 10kΩ阻值越大边沿越缓高速时不建议大于10k单片机输入脚P3.5T1或 P3.2INT0典型接法为 T1 输入计数脉冲电平5V 逻辑电平与 STC89C51 共用电源上拉电阻阻值的选择可以算一下5V 上拉10kΩ 时低电平灌电流只有 0.5mA完全在霍尔 IC 允许范围内。霍尔信号属于低频脉冲即便转速 3000RPM 也只有 50Hz10kΩ 上拉与寄生电容产生的 RC 延时远小于脉冲宽度所以低速演示用 10kΩ 没问题。如果电机转速很高或者信号线较长换成 4.7kΩ 更稳妥。2.3 用外部中断0验证霍尔脉冲是否正常拿到下载包后不要急着研究整套测速算法先把霍尔信号链单独验证。可以用外部中断 0 做脉冲计数配合串口或 LCD 观察能最快区分“霍尔没信号”和“转速算法写错”这两类问题。以下代码基于 STC89C51外部中断 0 配置为下降沿触发。// 验证霍尔脉冲每个下降沿进入一次中断pulse_count 加 1 #include reg52.h volatile unsigned int pulse_count 0; void ext0_init(void) { IT0 1; // IT01 表示 INT0 下降沿触发 EX0 1; // 打开 INT0 中断使能 EA 1; // 打开总中断 } void ext0_isr(void) interrupt 0 { pulse_count; // 每次脉冲到达都会执行这里 }代码里IT0 1的关键是匹配霍尔输出从高到低的跳变。A3144 在磁铁经过时会输出一个低电平脉冲所以下降沿触发最合适。如果实际使用的霍尔传感器是推挽输出极性相反就把IT0改成 0选择低电平或上升沿触发。验证过程中让电机空转pulse_count应该稳定递增。如果它完全不动先检查磁铁是否装反、霍尔供电是否正常、上拉电阻是否漏焊再去查程序。3. 转速计算核心定时器1计数与定时器0闸门里的 RPM 换算3.1 每转一个脉冲时的 RPM 公式转轴上一颗磁铁霍尔器件每转输出一个脉冲那么 1 秒内的脉冲数就等于每秒转数乘以 60 就是转/分。通用公式是RPM (1秒内脉冲数 / 每转脉冲数) * 60当每转 1 个脉冲时RPM 就是脉冲数 × 60。如果说显示转速是 3000RPM意味着每秒应该数到 50 个脉冲。仿真时如果想复现 3000RPM只需要把霍尔信号源的频率设置成 50Hz。如果后来希望提高低速测速分辨率在转轴上装两颗对称磁铁每转脉冲数变成 2公式就要除以 2得到RPM 脉冲数 * 30。资源包里的仿真图和程序注释默认是单磁铁方案所以直接用乘 60 的逻辑。3.2 让定时器1当计数器、定时器0当闸门STC89C51 内部有两个 16 位定时器/计数器。把定时器 1 配置为计数模式外部脉冲接到 P3.5T1 引脚每出现一次下降沿TH1:TL1的值加 1。定时器 0 保持定时模式中断周期固定累计到 100 次就是 1 秒。等 1 秒闸门到了之后读取TH1:TL1的值就是这一秒内的脉冲数。这里有一个容易忽略的细节读取 16 位计数结果之前必须先停掉计数器也就是把TR1清零。否则在读取TL1的瞬间TH1刚好发生进位会读到低位高位错位的数据转速会偶发跳变。读完计数值、清零、再重新启动计数器整个过程代码量不大但顺序最容易被新手写反。3.3 完整测速代码与初值计算下面是一份可以直接抄进工程文件的测速核心代码。示例按 12MHz 晶振、STC89C51 工作在 12T 模式机器周期 1μs定时器 0 中断周期 10ms100 次中断就是 1s。// 定时器0做10ms闸门定时器1计数外部脉冲主循环中换算RPM #include reg52.h #define GATE_TIMES 100 // 10ms * 100 1s volatile unsigned int timer0_cnt 0; // 10ms 中断累计次数 volatile unsigned int speed_rpm 0; // 最终转速结果 void timer0_isr(void) interrupt 1 { TH0 0xD8; // 12MHz 定时10ms65536-100000xD8F0 TL0 0xF0; timer0_cnt; } void timer1_counter_init(void) { TMOD (TMOD 0xF0) | 0x50; // 定时器1方式1计数模式P3.5下降沿计数 TH1 0x00; TL1 0x00; ET1 0; // T1不需要中断 TR1 1; } void timer0_gate_init(void) { TMOD (TMOD 0x0F) | 0x01; // 定时器0方式1定时模式 TH0 0xD8; TL0 0xF0; ET0 1; TR0 1; } void main(void) { unsigned int pulse_cnt; timer0_gate_init(); timer1_counter_init(); EA 1; while (1) { if (timer0_cnt GATE_TIMES) { timer0_cnt 0; TR1 0; // 读之前停止计数防进位错位 pulse_cnt (unsigned int)(TH1 8) | TL1; // 读出1秒内的脉冲数 TH1 0; TL1 0; TR1 1; speed_rpm pulse_cnt * 60; // 每转1脉冲脉冲数*60就是RPM // 这里可以调用LCD1602显示speed_rpm } } }TMOD的赋值写法是“先清对应位再置位”避免修改另一个定时器的配置。TH1 8与TL1拼接时要注意类型转换否则移位结果默认是int高 8 位会丢失。pulse_cnt * 60最大可能超过 65535但 65535 对应每分钟 6 万多转物理上不会出现在普通直流电机上所以直接用unsigned int保存足够。12MHz 的 10ms 初值 0xD8F0 是根据65536 - 10000算出来的如果换成 11.0592MHz 晶振机器周期变成 0.9216μs10ms 需要的计数是 10852初值就是 65536 - 10852 0x5C5C不能直接照抄。3.4 测速刷新率和量程取舍转速测量本质上是在固定闸门时间内数脉冲。闸门时间越短刷新越快但低速时误差越大。对 1 个脉冲/转的情况以下表格给出不同闸门下的分辨能力闸门时间1Hz脉冲对应显示最低可分辨步进适用场景0.1s600 RPM10 RPM高速电机刷新快0.5s120 RPM2 RPM中速电机折中方案1s60 RPM1 RPM低速测量显示稳定仿真包里的程序按 1s 闸门写因为演示时数字稳定方便截图和讲解。做实际调速系统时0.5s 通常更合适既能看出转速变化低速也不至于完全没反应。修改闸门时间要同时处理两个地方GATE_TIMES和定时器 0 初值不能只改一个。4. 按键调速、启停与正反转背后的 PWM 控制逻辑4.1 用定时器0中断同时承担 PWM 时基和测速闸门51 单片机只有两个定时器定时器 1 已经用于计数霍尔脉冲定时器 0 就必须同时完成 PWM 产生和测速时基两项任务。常见做法是把定时器 0 的中断周期设成 1ms产生 1kHz 的 PWM 信号中断内同时累计 1000 次作为 1s 闸门。1kHz 对小型直流电机完全够用而且占空比调节粒度可以做到 1%。PWM 输出接到电机驱动芯片的使能端方向和正反转由普通 IO 控制。下面代码以 P1.0 输出 PWM、P1.1 和 P1.2 控制方向为例与常见 L293D/L298 接法兼容。// 定时器0中断1kHz PWM 1s测速闸门 #include reg52.h sbit motor_pwm P1^0; // 输出PWM到驱动使能端 sbit motor_dir1 P1^1; // 方向控制1 sbit motor_dir2 P1^2; // 方向控制2两者互补输出 volatile unsigned int pwm_duty 50; // 占空比0~100初始50% volatile unsigned int pwm_cnt 0; // PWM相位计数 volatile unsigned int gate_cnt 0; // 闸门累计1000次为1s void timer0_isr(void) interrupt 1 { TH0 0xFC; // 12MHz1ms初值65536-10000xFC18 TL0 0x18; if (pwm_cnt pwm_duty) motor_pwm 1; else motor_pwm 0; pwm_cnt (pwm_cnt 1) % 100; // 0~99循环实现1%精度 gate_cnt; if (gate_cnt 1000) // 1000次1ms 1s闸门 { gate_cnt 0; // 这里读取定时器1的计数并计算RPM逻辑见第3章 } }pwm_cnt pwm_duty是关键比较。当pwm_duty 0时输出永远为低电平电机停止pwm_duty 100时输出持续高电平电机满速。用%100回绕而不是if (pwm_cnt 100) pwm_cnt 0可以让高低电平切换位置更稳定避免相位滑动。如果把定时器初值改成 0xFF9C中断频率能提高到 10kHz但 51 单片机中断开销明显增加主循环扫描按键更容易卡顿这套资源用 1kHz 是合理的取舍。4.2 五个按键的扫描与占空比限制按键功能在资源说明里写得很清楚1 键加速、2 键减速、3 键正转、4 键反转、5 键开始/暂停。六个按键里还有一个是单片机的复位键连接复位电路不需要软件扫描。按键处理的重要边界是占空比不能超过 0~100。如果加速到 100 继续加变成 101 后pwm_cnt pwm_duty会导致输出一直为高看起来像失控如果减速到 0 继续减负值在无符号比较中会变成巨大数同样异常。所以每步加减之后都要限幅。下面是一段带消抖和限幅的加速键处理逻辑sbit key_acc P2^0; // 加速键低电平有效 void key_acc_process(void) { if (key_acc 0) { delay_ms(20); // 消抖 if (key_acc 0) { if (pwm_duty 100) pwm_duty; while (key_acc 0); // 等待按键释放 } } }短按一次占空比加 1长按连续加速需要把while替换成每隔几十毫秒自动加一的计数逻辑同时检测是否有其他按键按下否则长按会一直阻塞主循环。正反转切换键不宜在电机高速旋转时直接改变motor_dir1和motor_dir2因为电流方向瞬间反转会对驱动管造成冲击。更安全的顺序是先将pwm_duty清零延时 200ms 左右再切换方向最后恢复原占空比。仿真里这条顺序看不出区别实物 PCB 上能明显降低驱动管发热。4.3 正反转切换的硬件与逻辑注意事项正反转要求电机电极电压反向资源包里的原理图若用两个方向引脚大概率接的是 H 桥驱动。H 桥的使能端接 PWM两个方向引脚必须互补正转时dir11, dir20反转时dir10, dir21。最危险的是上电瞬间两个 IO 默认状态都为高H 桥上下桥臂同时导通形成短路。程序初始化时要在main()开头主动把dir10, dir20或者都赋成低电平等第一次按键事件再改变方向。LCD1602 第二行显示的占空比应当和实际 PWM 输出一致。调试中发现显示 50% 但电机转速变化不明显先用 Proteus 虚拟示波器看 P1.0 是否有方波再看方波是否接在 H 桥使能端。用示波器确认波形比反复改代码快得多。5. Proteus 仿真复现与霍尔传感器波形验证技巧5.1 用脉冲发生器模拟霍尔输出绕开物理模型Proteus 元件库里没有“磁铁旋转霍尔传感器”的完整物理模型这套资源里的仿真图霍尔部分通常被抽象成一个脉冲发生器或者数字时钟源连接到单片机的 P3.5。打开04__proteus仿真时如果看到一个小方波发生器图标就说明它是用来模拟霍尔脉冲的。理解这一点很重要仿真环境里没有距离 2mm 的问题取而代之的是脉冲源的频率和幅值。5.2 频率设定50Hz 对应多少 RPM仿真时最容易把频率和 RPM 搞混。脉冲源设置的 50Hz 表示每秒钟输出 50 个脉冲对于每转 1 个脉冲的霍尔方案就是电机每秒转 50 圈折合 3000RPM。同理想让 LCD 显示 1000RPM脉冲源频率应该设置为 1000 / 60 ≈ 16.67Hz。如果仿真跑出来后显示数值比预期大两倍先检查仿真图里是不是用了两个磁铁对应的双脉冲模型或者霍尔输出是否同时接到了两个可计数引脚。5.3 信号抖动和磁铁距离在仿真里的验证真实的 2mm 间距问题在仿真里可以用带抖动脉冲的信号源近似。把脉冲源的上升沿抖动打开或者让脉冲间隔随机变化观察 LCD 转速是否跳动。如果转速跳得厉害可以在霍尔输出到单片机引脚之间加一个小电容滤波或在外部中断代码里加入最小间隔判断丢弃时间过短的脉冲。这个“边沿间隔判断”对实物调试同样有效能滤掉电机换向器产生的火花干扰。5.4 三处最容易忽略的仿真调试点对照04__proteus仿真和02__原理图仿真跑不通的原因集中在以下三处现象原因处理转速一直为0脉冲源没接到P3.5或幅值低于数字高电平阈值设定脉冲源 5V 幅值检查网络标签转速显示翻倍每转产生两个脉冲或者两个输入脚同时计数只保留一路计数输入检查磁铁数量设置LCD 显示乱码晶振频率和程序初值不匹配把仿真里的晶振改成 12MHz与代码一致最后一个小技巧调试时把 LCD 上显示的转速同时通过串口发到 Proteus 虚拟终端一边调整脉冲源频率一边看串口数字是否线性跟随。如果只在某个频率段跳变多半是闸门时间和初值重装不匹配如果始终有固定倍数误差就回到公式重新确认每转脉冲数。先用 1s 闸门把逻辑跑通再缩短到 0.5s这样能最快定位是算法问题还是信号问题。本文还有配套的精品资源点击获取
返回列表