江科协51单片机 17-2 红外遥控电机调速实验调试总结

红外遥控直流电机 PWM 调速实验------调试全过程总结

工程路径C:\Users\54200\Desktop\51MCU\17 红外遥控电机转速

目标现象 :复现教学视频(BV1Mb411e7re P38)中"遥控器控制直流电机转速"的效果

最终状态 :✅ 已实现------空调遥控器单键(VOL-)循环调速:0停→1低速→2中速→3全速→0停

调试时间 :2026-08-30

参考教程:普中 51 单片机开发板配套教程(Bilibili BV1Mb411e7re P38)


目录


一、问题背景与目标

「17 红外遥控电机转速」工程初始为上一课的独立按键调速 版本。目标是改为教学视频 P38 中的红外遥控调速效果:上电电机停止,用遥控器按键逐步调节直流电机转速,数码管同步显示档位。

二、初始代码分析与方案设计

2.1 原程序结构

main.c 基于定时器 T0 产生 PWM(100us 中断,周期 10ms,即 100Hz)驱动直流电机(P1.0,经驱动电路接 J47 端子),K1 按键消抖循环切换四档占空比(0/30/70/100),数码管(P0 段选 + 74HC138 位选 LSA/LSB/LSC)显示档位。缺的只是红外接收部分。

2.2 红外遥控方案设计

采用 NEC 红外协议解码

硬件资源 用途
INT0 外部中断(P3.2,下降沿触发) 红外接收头 OUT 引脚,引导码下降沿进入解码
T0 定时器(100us 中断) 复用为脉宽测量时基 + PWM 产生
数码管第 1 位 显示当前档位 0~3

三、第一轮调试:NEC 红外解码实现

3.1 解码架构

在 INT0 中断服务函数中按 NEC 协议逐位解码:9ms 引导码低电平 → 4.5ms 高电平 → 32 位数据(地址码、地址反码、数据码、数据反码),并做键值反码校验防误码。

3.2 关键技术点

  • 脉宽测量不用软件延时 :解码期间 PWM 中断照常运行,软件延时函数会被打断导致测量失真。改为复用 T0 中断中每 100us 累加一次的时基计数器 g_ir_time(u8 类型,8 位读取天然原子,避免读撕裂)。
  • 中断优先级 :T0 设高优先级(PT0=1),保证 60 余毫秒的解码过程中 PWM 输出不中断,电机不顿挫。
  • '0'/'1' 判决:数据位高电平约 560us 判 '0',约 1.68ms 判 '1'(以 100us 计数次数为阈值)。

3.3 初版按键映射

按普中配套遥控器键值表:数字键 0~3 直接设档,VOL+ 升档、VOL- 降档。编译 0 错误 0 警告(20:06)。

四、第二轮调试:VOL+ 循环升档与键值对调

用户需求 :希望 VOL+ 为增、VOL- 为减,且最高档后再按能回到 0(循环)。用户实测反馈"按 VOL- 反而增档",据此判断该批次遥控器 VOL+/VOL- 键值与常见表相反,对调两键映射,并实现 VOL+ 循环回 0、VOL- 降到底为止(20:12 编译)。

五、第三轮调试:"转几秒停止"之谜

5.1 现象与初步推断

用户反馈烧录后"上电自己转几秒停止、完全无遥控反应"------与最原始"转 5 秒停止"老程序行为一致,初步怀疑烧录了旧固件。

5.2 程序侧逐字节排查

template.hex 做了逐字节解析验证:

  • ✅ 主函数开头 CLR P1.0(上电电机必停),程序无任何"自转"路径
  • SETB IT0/EX0/PT0 红外中断配置齐全
  • ✅ 六个键值比较指令均在------注意 C51 将 switch 编译为减法树 ,键值 0x16/0x18/0x5E 以差值形式出现,直接按原始字节搜索搜不到是虚惊一场(重要教训)
  • ✅ 与用户在 Keil GUI 中自行编译的 hex 完全一致(cmp 校验)

5.3 发现外部干扰因素

  • 51MCU 目录下存在 11 个同名 template.hex,极易选错
  • STC-ISP 不会自动刷新已加载文件,重编译后必须重新"打开程序文件"
  • 用户曾于 20:21 在 Keil 图形界面自行打开工程编译(template.uvgui.54200 文件为证)

5.4 防呆措施:上电指纹 + 唯一文件名

  • 程序上电先在数码管显示 H 约 1 秒(旧程序无此动作),一眼分辨固件新旧
  • hex 另存为唯一文件名 红外遥控电机_v3指纹H.hex(1756 字节,code=566)

六、第四轮调试:真相大白------空调遥控器连发双键值

6.1 指纹实验的关键结论

