基于MC68HC11E9的步进电机控制系统:从原理到工程实践
1. 项目概述
如果你正在寻找一个能亲手搭建、并且能深刻理解微控制器如何与物理世界交互的嵌入式项目,那么基于MC68HC11E9的步进电机控制系统绝对是一个经典且富有教义的案例。这不仅仅是让一个电机转起来那么简单,它涉及到了从模拟信号采集、数字逻辑处理、功率驱动到人机交互的完整闭环。我当年在学校实验室里第一次成功让电机按照我的指令精确转动时,那种软硬件协同工作的成就感至今难忘。这个项目非常适合电子、自动化或嵌入式方向的学习者和爱好者,它能让你把书本上的单片机原理、接口技术和汇编语言知识,变成一个看得见摸得着的运动控制系统。核心就是利用MC68HC11E9这颗8位MCU作为大脑,通过编程控制其I/O口输出特定的脉冲序列,再经过驱动电路放大,最终精确地驱动步进电机的转子一步一步地转动。我们将实现速度可调、方向可控、位置可寻的完整功能,过程中你会遇到硬件选型、信号调理、时序控制和抗干扰等实际问题,这正是工程实践的精华所在。
2. 系统核心设计与思路拆解
在动手焊接第一根线之前,我们必须把整个系统的骨架和脉络理清楚。一个典型的步进电机控制系统,其核心任务可以分解为“感知-决策-执行-反馈”四个环节。我们的设计正是围绕这个逻辑展开的。
2.1 控制逻辑与信号流分析
整个系统的核心控制逻辑是一个经典的“轮询-中断”混合架构。主程序在一个无限循环中,持续执行几个关键任务:首先,它通过A/D转换器读取电位器的电压值,这个模拟量决定了我们期望的电机转速。接着,程序将这个电压值转换为一个数字化的“速度代码”,并驱动七段数码管将其显示出来,让操作者有一个直观的视觉反馈。然后,程序会检查方向控制开关的状态,决定下一步电机旋转的方向。最后,它调用电机转动子程序,根据当前设定的速度和方向,生成相应的脉冲序列输出到电机线圈。
但这其中嵌入了一个关键的中断事件:位置校准。系统上电或需要重新定位时,电机需要找到一个绝对的“零点”。我们通过一个红外对管(发射器和接收器)来实现。在电机转动的轮子上安装一个挡片,当挡片穿过红外光束时,接收器的输出状态会发生变化。这个变化被连接到MCU的一个I/O口(本例中是PORTA0)进行检测。一旦检测到光束被遮挡,程序会触发一个标志,并让电机停在一个已知的绝对位置上,同时数码管显示“S”表示停止等待。此时,需要一个外部中断(通过一个按钮触发IRQ)来“告知”系统校准完成,程序才能继续进入正常的受控转动循环。这种“硬件定位+软件中断响应”的模式,确保了定位的精确性和系统的可控性。
2.2 MC68HC11E9的选型与资源分配
为什么选择MC68HC11E9?在它活跃的那个年代,这是一颗功能非常全面的8位微控制器。对于本项目而言,它的几个关键特性被充分利用:
- 丰富的I/O端口:我们需要至少4个I/O口来驱动电机的四相线圈(PORTC[3:0]),7个I/O口来驱动七段数码管(PORTB[6:0]),以及额外的口线用于方向开关、状态LED和红外检测。MC68HC11E9的多个并行I/O口(PORTA, PORTB, PORTC, PORTD, PORTE)完全满足需求,并且部分端口可以灵活配置为输入或输出。
- 内置8路8位A/D转换器:这是实现无级调速的关键。我们使用PORTE0(AN0)作为模拟输入通道,连接一个电位器。MCU内部的高精度A/D转换器将电位器分压得到的0-5V模拟电压,转换为0-255的数字量,省去了外接专用A/D芯片的麻烦和成本。
- 片上EEPROM:对于开发调试和中小批量生产非常友好。我们可以将调试好的控制程序直接烧录进片内EEPROM,形成真正的“单片”解决方案,无需外挂程序存储器。
- 强大的中断系统:我们利用了IRQ外部中断来响应位置校准后的启动命令。MC68HC11的中断向量机制使得中断服务程序的编写和响应非常高效。
资源分配规划表: 为了让思路更清晰,我将MCU的主要硬件资源分配整理如下:
| 外设/功能 | 使用引脚/资源 | 配置与说明 |
|---|---|---|
| 电机线圈驱动 | PORTC0, PORTC1, PORTC2, PORTC3 | 配置为输出,直接或通过驱动芯片输出控制脉冲。 |
| 七段数码管 | PORTB0 ~ PORTB6 | 配置为输出,输出段选码,显示当前速度等级(0-F)。 |
| 方向控制 | PORTD0 | 配置为输入,外接上拉/下拉电阻和拨动开关,高/低电平代表顺时针/逆时针。 |
| 方向指示LED | 由方向控制电路驱动 | 通常使用两个LED,分别由PORTD0的电平通过三极管或反相器驱动。 |
| 速度设定(电位器) | PORTE0 (AN0) | 配置为模拟输入,连接电位器中间抽头。需配置A/D控制寄存器。 |
| 红外位置检测 | PORTA0 | 配置为输入,检测红外接收管的输出电平(数字量)。 |
| 单步/启动控制 | IRQ引脚 | 外接一个常开按钮到地,按下产生下降沿触发IRQ中断。 |
| 电源与参考电压 | V_RH, V_RL | 分别接+5V和GND,为A/D转换提供参考基准。 |
这个分配方案确保了资源不冲突,且程序中对各个端口的初始化配置(数据方向寄存器DDR)必须与之严格对应。
2.3 步进电机工作原理与驱动方式选择
步进电机之所以能“一步一步”地转,核心在于其定子绕组的排布和通电顺序。我们以最常见的四相单极性步进电机为例(这也是原文中很可能使用的类型)。它的定子上有四个绕组(A, B, C, D),转子是永磁体。当按特定顺序给绕组通电时,会产生一个旋转的磁场,吸引转子一步步跟随转动。
驱动方式是硬件设计的重中之重。MC68HC11E9的I/O口拉电流和灌电流能力有限(通常每个引脚几mA到十几mA),而步进电机线圈的工作电流通常在几百mA甚至更高。因此,绝对不能将MCU引脚直接连接电机线圈,必须使用驱动电路。
原文提到了两种驱动方案:
- 专用驱动芯片(ULN2075B):这是最省事、最可靠的选择。ULN2075B内部集成了7个达林顿晶体管阵列,每个通道能提供高达500mA的驱动电流,并且内置了续流二极管,用于吸收电机线圈断电时产生的反向电动势,保护MCU。它本质上是一个高电压、大电流的反相缓冲器。我们将MCU的4个控制信号接至ULN2075B的输入,输出接电机线圈,电机线圈的另一端接电源电压(可以是+5V,也可以是更高的+12V或+24V以获得更大扭矩)。
- 分立元件推挽放大器:这是一种更底层的方案,用一对NPN和PNP三极管组成推挽电路。MCU的低电平信号使NPN导通,输出高电平;高电平信号使PNP导通,输出低电平。这种电路可以提供比ULN2075B更强的驱动能力,但需要额外的8个三极管和更多外围电阻,电路复杂,调试也更麻烦。它适合对驱动电流有极端要求,或作为学习晶体管放大原理的实践。
实操心得:驱动电路的选择对于初学者或希望快速稳定的项目,强烈推荐使用ULN2003A或ULN2803系列驱动芯片。它们比ULN2075B更常见、更便宜,引脚兼容。ULN2003A有7个通道,ULN2803有8个通道。记得一定要在驱动芯片的COM引脚和电机电源之间连接一个续流二极管(芯片内部通常已集成),这是保护电路、防止高压尖峰烧毁器件的生命线。我曾因为省事没接外部二极管,在频繁启停电机时,反向电动势产生的瞬间高压直接打回了MCU的I/O口,导致端口损坏,教训深刻。
3. 硬件电路设计与搭建要点
有了清晰的设计思路,我们就可以着手将原理图转化为实际的电路板了。硬件是软件的基石,一个稳定可靠的硬件平台能避免后续调试中无数匪夷所思的“玄学”问题。
3.1 核心控制与电源模块
首先是为MC68HC11E9及其最小系统搭建一个稳定的工作环境。你需要一个**+5V的稳压电源**,为MCU、逻辑芯片和部分外设供电。如果电机使用高于5V的电压(如+12V),务必确保两套电源的“地”(GND)是共地的。建议使用7805之类的线性稳压芯片,或者更高效的DC-DC模块,但要注意其输出纹波。
MC68HC11E9需要外部时钟,通常接一个8MHz或4MHz的石英晶体到XTAL和EXTAL引脚,并配以两个20pF左右的负载电容。复位电路是必须的,一个简单的RC复位电路(10kΩ电阻和10μF电容到地)加上一个手动复位按钮,就能保证MCU可靠上电和手动重启。别忘了在VDD引脚附近放置一个0.1μF的陶瓷去耦电容,并且尽可能靠近芯片引脚,这是抑制电源噪声、保证MCU稳定运行的关键。
3.2 信号输入与用户接口电路
这部分电路是系统与操作者交互的桥梁。
- 速度设定电路:一个25kΩ的电位器,两端分别接+5V和GND,中间滑动端接MCU的PORTE0(AN0)。旋转电位器,就在PE0上产生0-5V的可调电压。为了稳定,可以在滑动端对地接一个0.1μF的小电容,滤除可能的高频干扰。
- 方向控制与指示电路:使用一个单刀双掷(SPDT)拨动开关。开关的中间触点接PORTD0。开关一侧通过一个10kΩ电阻上拉到+5V,另一侧直接接地。这样,开关拨到一侧时,PD0读到高电平(顺时针);拨到另一侧时,PD0读到低电平(逆时针)。两个LED(例如绿色和黄色)的阳极分别通过限流电阻(如330Ω)接到+5V,阴极分别连接到两个NPN三极管(如2N3904)的集电极。三极管的发射极接地,基极通过一个更大的电阻(如4.7kΩ)分别连接到PD0和经过一个反相器(如74HC04)后的PD0。这样,PD0为高时,绿色LED亮;PD0为低时,黄色LED亮。
- 位置检测电路:需要一个红外发射管和接收管(对射式)。发射管串联一个限流电阻(如220Ω)直接接+5V,使其常亮。接收管(如光电三极管型)的集电极接+5V,发射极通过一个上拉电阻(如10kΩ)接地,并从发射极引出信号线到MCU的PORTA0。当红外光束未被遮挡时,接收管导通,PA0被拉低(接近0V);当挡片遮挡光束时,接收管截止,PA0被上拉电阻拉高(接近5V)。MCU程序通过检测PA0的这个高低电平变化来判断是否到达零点位置。
- 单步/启动按钮:这是一个常开型轻触开关,一端接MCU的IRQ引脚,另一端接地。IRQ引脚内部通常有上拉电阻,或者需要在外部接一个上拉电阻(如10kΩ)到+5V。平时IRQ为高电平,按下按钮时被拉低,产生下降沿触发中断。
3.3 功率驱动与电机接口
这是硬件部分最容易出问题的地方,需要格外小心。
- 使用ULN2003A驱动芯片:将MCU的PORTC0-PORTC3四个引脚分别连接到ULN2003A的1B-4B输入引脚。ULN2003A的1C-4C输出引脚分别连接到步进电机的四个线圈引脚。电机的公共端(COM)连接到一个独立的电机电源(例如+12V)。ULN2003A的COM引脚(第9脚)必须连接到这个+12V电机电源的正极,这是为内部续流二极管提供回路的关键。电机电源的地与MCU的电源地必须连接在一起。
- 电机线圈接线顺序:这是让电机正确转动的关键。步进电机的四根线圈线通常有颜色标识,但不同厂家可能不同。你必须找到电机的数据手册(Datasheet),上面会明确标出线圈的相位关系(A, A’, B, B’)。如果找不到,可以用万用表测量:任意两根线之间的电阻,如果是其他两根线电阻的两倍左右,那么这两根线就是同一相线圈的头和尾(A和A’)。确定好四相后,按照A, B, A’, B’的顺序接到驱动芯片的四个输出上。接线顺序错误会导致电机抖动、无力甚至不转。
- 电源隔离与滤波:电机在启动、停止和换相时会产生很大的电流突变和电磁干扰。强烈建议在电机电源输入端并联一个大容量的电解电容(如1000μF/25V)和一个小容值的陶瓷电容(如0.1μF),以提供瞬时大电流并滤除高频噪声。如果条件允许,在MCU的电源和电机驱动电源之间使用一个DC-DC隔离模块,或者至少用磁珠和电容组成π型滤波,能极大提高MCU系统的稳定性。
注意事项:上电与断电顺序务必遵循“先逻辑,后功率”的原则。上电时,先给MCU和控制电路(+5V)上电,稳定后再接通电机驱动电源(+12V)。断电时顺序相反,先断电机电源,再断逻辑电源。这样可以避免电机电源的冲击通过驱动芯片影响到脆弱的MCU逻辑电平。我曾因为热插拔电机电源,导致瞬间浪涌通过ULN2003的输入输出寄生电容耦合,打坏了MCU的I/O口。
4. 软件程序深度解析与实现
硬件是躯体,软件是灵魂。这份用MC68HC11汇编语言编写的控制程序,虽然代码量不大,但结构清晰,完整地体现了嵌入式实时控制的思想。我们逐模块拆解,理解每一条指令的意图。
4.1 主程序流程与初始化(INIT)
程序从START标签开始,首先跳转到INIT子程序进行系统初始化。这是任何单片机程序的第一步,目的是将MCU置于一个已知的、确定的状态。
INIT LDX #$1000 ; 设置寄存器基地址为$1000 LDAA #$FF ; 将累加器A加载为$FF (所有位为1) STAA PORTCDR,X ; 将$FF写入PORTC的数据方向寄存器(DDRC),配置PORTC[7:0]全部为输出模式,用于驱动电机线圈和序列LED。 LDAA #$00 ; 将累加器A加载为$00 STAA PORTDDR,X ; 将$00写入PORTD的数据方向寄存器(DDRD),配置PORTD[7:0]全部为输入模式,用于读取方向开关状态。 LDAB #5 ; 将累加器B加载为5 STAB TIMER ; 将5存入用户自定义变量TIMER。这个变量用于控制每个步进脉冲的持续时间(每个线圈通电的循环次数),直接影响电机每一步的“力度”和稳定性。 LDAA #10 ; 将累加器A加载为10 (十进制) STAA COUNTER ; 将10存入COUNTER。这个变量用于控制电机转动多少步。原文注释说20步为一圈,但这里初始化为10,可能用于测试或半圈。你可以修改这个值来控制转动角度。 LDAA #$00 STAA PORTA,X ; 将$00写入PORTA的数据寄存器。虽然PORTA默认是输入,但这里写入是为了确保初始状态已知。更重要的是,它配置了PORTA0为输入,准备读取红外信号。 STAA ATEMP5 ; 清零自定义变量ATEMP5(可能用作临时标志) STAA FLGIRQ ; 清零中断标志FLGIRQ。当红外定位触发时,此标志会被置位。 CLI ; 清除中断屏蔽位(I位),允许响应IRQ等可屏蔽中断。 RTS ; 返回主程序关键点解析:
LDX #$1000:MC68HC11的寄存器(如PORTA, PORTB, ADCTL等)在内存中统一编址,地址从$1000开始。设置索引寄存器X为$1000后,后续就可以用STAA PORTA,X这样的变址寻址方式来访问这些寄存器,使代码更简洁。- 数据方向寄存器(DDR):这是配置I/O口输入输出的关键。向DDR的某位写1,对应引脚为输出;写0则为输入。务必在程序开始正确配置。
CLI指令:它清除了条件码寄存器(CCR)中的中断屏蔽位(I位)。只有执行了CLI,MCU才能响应来自IRQ引脚的外部中断请求。如果忘记打开中断,你的单步/启动按钮将毫无作用。
4.2 方向判断与速度采样循环
初始化完成后,程序进入一个名为NEXT的无限循环。这个循环依次调用各个功能子程序,构成了系统的主要工作流。
NEXT JSR DIRECTION ; 调用方向判断子程序 JSR READAD ; 调用A/D转换启动与延时子程序 JSR COMSPD ; 调用速度计算子程序 JSR DISPLAY ; 调用七段数码管显示子程序 JSR ALIGN ; 调用位置对齐检测子程序 JSR TURN ; 调用电机转动控制子程序 BRA NEXT ; 跳回NEXT,形成无限循环DIRECTION子程序:它读取连接了方向开关的PORTD0引脚状态,并将其存储到ATEMP变量中,作为后续TURN子程序选择顺时针或逆时针转动序列的依据。
READAD与COMSPD子程序:这是实现无级调速的核心。
READAD子程序负责配置并启动A/D转换器。它先向OPTION寄存器写入$90,开启A/D转换器电源(ADPU)并插入延时以确保晶振稳定。然后向ADCTL寄存器写入$A0,设置为连续扫描模式(SCAN=1),并选择对通道0(PE0)进行转换。一旦设置好,A/D转换器就会在后台自动、连续地将PE0的模拟电压转换为数字量,结果存入ADR1(结果寄存器1,地址$1031)中。COMSPD子程序则从ADR1中读取转换结果。这个结果范围是0-255($00-$FF)。为了得到0-15($0-$F)的速度等级用于显示和控制延时,程序先对结果取反(COMA),这样电位器旋到最大(电压最高,AD值最大)时,对应的速度等级反而最小(延时最长,速度最慢),符合直觉。然后连续进行4次逻辑右移(LSRA),相当于除以16,最终得到存储在ATEMP2中的0-F的速度代码。
实操心得:A/D转换的稳定与滤波在实际应用中,直接读取一次A/D结果可能会因为电源噪声或信号抖动导致速度显示跳动、电机转速不稳。一个常见的改进是软件滤波。例如,在
COMSPD子程序中,可以连续采样4次或8次,然后取平均值,再将平均值进行移位处理。代码上可以增加一个循环求和再除以次数的过程。虽然MC68HC11的8位除法稍慢,但对于速度控制这种实时性要求不极端的情况,完全可行,能极大提升系统的抗干扰能力和操作平滑度。
4.3 位置对齐(ALIGN)与中断处理
ALIGN子程序是实现绝对位置定位的关键。它不断检查连接红外接收管的PORTA0引脚。
- 如果检测到PA0为高(光束被遮挡,到达零点),且中断标志
FLGIRQ为0(首次到达),则程序会在七段数码管上显示“S”(代码$A4),然后执行WAI(等待中断)指令,使MCU进入低功耗等待状态,程序暂停在此。 - 此时,只有当用户按下连接在IRQ引脚上的按钮,产生一个下降沿触发IRQ中断,MCU才会跳转到中断服务程序
IRQHND。该服务程序非常简单,仅仅是将FLGIRQ标志加1(INC FLGIRQ),然后返回(RTI)。 - 中断返回后,程序从
WAI之后继续执行RTS,返回到主循环。由于此时FLGIRQ已不为0,下次循环再进入ALIGN子程序时,会直接跳过等待部分,进入TURN子程序,电机开始受控转动。
这种设计巧妙地将硬件定位(红外对管)与用户确认(按钮中断)结合起来,确保了每次启动或复位后,电机都能从一个已知的、精确的物理位置开始运动,这对于需要重复定位的应用至关重要。
4.4 电机转动控制(TURN)与脉冲序列生成
TURN子程序是整个系统动作的执行者。它首先检查COUNTER是否为0,如果为0则重置为初始值(如10),控制总的步进数。然后读取之前存储在ATEMP中的方向标志。
核心在于线圈通电序列。步进电机的转动依赖于给定子线圈施加一个循环变化的脉冲序列。对于四相单极电机,常用的有单四拍(A-B-C-D-A...)和双四拍(AB-BC-CD-DA-AB...)等方式。原文程序采用的是单四拍方式,但通过让每个状态保持多个循环(由TIMER变量控制)来实现速度控制。
以顺时针(CW)转动为例,程序依次向PORTC输出以下8个值(对应PC3-PC0,控制D-C-B-A四相):
$01(0001) - A相通电$03(0011) - A、B相通电$02(0010) - B相通电$06(0110) - B、C相通电$04(0100) - C相通电$0C(1100) - C、D相通电$08(1000) - D相通电$09(1001) - D、A相通电
注意,这实际上是单四拍和双四拍的混合(半步进),它输出8个状态,使电机每步旋转0.9度(假设电机为1.8度/步的半步进模式)。每个状态输出后,程序都调用一个DELAY1子程序。DELAY1子程序根据ATEMP2(速度代码)的值,进行相应次数的空循环延时。速度代码值越大,延时循环次数越多,每一步的间隔时间就越长,电机转速就越慢。这就是用软件延时实现调速的原理。
逆时针(CCW)转动的序列就是上述顺序的逆序。程序通过判断ATEMP的值,选择跳转到CW或CCW标签处开始执行相应的序列。
DELAY1子程序的精妙之处:它不仅完成了延时,还在此期间做了一件事:检查红外对管状态(PA0)。如果检测到光束再次被遮挡(即电机转了一圈又回到了零点),它会在七段数码管上显示一个“P”(代码$98),作为“位置”提示。这是一个简单的圈数计数或位置反馈的雏形。在实际应用中,可以扩展此功能,每显示一次“P”就对一个计数器加一,从而实现转动圈数的计量。
5. 系统调试与常见问题排查
即使按照原理图一丝不苟地搭建好硬件,并烧录了看似无误的程序,系统也可能无法正常工作。下面是我在多年项目中总结出的调试步骤和常见问题排查表,能帮你快速定位问题。
5.1 分模块调试法
不要试图让整个系统一次就跑起来。采用“分而治之”的策略:
- 最小系统测试:首先确保MC68HC11E9最小系统(电源、晶振、复位)工作正常。可以编写一个最简单的LED闪烁程序(只涉及一个I/O口),烧录测试。如果LED不闪,检查电源电压、晶振是否起振(用示波器看XTAL引脚)、复位引脚电平是否正确。
- 输入模块测试:
- 电位器:用万用表测量PE0引脚电压,旋转电位器时电压应在0-5V平滑变化。在程序中修改,将A/D转换后的原始值(0-255)直接送到数码管显示,看显示值是否随电位器旋转而线性变化。
- 方向开关:编写程序,读取PD0状态并直接控制两个方向LED,拨动开关看LED指示是否正确切换。
- 红外对管:用程序循环读取PA0状态并送到LED显示。用手遮挡红外光束,观察LED状态是否变化。注意红外接收管可能对环境光敏感,调试时最好在弱光下进行。
- 输出模块测试:
- 数码管:编写一个循环显示0-9、A-F的程序,检查段码是否正确,有无缺划或常亮段。注意数码管是共阳还是共阴,原文电路假设是共阳数码管,段选信号低电平点亮。
- 电机驱动(不带电机):这是关键!先不要接电机。编写一个程序,让PORTC的四位按固定序列输出(如0001, 0010, 0100, 1000循环)。用逻辑分析仪或示波器(甚至四个LED加电阻)观察这四个引脚的波形。你应该看到四路方波脉冲依次出现。同时用万用表测量ULN2003A对应输出引脚对地的电压,当输入为高时(MCU输出5V),ULN2003A输出应该为低(接近0V,因为内部达林顿管导通接地);输入为低时,输出应为高阻态(由于电机电源未接,可能为不确定状态)。确认逻辑无误。
- 带载联调:
- 接上电机:在确认驱动逻辑正确后,断开系统电源,接上步进电机。务必确保电机电源电压和电流在电机和驱动芯片的额定范围内。上电后,电机可能会发出“嗡嗡”声并轻微振动,这是正常的锁定状态。
- 低速测试:将电位器调到低速端(速度代码接近F),运行完整程序。观察电机是否开始缓慢、平稳地转动。用手轻轻捏住转轴,应能感觉到均匀的步进力矩。如果电机只是剧烈振动但不转,99%的问题是线圈接线顺序错误。请立即断电,尝试交换任意两相线圈的接线顺序,再测试。
5.2 常见问题速查与解决方案
下表列出了开发过程中最可能遇到的“坑”及其解决办法:
| 现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 电机完全不转,也无声音 | 1. 电机电源未接通或损坏。 2. 驱动芯片(ULN2003)电源或使能端未接好。 3. MCU程序未运行或I/O口无输出。 | 1. 检查电机电源电压,测量驱动芯片输出端对地电压。 2. 检查ULN2003的COM脚是否接电机电源正极。 3. 用示波器检查MCU的PORTC引脚是否有脉冲序列输出。检查程序是否卡在初始化或某个循环中。 |
| 电机剧烈振动/抖动,但不旋转 | 线圈相序接错(最常见)。 | 立即断电!尝试交换任意两相线圈的接线。通常有6种可能的接法,只有1种是正确的。最好根据电机手册接线。 |
| 电机转动方向与预期相反 | 方向开关逻辑接反,或电机线圈相序虽正确但旋转顺序反了。 | 1. 检查方向开关电路,确认PD0电平与预期一致。 2. 如果不介意,可直接在软件中交换顺时针和逆时针的脉冲序列表。 |
| 电机转速不稳定,时快时慢 | 1. 电源功率不足,电机启动时拉低逻辑电源电压。 2. A/D采样受到干扰,速度值跳动。 3. 软件延时被中断打断。 | 1. 在电机电源端加大滤波电容(如2200μF)。确保逻辑电源与电机电源分离或加强滤波。 2. 在A/D输入引脚(PE0)对地加一个0.1μF电容。在软件中增加A/D采样值的软件滤波(取平均)。 3. 检查是否有未预料的中断发生。在关键的延时循环中,可以暂时禁用中断( SEI)。 |
| 红外定位不准或失效 | 1. 红外对管未对准,或挡片太窄/太宽。 2. 环境光干扰(特别是日光灯)。 3. 上拉电阻阻值不当,信号边沿不陡峭。 | 1. 精细调整对管和挡片的相对位置,确保挡片能完全遮挡光束。可用示波器观察PA0信号。 2. 为红外接收管加装遮光罩,或使用调制型红外对管(发射管用一定频率驱动,接收管只解调该频率)。 3. 尝试减小上拉电阻(如从10kΩ改为4.7kΩ),提高响应速度。在PA0对地加一个小电容(如10nF)滤除毛刺。 |
| 数码管显示乱码或不亮 | 1. 段码数据错误(共阳/共阴弄反)。 2. 限流电阻过大或过小。 3. PORTB未正确配置为输出。 | 1. 确认数码管类型。共阳数码管,段选低电平点亮;共阴则高电平点亮。修改COMPDIS子程序中的段码表。2. 典型限流电阻为330Ω。测量数码管引脚电压。 3. 检查初始化中是否将PORTB的DDR配置为输出( LDAA #$FF;STAA PORTBDDR,X,注意原文程序未显示此步骤,可能需要添加)。 |
| 按下单步按钮无反应 | 1. IRQ中断未开启(CLI指令未执行)。2. 按钮电路接错,或IRQ引脚内部/外部上拉失效。 3. 中断向量地址设置错误。 | 1. 检查INIT子程序中是否有CLI指令。2. 用万用表测量按钮未按下时IRQ引脚电压是否为高(约5V),按下时是否为低(0V)。 3. 确认程序末尾中断向量 ORG $FFF2处是否正确指向了中断服务程序IRQHND的地址。在仿真器中单步调试,按下按钮看PC是否跳转到IRQHND。 |
调试是一个需要耐心和逻辑分析的过程。善用万用表测量电压,用示波器或逻辑分析仪观察关键信号波形,能让你从“猜”变成“看”,效率倍增。最后,别忘了软件里的那些延时常数(TIMER初始值,DELAY1中的循环基数),它们直接决定了电机的起步速度和最大速度,需要根据你的具体电机和机械负载进行反复调整,才能达到既平稳又有力的效果。
