MC68336总线操作解析:从握手协议到动态总线调整与调试
2026/6/19 0:59:54 网站建设 项目流程

1. 总线操作基础:从握手到完成

在嵌入式微控制器世界里,CPU与外部世界的对话,几乎全部依赖于总线。你可以把它想象成一条繁忙的多车道高速公路,地址是目的地门牌号,数据是运送的货物,而控制信号就是交通信号灯和交警手势。MC68336/376的系统集成模块(SIM)作为这条“高速公路”的交通枢纽,其总线操作逻辑是理解整个芯片如何与外部存储器、外设协同工作的基石。

一个完整的总线周期,本质上是CPU发起一次“对话请求”到“对话结束”的全过程。这个过程并非一蹴而就,而是由一系列精心编排的信号按严格时序共同完成的。对于MC68336,一个最基本的、无等待状态的外部总线周期通常需要三个系统时钟周期。整个过程始于CPU将目标地址放到地址总线ADDR[23:0]上,同时通过功能码FC[2:0]声明这次访问属于哪个“辖区”(用户程序、用户数据、监控程序等)。紧接着,地址选通信号AS被拉低,这就像交警举起手,告诉所有外部设备:“注意,现在我要访问这个地址了!”

随后,读写信号R/W和大小信号SIZ[1:0]也变为有效状态。R/W的高低电平决定了数据流的方向——是从CPU流出(写)还是流入CPU(读)。SIZ信号则告诉外部设备,这次要传输的数据还剩多少字节(1字节、2字节、3字节或4字节)。在写周期中,数据选通信号DS会在AS有效后的一个完整时钟周期被置低,此时CPU已经把要写的数据放到了数据总线DATA[15:0]上。而在读周期,DS的置低则意味着CPU在告诉外部设备:“请把数据放到总线上,我准备接收了。”

整个周期的终结,依赖于外部设备(或内部片选逻辑)的“回应”。这个回应的核心就是数据与大小应答信号DSACK[1:0]。外部设备通过驱动这对信号的不同组合,来告知CPU两件事:第一,我的数据端口宽度是8位还是16位;第二,数据传输已经完成(对于读)或数据已被成功接收(对于写),本次总线周期可以结束了。如果DSACK迟迟不来,CPU就会在时钟周期内插入等待状态,直到收到应答或超时。这套“请求-应答”的握手协议,是确保不同速度设备都能与CPU可靠通信的关键。

注意:AS、DS、R/W、SIZ等控制信号的有效期都与AS信号同步。这意味着,一旦AS被置高(无效),这些信号就可能发生变化。在设计外部逻辑电路时,必须确保在AS有效期间锁存这些信号,否则会导致寻址或控制错误。

2. 核心控制信号深度解析

总线上的每一个信号都肩负着特定使命,理解它们的状态、时序和交互,是进行硬件设计和调试的前提。下面我们来逐一拆解这些关键角色。

2.1 地址与数据选通:AS与DS

AS和DS是总线周期同步的“节拍器”。AS的下降沿标志着一个总线周期的开始,所有地址、功能码、大小信号在此刻必须已经稳定有效。它的有效(低电平)期间,定义了地址信息的有效期。DS信号则专门用于管理数据总线上的活动。

读周期,CPU在置低DS的同时,也释放了对数据总线的驱动(变为高阻态),为外部设备输出数据腾出总线。外部设备需要在DS有效后,在规定的建立时间(setup time)内将有效数据放到总线上,并同时置低相应的DSACK信号。CPU会在随后的时钟下降沿锁存数据总线上的值。

写周期,CPU会先驱动数据到总线上,然后在AS有效后的下一个周期置低DS。DS的置低意味着数据已经稳定,外部设备可以安全地锁存这些数据。外部设备在成功锁存数据后,同样需要通过DSACK来回应。

两者在时序上的配合至关重要。手册中明确指出,DS的置低发生在AS置低后的一个完整时钟周期。这个设计给了地址解码逻辑额外的时间来准备,确保了在数据相位开始前,目标设备已经被准确选中。

2.2 数据端口宽度协商:DSACK[1:0]与动态总线调整

这是MC68336总线设计中最精妙的部分之一——动态总线调整。CPU并不预设外部设备是8位还是16位,而是在每个总线周期开始时,“假设”对方是16位端口。真正的端口宽度,由外部设备在周期中通过DSACK[1:0]信号实时告知。

DSACK信号的编码规则非常清晰:

  • DSACK1=1, DSACK0=1:插入等待状态。CPU会持续等待,直到这对信号的状态发生变化。这用于连接慢速设备。
  • DSACK1=1, DSACK0=0:结束周期,端口为8位。
  • DSACK1=0, DSACK0=1:结束周期,端口为16位。
  • DSACK1=0, DSACK0=0:保留,不应使用。

动态总线调整带来了巨大的灵活性,但也引入了约束。为了高效地进行多字节传输(如读取一个32位长字),MCU要求不同位宽的设备必须固定在数据总线的特定位置:

  • 16位端口:必须连接在数据总线的高16位(DATA[15:0])。这样,CPU在一个周期内就能读写完整的16位数据。
  • 8位端口:必须连接在数据总线的高8位(DATA[15:8])。这是为了在传输非对齐的字节数据时,能通过内部数据多路复用器将数据正确地路由到目标寄存器。

假设CPU需要从一个8位端口的存储器读取一个32位(4字节)操作数。由于端口每次只能提供1字节,CPU需要发起4次独立的读总线周期。它会根据地址和SIZ信号,依次读取OP0, OP1, OP2, OP3这四个字节(操作数字节顺序见图5-9)。而如果是从16位端口读取同一个32位操作数,则只需要2个总线周期:第一个周期读取高16位(OP0和OP1),第二个周期读取低16位(OP2和OP3)。这一切拆分与重组,都由CPU内部的EBI(外部总线接口)数据多路复用器自动完成,对程序员透明。

2.3 异常与调试信号:BERR与HALT

不是所有总线周期都会一帆风顺。当访问了不存在的地址、外设故障或需要调试时,BERR和HALT信号就登场了。

BERR是总线错误信号。当外部逻辑(或使能后的SIM内部总线监控器)检测到当前总线周期无法被正常终止(例如,在超时后仍未收到任何DSACK或AVEC响应)时,就会置低BERR。CPU在周期结束时采样到BERR有效而HALT无效,就会触发总线错误异常。异常处理程序会接管,通常用于报告系统错误或进行恢复。这里有个关键细节:总线错误异常的处理可能会被延迟。因为CPU的流水线可能已经预取了后续指令,BERR的最终处理要等到受影响的指令执行边界。这在进行精确的故障调试时需要特别注意。

HALT是暂停信号,主要用于硬件调试。当外部调试器置低HALT时,CPU会在完成当前外部总线周期后暂停。此时,数据总线变为高阻态,AS、DS等控制信号变为无效,但地址、功能码、R/W和SIZ信号会保持住当前状态,就像给系统拍了一张“快照”。调试器可以借此检查地址总线和相关状态。当HALT被释放后,CPU会从暂停点继续执行。HALT只影响外部总线周期,如果程序完全在内部存储器和模块中运行,CPU不会停止,这为调试带来了灵活性。

更复杂的情况是BERR和HALT同时有效,这表示一个“重试”终止。CPU会中止当前出错的总线周期,并在HALT信号释放后,重新发起一次相同的总线周期。这在处理某些短暂的、可恢复的总线错误(如仲裁冲突后的重试)时非常有用。

2.4 功能码与CPU空间:FC[2:0]的深层含义

功能码FC[2:0]常被初学者忽略,但它实际上是地址空间的“扩展”。它标识了当前总线周期访问的地址空间类型,这对于构建具有内存保护功能的系统至关重要。

FC2FC1FC0地址空间说明
000保留
001用户数据空间用户模式下的数据访问。
010用户程序空间用户模式下的指令取指。
011保留
100保留
101监控者数据空间监控者(特权)模式下的数据访问。
110监控者程序空间监控者模式下的指令取指。
111CPU空间用于特殊控制功能,如中断响应、断点、低功耗广播,而非普通内存读写。

CPU空间(FC=111)是一个特殊的存在。当访问CPU空间时,地址总线的高位ADDR[19:16]被编码为“类型字段”,用于区分不同的特殊周期:

  • 类型$0:断点响应周期。由BKPT指令或BKPT引脚触发,用于软件/硬件调试。
  • 类型$3:低功耗停止广播周期。执行LPSTOP指令时产生,通知系统即将进入低功耗模式。
  • 类型$F:中断响应周期。响应外部中断请求时,用于获取中断向量号。

外部硬件可以解码FC和地址线,来识别这些特殊周期并做出相应反应,例如在中断响应周期将向量号放到数据总线上。

3. 各类总线周期的实操流程与信号交互

理解了单个信号后,我们需要把它们放到完整的时序流中去看。不同类型的总线周期,信号舞步各不相同。

3.1 常规读写周期:标准的三拍华尔兹

一个无等待状态的常规读周期,是理解总线交互的最佳范例。我们以一个从16位端口读取一个字(Word)的操作数为例,结合流程图(图5-10)来分解其步骤:

  1. S0状态(启动):CPU驱动地址到ADDR[23:0],设置R/W为高(读),根据操作数大小驱动SIZ[1:0](对于字操作,SIZ=1,0),并驱动FC[2:0]表明访问空间。此时AS、DS尚未有效。
  2. S1状态(地址选通):CPU置低AS,标志着地址等信息已稳定,外部设备可以开始解码。对于读周期,DS也在此状态被置低,CPU释放数据总线。
  3. S2状态(数据准备):外部设备解码地址和R/W信号,将请求的数据放到数据总线DATA[15:0]上(对于8位端口,则放到DATA[15:8]),并驱动DSACK[1:0]信号(对于16位端口,驱动为0,1)来回应。
  4. S3状态(应答解码):CPU在S2结束(S3开始)的时钟下降沿采样DSACK信号。如果检测到有效的DSACK(非1,1),则知道数据已就绪且端口宽度。
  5. S4状态(数据锁存):CPU在S4开始的时钟下降沿锁存数据总线上的值。这是数据被真正读入CPU的时刻。
  6. S5状态(周期结束):CPU置高AS和DS,结束当前周期。外部设备撤除数据和DSACK信号。系统进入下一个总线周期的S0状态。

写周期的流程类似,但数据流方向相反。关键区别在于:CPU在S2状态将数据驱动到总线上,然后在S3状态置低DS(对于常规周期)。外部设备在DS有效期间锁存数据,然后发出DSACK应答。

3.2 快速终止周期:芯片选择带来的加速

常规周期至少需要3个时钟,这对于访问高速存储器(如SRAM)来说仍有优化空间。SIM的片选逻辑提供了“快速终止”选项,可以将外部总线访问缩短到2个周期。

其核心原理是:由片选逻辑内部生成DSACK应答信号,而不是等待外部设备驱动。当访问的地址落在某个配置为快速终止的片选区域时,SIM模块会在预定的、更早的时钟边沿(例如S4的下降沿)内部产生DSACK信号,从而提前结束周期。这省去了外部DSACK信号的传播和建立时间。

要使用快速终止,必须满足几个条件:

  1. 被访问的外部设备必须足够快,能在更短的时间窗口内提供稳定数据(读)或锁存数据(写)。
  2. 对应的片选选项寄存器中的DSACK字段必须编程为快速终止编码(%1110)。
  3. 对于快速终止写周期,片选选项寄存器中的STRB字段必须编程为地址选通编码,以确保片选信号在写周期也能被正确置位。

实操心得:在硬件设计初期就规划好内存映射。将需要高速访问的器件(如程序存储器、数据RAM)分配到支持快速终止的片选区域,能显著提升系统性能。但要注意,如果多个片选同时匹配一个设备,且它们的MODE、STRB和DSACK配置不一致,可能会在内部总线上产生冲突。务必确保所有匹配的片选配置完全一致。

3.3 异常控制周期:当总线出错时

总线周期并非总能被DSACK正常终止。表5-13详细列出了DSACK、BERR、HALT信号不同组合下的终止结果。理解这些情况对设计可靠的系统和调试硬件问题至关重要。

  • Case 1 (正常终止):只有DSACK被响应。总线周期顺利完成。
  • Case 2 (暂停终止):HALT与DSACK同时或更早被响应。周期正常结束,但CPU随后进入暂停状态,直到HALT释放。用于单步调试。
  • Case 3 & 4 (总线错误终止):BERR被响应(无论DSACK是否存在)。周期被强制终止,CPU将触发总线错误异常。Case 3是BERR替代了DSACK,Case 4是BERR在DSACK之后到来(例如,设备先应答后报告错误)。
  • Case 5 & 6 (重试终止):BERR和HALT同时被响应。周期终止,但CPU不会立即处理异常,而是等待HALT释放后,重新执行这个出错的总线周期。这对于处理由短暂冲突(如总线仲裁)引起的错误非常有用。

这里有一个极其重要的警告:如果DSACK或BERR信号在下一个总线周期的S2状态仍然保持有效(即没有及时撤销),可能会导致下一个周期被意外提前终止。在设计外部逻辑时,必须确保这些应答信号在AS无效后的适当时间内撤销,通常是在下一个时钟上升沿之前。

4. 总线操作中的高级主题与问题排查

掌握了基本周期后,一些高级机制和常见“坑点”需要特别关注。

4.1 操作数对齐与未对齐访问

CPU32内核的基本操作数大小是16位。所谓“对齐”,指的是一个操作数的起始地址是否能被其大小整除。具体来说:

  • 字节操作数:在任何地址都是对齐的。
  • 字操作数:在偶地址(ADDR0=0)是对齐的,在奇地址(ADDR0=1)是未对齐的。
  • 长字操作数:在能被4整除的地址(ADDR0=0且ADDR1=0)是对齐的,否则是未对齐的。

MC68336/376的CPU32内核不支持未对齐的传输。这意味着,如果你试图从一个奇地址读取一个字,或者从一个非4字节对齐的地址读取一个长字,指令本身会引发异常。这是与一些现代处理器(如ARM Cortex-M)的重要区别。当CPU需要传输一个长字到16位端口时,即使地址是对齐的,它也会自动拆分成两个对齐的字传输(先高字,后低字)。这种拆分对程序员是透明的,但会影响性能,因为需要两个总线周期。

4.2 同步于CLKOUT的异步接口

MC68336的总线被归类为“异步”,因为它使用DSACK这样的握手信号,而不依赖统一的时钟边沿来锁存数据。然而,这一切又是相对于内部系统时钟输出CLKOUT来计量的。为了与同步于CLKOUT的外部逻辑协同工作,手册规定了异步输入(如DSACK、BERR)的建立时间和保持时间。

简单来说,外部逻辑必须确保其应答信号在CLKOUT的特定边沿(通常是S2的下降沿)之前满足建立时间要求,并在该边沿之后满足保持时间要求。这样,MCU才能可靠地在那个时钟边沿采样到正确的信号状态。如果系统完全由CLKOUT同步,且满足这些时序要求,那么总线周期就能以最小的3个时钟周期运行。

4.3 常见问题与硬件调试技巧实录

在实际硬件调试中,总线问题是最常见也最令人头疼的。以下是一些典型问题及排查思路:

问题1:系统上电后“跑飞”,无法执行最简单的程序。

  • 排查思路
    1. 检查基本信号:用示波器或逻辑分析仪首先查看CLKOUT是否有稳定时钟,复位信号是否正常。
    2. 追踪第一个取指周期:复位后,CPU会从特定地址(通常是0x000000)取指。触发捕捉第一个总线周期。
      • 看AS/DS:是否有规律的周期性的选通脉冲?如果没有,可能是CPU未启动或时钟问题。
      • 看地址线:第一个周期的地址是否是预期的复位向量地址?地址线波形是否清晰无毛刺?
      • 看数据线:在读周期,数据总线上是否有外部存储器送出的数据?数据值是否稳定?
      • 看DSACK:外部存储器(如Flash)是否给出了正确的DSACK应答?如果DSACK一直为高,CPU会无限插入等待状态,最终触发内部总线监控器的BERR。
    3. 检查片选和译码:确保外部存储器的片选信号(可能由SIM片选逻辑或外部CPLD产生)在地址有效期间被正确激活。

问题2:访问某个特定外设时数据错误,但访问内存正常。

  • 排查思路
    1. 确认端口宽度:该外设是8位还是16位?其数据线是否按规则连接到了DATA[15:8]或DATA[15:0]?连接错误是导致数据错位的最常见原因。
    2. 检查DSACK生成:该外设或其译码逻辑是否正确生成了DSACK信号?对于8位设备,应该是DSACK[1:0] = 1,0;对于16位设备,是0,1。用逻辑分析仪确认时序。
    3. 检查读写时序:对比示波器波形与数据手册中的时序图。特别关注数据建立时间(Data Setup Time)和数据保持时间(Data Hold Time)是否满足外设要求。在写周期,数据必须在DS有效前稳定;在读周期,数据必须在CPU锁存前稳定。
    4. 检查未对齐访问:确认软件没有对该外设的寄存器进行未对齐的字或长字访问。尝试改用字节访问测试。

问题3:系统间歇性出现总线错误异常。

  • 排查思路
    1. 启用内部总线监控器:检查SIM的系统保护控制寄存器(SYPCR),确保总线监控超时(BMT)功能已启用,并设置一个合理的超时周期(如64个时钟周期)。当DSACK长时间无响应时,监控器会内部产生BERR,这能帮你定位是哪个访问超时。
    2. 检查电源和地:间歇性故障常与电源完整性有关。测量芯片电源引脚处的电压纹波,确保在CPU高频操作时电压跌落不会太大。
    3. 检查总线负载和布线:过长的、负载过重的总线可能导致信号边沿变缓,违反建立/保持时间。检查PCB布线,确保关键控制信号(AS, DS, R/W)走线短且干净,必要时串联端接电阻。
    4. 检查仲裁:如果系统中有其他总线主设备(如DMA控制器),检查总线仲裁逻辑。在仲裁期间或主设备切换时,如果当前主设备(MCU)的总线周期被不适当地终止,也可能引发错误。

问题4:使用HALT进行单步调试时,系统行为异常。

  • 排查思路
    1. 理解HALT的局限性:HALT只停止外部总线周期。如果程序正在内部RAM或片上外设中运行,CPU不会停止。确保你单步的代码段确实涉及外部总线访问。
    2. 检查HALT信号质量:确保调试器驱动的HALT信号干净,无毛刺,并且满足MCU输入信号的电气要求。
    3. 注意总线保持状态:当CPU因HALT暂停时,地址、FC、R/W、SIZ信号会保持,但数据总线为高阻态。确保外部设备不会因为总线上出现浮空状态而动作异常,可以考虑为数据总线增加上拉电阻。

调试总线问题,一台好的逻辑分析仪是必不可少的。你需要设置触发条件(如AS下降沿 + 特定地址),同时捕获地址、数据、控制信号和DSACK/BERR/HALT,然后对照数据手册的时序图逐个状态进行分析。从最简单的读写操作开始验证,逐步增加复杂性,是解决复杂总线问题的有效方法。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询