用户烧录 v3 后看到了 H 指纹 ,证明烧录链路完全正常!但电机仍"转几秒停止"。由此锁定真正的根因:用户使用的是空调遥控器,而非普中配套遥控器。

6.2 怪现象的完整解释

空调遥控器按一次键会连发多帧数据 ,程序先后解码出 0x15 和 0x07 两个键值

版本 0x15 的映射 0x07 的映射 净效果(按一次键)
v1("好用"版) 升档 降档(从 0 减不动,无效) 净加一档,但封顶不能停
v3("转几秒停止") 降档 升档 先加后减互相抵消,电机一顿一顿回到 0

6.3 v4 单键循环方案

既然遥控器实际就这两个键值,干脆统一映射为同一个动作

  • 0x15 与 0x07 均触发"升一档,最高档后回 0":0停→1低速→2中速→3全速→0停,循环
  • 其余键值忽略(保留 0x16=停止作为保险)
  • 新增 200ms 按键锁存g_lock_ms,由 T0 中断 1ms 分频递减):一次按键产生的连发重复帧直接丢弃,杜绝一次连跳几档
  • 上电指纹改为 P(区分 v3 的 H)

v4 编译 0 错误 0 警告(code=559,20:45),文件名 红外遥控电机_v4_单键循环.hex实测成功:单键 VOL- 即可完成"逐步增速 + 循环回停"全部操作。

七、最终程序结构与操作说明

复制代码
main.c(v4 单键循环版)
├── PWM 生成:T0 100us 中断,100Hz,占空比查表 speed_table[4]={0,30,70,100}
├── 红外解码:INT0(P3.2)+ T0 时基测脉宽,NEC 协议 + 反码校验
├── 按键锁存:200ms 内重复帧丢弃(T0 中断 1ms 分频递减)
├── 档位控制:收到 0x15/0x07 → g_speed_level++(>3 回 0)
├── 数码管:上电显示 P 1 秒 → 显示档位 0~3
└── 上电防御:DC_Motor=0,初始占空比 0%
空调遥控器操作 电机 数码管
上电 停止(先显示 P 一秒) 0
按一次 低速 30% 1
按两次 中速 70% 2
按三次 全速 100% 3
按四次 停止 0

八、调试经验与要点提炼

  1. 硬件资源复用:一个定时器可同时承担 PWM 产生与红外脉宽测量时基,关键在于中断优先级设计(PT0=1)
  2. 中断环境忌软件延时 :脉宽测量应基于定时器时基计数,而非 delay() 函数;多字节共享变量需考虑原子性(u8 单字节读取天然原子)
  3. switch 的编译器优化:C51 将 switch 编译为减法树,立即数以差值形式出现在机器码中------反汇编搜索常量时要留意,勿因搜不到而误判
  4. 固件版本管理 :多个工程同名 hex 是大坑;重编译后 STC-ISP 不会自动刷新;唯一文件名 + 上电指纹是低成本高可靠的防呆组合
  5. 现象指纹法:为不同版本固件设计不同的上电显示(H/P),一次实验即可区分"程序问题"还是"烧录问题"
  6. 非配套遥控器的协议差异:空调遥控器连发多帧、单键多码值,适配时应按实测键值映射,并对重复帧做时间窗锁存
  7. 逐步排除法:本轮调试依次排除了"代码缺失→烧录错误→编译产物过期→遥控器协议差异",每轮一个假设、一个验证手段,最终定位根因
相关推荐
oshan20122 小时前
零基础STM32入门教程--10-PWM 呼吸灯
stm32·单片机·嵌入式硬件
记帖3 小时前
STM32C5A3R开发(7)----ADC电压采集
嵌入式硬件·adc·dac·stm32cubeide·stm32c5·stm32cubemx2·stm32c5a3rgt6
自小吃多5 小时前
器件移动、旋转、镜像、对齐、等间距操作笔记
笔记·嵌入式硬件
jianqiang.xue6 小时前
智能体整体架构设计:四大模块与目录组织
单片机·嵌入式硬件·物联网·架构·esp32
Messy create8 小时前
【BMS-AFE-温度检测】
stm32·单片机·能源
东莞市永盛电气8 小时前
三相208V变380V变压器,出海工业设备供电适配方案
python·单片机·嵌入式硬件
Learn-Share_HY9 小时前
[IT Network]如何配置反向路徑過濾器(rp_filter),以解決路由不對稱問題?
linux·嵌入式硬件·物联网·网络协议·tcp/ip·http·iot
深圳市宝华视联10 小时前
医院内网部署手术示教系统注意事项
嵌入式硬件·实时互动·音视频·实时音视频·视频编解码·嵌入式实时数据库
新晨单片机设计10 小时前
S001A-基于STM32单片机超声波视力保护仪【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus