1. 项目概述:MC68377 BIM的异步芯片选择与32位定时器
在嵌入式系统,尤其是基于经典MCU如Motorola/Freescale 68000家族的设计中,如何高效、可靠地管理外部设备访问和精确的时间控制,是决定系统稳定性和性能的关键。MC68377的突发集成模块(Burst Integration Module, BIM)将这两个核心功能——异步芯片选择(Asynchronous Chip Select, ACS)和系统保护定时器(包含实时时钟RTC与软件看门狗SWDOG)——集成在片内,极大地减少了外部“胶合逻辑”的需求,提升了系统集成度和可靠性。对于硬件工程师和底层驱动开发者而言,深入理解这两个模块的协同工作机制,是进行精准硬件配置和编写高效、稳定固件的基础。
异步芯片选择远不止是简单的地址解码器。它是一个高度可编程的总线接口引擎,能够根据地址、空间类型、读写操作和数据宽度,动态生成具有精确时序的片选信号,甚至能内部产生DTACK信号来终止总线周期,从而无缝对接不同速度、不同接口协议的外部SRAM、Flash、FPGA或专用ASIC。而定时器模块,特别是其32位链式模式,则将看似独立的实时时钟和看门狗定时器融合成一个超长间隔的精密计时器,不仅用于常规的定时中断,更是在低功耗系统设计中,实现从深度睡眠模式(如LPSTOP)中定时唤醒的核心机制。本文将结合手册中的图表和寄存器描述,拆解其设计逻辑、配置要点和实际应用中的“坑”,让你不仅能看懂手册,更能用活这些功能。
2. 异步芯片选择(ACS)模块深度解析
2.1 ACS的核心价值与设计哲学
在传统的68000系统设计中,为每个外部设备生成片选(CS)、输出使能(OE)、写使能(WE)信号,并处理总线应答(DTACK),通常需要额外的PAL或CPLD来实现地址解码和时序逻辑。BIM中的ACS模块将这些功能集成化、可编程化。其设计哲学是以软件配置替代硬件连线,通过一组基地址寄存器(CSBAR)和选项寄存器(CSOR),为最多7个外部设备(CS1-CS7)定义独立的访问窗口和总线行为。
这样做的好处显而易见:灵活性、节省PCB空间与BOM成本、提升时序一致性。例如,你可以用一个ACS通道配置为连接一个慢速的8位EEPROM(需要插入等待状态),另一个通道配置为连接一个快速的16位SRAM(零等待状态),而无需改动任何外部电路,只需在初始化代码中设置不同的寄存器值。
2.2 ACS的工作机制:从地址匹配到信号生成
ACS的工作流程可以概括为“匹配-断言-终止”三步。其内部逻辑框图(手册图3-20)清晰地展示了这一过程。
2.2.1 地址与选项匹配
这是ACS激活的前提。每个ACS通道独立地将当前总线周期信息与自己的编程配置进行比较:
- 地址匹配:比较器将内部地址总线的高位(A[23:16]及以下,具体取决于块大小)与CSBAR寄存器中设定的基地址进行比较。块大小(BLOCK SIZE)字段决定了参与比较的地址线数量。例如,设置为64KB块大小时,只比较A[23:16];设置为1MB时,则比较A[23:20]。这决定了该ACS响应的地址范围。
- 选项匹配:在地址匹配的基础上,进一步比较总线周期的其他属性:
- 读写(R/W):可配置为只匹配读、只匹配写或读写都匹配。
- 空间(SPACE):匹配CPU空间、用户空间、管理空间或所有空间。这对于区分普通内存访问和中断应答(IACK)等特殊周期至关重要。
- 程序/数据(PROG/DATA):在非CPU空间周期中,可进一步区分是程序取指还是数据访问。
- 端口大小(PSIZ):定义外设是8位还是16位,以及对于16位设备,是使能高字节、低字节还是双字节。这直接影响数据总线的连接方式和字节使能信号的生成逻辑。
注意:选项寄存器中的R/W字段如果被设置为“00”(CS禁用),则该ACS通道将完全退出匹配过程,其对应的引脚被驱动为高电平,且无法内部产生DTACK。这是禁用某个ACS通道的正确方法。
2.2.2 芯片选择信号的断言与撤销
一旦匹配成功,对应的ACS引脚将根据选项寄存器中的STRB(选通类型)和DTACK(等待状态)字段被驱动。手册表3-78是理解此时序的关键。
STRB位:决定了CS引脚何时有效。- CE时序:片选信号在总线周期早期(S0/S1状态)即有效,类似于存储器的片使能(Chip Enable)信号,为外设提供更长的地址建立时间。
- DS时序:片选信号与数据选通(DS)信号同步有效,类似于存储器的输出使能(OE)或写使能(WE)信号。
NEGATE EARLY位:这是一个针对慢速总线接口设备的贴心设计。当置位时,CS引脚会在总线周期结束(S5)前一个时钟周期提前无效。这为那些需要较长时间来释放总线(如下一周期地址建立时间要求高)的设备提供了额外的“脱钩”时间,尤其是在写周期后。如果外部DTACK提前终止了周期,此位设置无效,CS仍在S5撤销。
2.2.3 总线周期终止:内部DTACK生成
这是ACS另一个强大功能。当DTACK字段被设置为一个非零的等待状态数值(1-14)时,ACS模块内部的DTACK发生器会在匹配的周期中,在编程的等待状态数耗尽后,内部产生一个DTACK信号来终止总线周期。如果DTACK字段设为0或外部DTACK引脚先于内部DTACK被拉低,则总线周期由外部信号终止。
实操心得:在调试阶段,如果怀疑外部设备响应有问题,可以先将对应ACS的
DTACK字段设置为一个较大的值(如7),并确保NEGATE EARLY位清零。这样,你可以有充足的时间用逻辑分析仪观察总线波形,确认地址、数据、控制信号是否正常,而不会因为外部DTACK未及时响应导致总线错误。
2.3 ACS寄存器配置详解与避坑指南
配置ACS的核心在于正确设置CSBAR和CSOR寄存器。手册中的表3-80和表3-81提供了详细的位描述,但实际配置时需要理解其关联。
2.3.1 基地址寄存器(CSBARx)配置
- 基地址(A[23:16]):这个值必须是所选块大小的整数倍。例如,配置一个起始地址为0x200000、大小为256KB的存储区。256KB对应块大小编码
010,此时比较的地址线是A[23:18]。因此,基地址字段(A[23:16])应设置为0x20。地址0x200000满足A[23:18] =100000(二进制),与0x20(00100000)的高6位001000并不匹配!这里有个关键点:手册中“Base address fields”指的是参与比较的地址位的值,而非完整的起始地址的高字节。对于256KB块,我们比较A[23:18],所以需要将期望的起始地址右移18位(除以256K)后填入。0x200000 >> 18 = 0x8。因此,基地址字段应填0x08。这确保了从0x200000到0x23FFFF的地址范围都能被正确匹配。 - 块大小(BLOCK SIZE):选择时需考虑地址空间的划分是否浪费,以及对于CPU空间访问的特殊要求。若要匹配IACK、LPSTOP或断点应答等CPU空间周期,块大小必须设置为64KB,因为此时需要利用A[19:16]来识别CPU空间类型(见表3-79)。
2.3.2 选项寄存器(CSORx)配置
- 端口大小(PSIZ):这是最容易出错的地方之一。对于8位设备,必须连接在数据总线的高8位(D[15:8]),且PSIZ设置为
00。对于16位设备,若希望无论访问高/低字节都能选中该设备,应设置为11(双字节)。如果需要用两个ACS分别控制���个16位存储体的高8位和低8位(例如由两片8位存储器组成),则需配置两个ACS,PSIZ分别设为10(高字节)和01(低字节),并确保它们的基地址和块大小设置相同。 - 特定中断级别(SIPL):当ACS用于响应IACK周期时,此位决定是否进行中断优先级过滤。每个ACS通道被隐式分配了一个固定的中断级别(CS1对应IPL1,CS7对应IPL7)。如果SIPL=1,则只有当中断优先级编码(A[3:1])与该ACS的固定级别匹配时,ACS才会断言。这允许你用不同的ACS为不同优先级的中断源提供不同的IACK响应时序(例如,高优先级中断需要更快的响应,可以配置更少的等待状态)。
常见问题排查:
- ACS引脚无输出:首先检查端口引脚分配寄存器,确保该引脚功能已设置为ACS,而非通用I/O。其次,确认CSORx中的R/W字段未设置为
00(禁用)。最后,用示波器或逻辑分析仪触发对应的地址访问,观察内部总线信号,确认地址/选项匹配逻辑是否真的被触发。- 总线周期异常终止或出现总线错误:检查
DTACK字段设置。如果设置为内部生成等待状态,但外部设备也试图驱动DTACK,可能会造成冲突。确保外部设备在未被选中时不驱动DTACK。另外,检查多个同时激活的ACS的DTACK和PSIZ设置是否一致,不一致会导致未定义行为。- 字节访问16位设备异常:确认PSIZ设置是否正确。如果你希望访问16位设备的低字节(地址为奇数),但PSIZ设置为
10(仅高字节),则ACS不会断言。对于完整的16位设备访问,应使用11(双字节)。
3. 系统保护定时器:从16位到32位链式模式
3.1 模块构成与基本工作原理
BIM的系统保护子模块主要包含两个16位定时器:实时时钟间隔定时器(RTIT)和软件看门狗间隔定时器(SWIT)。在非链式模式下,它们独立工作:
- RTIT:通常用作通用的周期性中断定时器(如系统滴答时钟)。其时钟源可通过定时器控制寄存器(TIC)选择系统时钟/2或晶振参考时钟/2,并可经过一个可编程的预分频器(分频系数从2^0到2^10)进行分频。定时值写入实时间隔寄存器(RTI),计数器(RTC)递减,减到0时置位RZ标志并可能产生中断,然后自动重载RTI值。
- SWIT:主要用作看门狗,防止软件跑飞。其时钟源固定为系统时钟/2。定时值写入软件看门狗间隔寄存器(SWI),计数器(SWC)递减。如果减到0前未被软件“喂狗”(重新写入SWI),则会根据配置产生复位或中断。
手册中的图3-17展示了RTIT的框图,清晰地显示了时钟选择、预分频器、计数器、比较器和中断逻辑之间的关系。
3.2 32位链式定时器模式精解
当需要超长定时间隔(可达数十天)时,可以将SWIT和RTIT串联,形成一个32位定时器。这是本项目的核心亮点。
3.2.1 链式工作原理
在32位模式下,SWIT作为高16位(MSW),RTIT作为低16位(LSW)。它们协同工作的流程(手册图3-18)如下:
- 初始化:向SWI和RTI寄存器写入一个32位的初始值(可分两次写入16位)。
- 启动计数:当RTI的低字节(或整个16位字)被写入时(如果LCI位为1),链式定时器开始递减计数。RTIT(LSW)使用其配置的时钟(可能带预分频)进行递减。
- 链式递减:当RTIT减到0时,它不会立即重载,而是会触发一个关键操作:将SWIT(MSW)减1,同时RTIT自身翻转到0xFFFF并继续递减。
- 超时判定:只有当SWIT和RTIT都减到0时,才认为整个32位定时器超时。此时,RZ标志被置位。
- 中断与重载:如果定时器中断使能位(TIEN)已设置且中断级别(TIQL)非零,则产生中断请求。随后,SWI和RTI寄存器的值会分别重载到SWIT和RTIT中,循环重新开始。
这种“LSW循环,MSW递减”的机制,等效于一个标准的32位递减计数器。手册中提供的计算公式是理解其定时间隔的基础。
3.2.2 定时间隔计算与预分频器选择
手册表3-77提供了在不同系统频率和预分频器下,32位定时器的超时范围,非常实用。但理解其背后的计算逻辑更重要。
基本公式(无预分频):32位定时器间隔 = (32位SWI/RTI值) × 2 / CLOCK其中,CLOCK是选择的时钟频率(系统时钟或晶振参考频率)。
带预分频的公式:32位定时器间隔 = (32位SWI/RTI值) × 2 / (CLOCK / prescaler)其中,prescaler = 2^n,n为预分频器抽头设置(RTC字段值)。
推导与举例: 假设我们需要一个8小时的定时,系统使用2MHz晶振参考时钟。从表3-77可知,在2MHz下,要达到小时级的定时,必须使用预分频器。我们选择2^4(16分频)。
- 计算所需的总计数周期数(Count):
目标时间 = Count × (预分频系数 / CLOCK) × 28小时 = 8 × 3600 秒 = 28800 秒28800 = Count × (16 / 2e6) × 2Count = 28800 × 2e6 / 32 = 1,800,000,000 - 将Count转换为32位十六进制值:
1,800,000,000 (十进制) = 0x6B49D200 (十六进制) - 寄存器赋值:
- SWI (高16位):0x6B49
- RTI (低16位):0xD200
- 预分频器设置 (TIC寄存器RTC字段):设置为4(对应2^4)。
- 时钟源选择:在TIC寄存器中选择晶振参考时钟/2。
注意事项:
- 写入顺序:由于LCI(低位连接中断)位的存在,向RTI寄存器的写入操作可能会复位预分频器并启动定时器链。因此,通常的编程顺序是:先配置TIC、SYPCR等控制寄存器,再写入SWI(高16位),最后写入RTI(低16位)来启动定时。
- 读取风险:手册明确警告,在32位模式下,通过两次独立的16位读操作来读取当前计数值(SWC和RTC)可能不准确,特别是在LSW即将翻越并递减MSW的时刻,误差最大可达64K。如果必须读取,建议在短时间内连续读取两次,或确保在读取期间定时器中断被禁用。
- 中断级别(TIQL):在32位模式下,中断请求的优先级由SYPCR中的TIQL字段决定。手册特别指出,在此模式下,对IRSEL位的写入将被忽略,中断请求是默认的唤醒/通知机制。
3.3 低功耗停止模式(LPSTOP)下的定时器操作
这是32位定时器一个极其重要的应用场景:作为系统的“闹钟”,将CPU从深度睡眠中唤醒。
3.3.1 进入LPSTOP前的配置
要让32位定时器在LPSTOP模式下正常工作并唤醒系统,必须正确配置以下位:
- SYPCR寄存器:
- SLPC位:必须置1,允许软件看门狗定时器(SWIT,此时作为32位定时器的高位)在LPSTOP期间继续运行。否则,SWIT停止,32位链式定时器失效。
- TIEN位:必须置1,使能定时器中断请求。这是唤醒系统的必要条件。
- TIQL字段:设置一个非零的中断优先级级别(如5)。CPU只有在状态寄存器(SR)中的中断屏蔽级别低于此值时,才能响应该中断。
- PCLK位:选择预分频器的时钟源。如果希望定时精度不受系统时钟关断的影响,应选择晶振参考时钟(通常更稳定)。
- TIC寄存器:配置RTIT的时钟源和预分频器。同样,为了精度,建议选择晶振参考时钟。
3.3.2 唤醒流程
- 系统执行
LPSTOP指令,CPU核心时钟停止,进入低功耗状态。 - 配置好的32位链式定时器(由稳定的晶振时钟驱动)继续递减计数。
- 当定时器超时(SWIT和RTIT均为0),RZ标志置位。
- 由于TIEN=1且TIQL优先级高于CPU当前屏蔽级别,定时器模块向CPU发出中断请求。
- 该中断请求使CPU退出LPSTOP模式,恢复时钟,并跳转到相应的中断服务程序(ISR)。
- 在ISR中,软件可以处理唤醒事件,重新配置定时器,或决定下一步操作(如再次进入LPSTOP)。
实操心得与避坑:
- 时钟源选择:在LPSTOP模式下,系统主时钟可能被关闭。因此,定时器的时钟源务必选择“晶振参考时钟/2”(通过TIC寄存器),而不是“系统时钟/2”。否则定时器将停止工作。
- 中断优先级:确保SYPCR中的TIQL级别高于进入LPSTOP前CPU的屏蔽级别。例如,如果使用
LPSTOP #7指令(屏蔽所有中断级别≤7的中断),则TIQL必须设置为>7的值(8-15),否则中断无法唤醒CPU。但注意,MC68377可能只支持特定范围的优先级,需查阅具体数据手册。- 看门狗功能冲突:在32位链式模式下,SWIT被用作高16位定时器,其原有的独立看门狗功能(超时复位)通常被禁用或需要特别处理。在唤醒后的ISR中,如果需要重新启用独立看门狗,必须重新配置SYPCR等相关寄存器。
- 功耗权衡:虽然RTIT和SWIT在LPSTOP下可以运行,但它们本身也会消耗功耗。在极端追求低功耗的应用中,需要评估这部分功耗是否可接受。有时,使用外部更低功耗的RTC芯片可能是更优选择。
4. 综合应用实例:配置一个带外部RAM和定时唤醒的系统
假设我们要设计一个数据记录仪,它大部分时间处于LPSTOP睡眠状态,每8小时被32位定时器唤醒一次,采集数据并存入外部SRAM,然后继续睡眠。SRAM通过ACS0接口连接。
4.1 硬件连接假设
- MC68377使用2MHz外部晶振。
- 外部SRAM:容量512KB,16位数据宽度,地址范围希望映射到0x100000 - 0x17FFFF。
- ACS0引脚连接到SRAM的片选(/CE)和输出使能(/OE),写使能(/WE)由BIM的另一个信号(如R/W)结合DS生成,或使用另一个ACS引脚。
4.2 ACS0配置(用于SRAM)
- 确定参数:
- 基地址:0x100000
- 块大小:512KB (0x80000)。查表,512KB对应块大小编码
011,比较地址线A[19]。0x100000的A[23:19] =00010(二进制)。基地址字段(A[23:16])应填入这个值右移16位?不对。对于512KB块,我们比较A[19]。我们需要将基地址0x100000右移19位来计算基地址字段值。0x100000 >> 19 = 0x8。所以CSBAR0的A[23:16]字段填0x08,块大小字段填011。 - 端口大小:16位,双字节访问 (
PSIZ=11)。 - 读写:读写均允许 (
R/W=11)。 - 空间:用户/管理空间均可 (
SPACE=11,PROG/DATA=00)。 - 时序:SRAM速度较快,假设零等待状态。设置
STRB为DS时序(以便生成OE),DTACK=0(依赖外部DTACK或由其他ACS内部生成,这里假设SRAM速度匹配,无需插入等待,DTACK由外部电路或BIM其他设置快速产生)。NEGATE EARLY=0。
- 寄存器值估算:
CSBAR0:0x0803(A[23:16]=0x08, 保留位=0, BLOCK=011)CSOR0: 需要根据位域计算。假设STRB选择DS时序(1),DTACK=0,其他位按上述设置。这需要根据表3-81的位域精确计算,此处略过具体数值。假设结果为0xXXYY。
4.3 32位定时器配置(8小时唤醒)
- 计算定时值:如前所述,2MHz晶振,预分频2^4,8小时对应32位值0x6B49D200。
SWI= 0x6B49RTI= 0xD200
- 配置控制寄存器:
- TIC寄存器:选择晶振参考时钟/2作为RTIT时钟源,设置预分频器抽头RTC=4(2^4)。同时,需要设置模式位以使能SWIT作为RTC扩展(即32位模式)。根据手册3.5.6.2节,这通常涉及设置某个特定位(例如,将SWIT配置为RTC扩展而非独立看门狗)。假设向TIC写入
0x0101(这是一个示例,具体位需查手册),其中低8位0x01可能表示预分频器选择等,高8位的0x01可能表示启用32位链式模式或相关配置。 - SYPCR寄存器:这是关键。
- 设置REN位,使得写入RTI时复位预分频器,保证定时起点精确。
- 设置PCLK=1,选择晶振频率驱动预分频器。
- 设置SLPC=1,允许SWIT在LPSTOP下运行。
- 设置TIEN=1,使能定时器中断。
- 设置TIQL=5(或其他合适的中断优先级)。
- 假设其他位(如看门狗使能、监控器设置)保持默认或禁用。根据手册示例,可能的值是
0xB15C,但需根据实际需求调整。
- TIC寄存器:选择晶振参考时钟/2作为RTIT时钟源,设置预分频器抽头RTC=4(2^4)。同时,需要设置模式位以使能SWIT作为RTC扩展(即32位模式)。根据手册3.5.6.2节,这通常涉及设置某个特定位(例如,将SWIT配置为RTC扩展而非独立看门狗)。假设向TIC写入
- 中断服务程序(ISR):
- 在ISR中,首先读取状态(可能包括检查RZ标志)并清除中断源。
- 执行数据采集任务。
- 将采集的数据通过ACS0接口写入外部SRAM。
- 如果需要,重新装载定时器值(SWI/RTI)以启动下一次8小时定时。
- 清除CPU状态寄存器中的中断屏蔽,并执行
RTE返回。如果希望再次进入睡眠,则在主循环中再次调用LPSTOP。
4.4 初始化代码流程概要
; 1. 配置ACS0 MOVE.W #$0803, CSBAR0 ; 设置基地址和块大小 MOVE.W #$XXYY, CSOR0 ; 设置选项寄存器(根据计算出的值) ; 2. 配置32位定时器 MOVE.W #$0101, TIC ; 配置定时器控制,选择时钟源、预分频、32位模式 MOVE.W #$B15C, SYPCR ; 配置系统保护控制,使能LPSTOP下运行、中断等 ; 3. 装载定时器初始值(先高后低) MOVE.W #$6B49, SWI ; 写入高16位 MOVE.W #$D200, RTI ; 写入低16位,启动定时器 ; 4. 设置中断向量和CPU状态 ; ... (将定时器中断服务程序地址填入对应向量表) ANDI.W #$F8FF, SR ; 确保CPU中断屏蔽级别低于TIQL(5),例如设置为4 ; 5. 主循环进入睡眠 main_loop: ; ... 可能的其他任务 LPSTOP #5 ; 进入低功耗停止模式,屏蔽级别≤5的中断 ; 由于TIQL=5,定时器中断(级别5)可以唤醒它 BRA main_loop ; 被唤醒后继续循环4.5 调试技巧
- 使用仿真器或调试器:单步执行初始化代码,观察ACS和定时器相关寄存器的值是否按预期写入。
- 逻辑分析仪:这是验证ACS时序和定时器行为的利器。触发ACS引脚或地址线,查看在访问SRAM区域时,CS、OE、地址、数据、DTACK的波形是否符合数据手册和你的配置(特别是
STRB和NEGATE EARLY的影响)。对于定时器,可以尝试配置一个较短的间隔(如1秒),用中断服务程序翻转一个GPIO引脚,然后用逻辑分析仪测量翻转间隔,验证定时精度。 - 软件模拟:在进入LPSTOP前,可以先将定时器配置为很短的时间(如几毫秒),并让唤醒中断点亮一个LED或发送串口信息。这可以快速验证整个低功耗定时唤醒链路是否通畅。
通过这样详细的拆解和实例,你应该对MC68377 BIM的异步芯片选择和32位定时器有了从原理到实践的全方位理解。这些模块的强大之处在于其高度的可编程性,能够适应各种复杂的外设接口和精准的定时需求,是构建稳健、高效嵌入式系统的基石。在实际项目中,反复查阅数据手册,结合硬件调试工具进行验证,是驾驭这些复杂外设的不二法门。