
1. 项目概述与核心价值如果你正在开发基于MC68SZ328微控制器的嵌入式系统无论是工业控制器、便携式医疗设备还是需要定时唤醒的智能仪表那么实时时钟RTC和脉冲宽度调制PWM这两个外设模块你大概率绕不开。它们一个负责提供系统的时间“心跳”和精准的定时事件另一个则能将数字信号转化为模拟世界的控制量驱动蜂鸣器、电机或是播放音频。手册里密密麻麻的寄存器位描述常常让人望而生畏感觉懂了每个比特的意思但连起来却不知道如何下手。我花了相当长的时间在几个基于MC68SZ328的实际项目里反复调试它的RTC和PWM模块。从最初的“照着手册配寄存器结果死活不工作”到后来能稳定实现毫秒级定时任务和高质量音频播放中间踩过的坑、总结出的配置套路远比手册上那几行冰冷的描述要丰富得多。这篇文章我就把这些实战经验掰开揉碎了讲给你听。我们不止看寄存器每个位是干什么的更要弄明白它们组合起来如何工作在代码里应该按什么顺序配置以及那些手册里没写、但实际调试中一定会遇到的“坑点”。比如为什么RTC闹钟设好了却不触发PWM播放音频时为什么会有杂音看门狗计数器读出来为什么不准这些问题的答案都藏在寄存器操作的细节和时序里。本文的目标读者是已经对MC68SZ328或类似MC68系列微控制器有基本了解正在或即将进行底层驱动开发的工程师、嵌入式爱好者。我会假设你已经搭建好了基本的开发环境编译器、调试器并且对内存映射I/OMMIO的访问方式如通过指针直接操作特定地址有概念。我们将聚焦于这两个模块的编程模型即如何通过配置一系列寄存器让它们按照我们的意图可靠地工作。你会发现一旦理解了其内在逻辑这些配置并非黑盒而是一套清晰、可预测的规则。2. 实时时钟RTC模块深度解析与配置策略MC68SZ328的RTC模块远不止一个简单的“电子表”。它是一个完整的定时事件系统集成了时间保持、多种频率的中断源、可编程闹钟、独立看门狗以及一个实用的倒计时秒表功能。理解它的整体架构是正确配置的前提。2.1 RTC模块的整体架构与时钟源RTC模块的核心是一个基于32.768kHz晶振的时基。这个频率经过内部分频产生1Hz的秒信号驱动一个“时间日期”TOD计数器。这个TOD计数器就是我们通常理解的年、月、日、时、分、秒的源头但手册中主要关注时、分、秒和日的计数。模块的丰富性体现在其中断系统上它不仅可以产生每秒、每分、每时、每日午夜的周期性中断还提供了8个可编程频率的“实时中断”RTI频率从4Hz到512Hz用于需要更高定时精度的任务如软件定时器、数据采样触发。此外独立的闹钟比较器和看门狗定时器分别用于单次或周期性的特定时间点事件以及系统故障监控。所有功能的使能、状态查询和配置都通过一组内存映射的寄存器完成。访问这些寄存器就像操作普通内存地址一样但需要严格注意位操作的原子性和读写时序。一个常见的误区是直接给整个寄存器赋值这可能会意外修改保留位Reserved Bits导致不可预测的行为。正确的做法是使用“读-修改-写”三部曲先读取寄存器当前值到变量用位操作与、或修改目标位再写回寄存器。2.2 核心寄存器详解与配置流程手册提供了寄存器的位定义但缺乏一个“开机上电后第一步做什么第二步做什么”的引导。下面我结合实战梳理出关键寄存器的配置逻辑和注意事项。2.2.1 RTC控制寄存器RTCCTL—— 开启时钟之源地址0xFFFFFB0C。这个寄存器非常简单但至关重要。它只有一个有效位RTCENBit 7。功能此位是RTC模块的总开关。为0时整个RTC模块包括TOD计数器、闹钟、看门狗、所有中断停止工作进入低功耗状态。为1时RTC使能。配置要点上电默认手册指出复位后RTCEN1默认使能。但在实际应用中尤其是从低功耗模式唤醒后显式地检查并设置此位是一个好习惯。操作顺序理论上应先配置好其他寄存器如闹钟时间、中断使能最后再开启RTCEN。但在MC68SZ328中即使RTCEN0大部分配置寄存器也是可写的。稳妥起见我推荐的流程是先禁止RTCEN0再配置最后使能RTCEN1。这可以避免在配置过程中产生意外的中断或计数器动作。配置代码示例C语言#define RTCCTL (*(volatile uint16_t*)0xFFFFFB0C) #define RTCEN_MASK (0x0080) // Bit 7 void RTC_Init(void) { // 1. 确保RTC模块关闭避免配置过程中的干扰 RTCCTL ~RTCEN_MASK; // ... 此处配置其他RTC寄存器闹钟、中断等 // 2. 所有配置完成后启动RTC RTCCTL | RTCEN_MASK; }2.2.2 闹钟寄存器RTCALRM, DAYALRM—— 精准事件触发这是RTC最常用的功能之一。MC68SZ328的闹钟分为两部分RTCALRM(0xFFFFFB04)设置闹钟的时、分、秒。DAYALRM(0xFFFFFB1C)设置闹钟的日0-511可理解为年日或简单日计数。工作逻辑RTC模块持续将当前的TOD时间时、分、秒、日与这两个闹钟寄存器的值进行比较。当所有字段都匹配时即当前时间等于设定的日、时、分、秒就会触发闹钟事件。位域解析RTCALRM[28:24]: HOURS 范围0-23。RTCALRM[21:16]: MINUTES范围0-59。RTCALRM[5:0]: SECONDS 范围0-59。DAYALRM[8:0]: DAYSAL 范围0-511。特别注意这些位域之间和周围有大量的保留位Reserved Bits手册明确要求必须写0。例如RTCALRM的Bit 23-22, 15-6都是保留位。配置流程与坑点写入即生效手册注明“After a write, the current time assumes the new values”。这意味着你写入闹钟寄存器后新的比较值立即生效。如果你在闹钟触发前修改了寄存器新的设定会覆盖旧的。单次与周期闹钟这是一个极易混淆的点。手册在RTCISR寄存器的ALM位描述中提到“The alarm will recur every 24 hours. For a single alarm, clear the interrupt enable in the interrupt service routine.” 这意味着硬件逻辑是周期性的每天都会在设定的时间比较一次。如果你想实现单次闹钟比如30分钟后响一次需要在闹钟中断服务程序ISR中手动关闭闹钟中断使能位RTCIENR.ALM 0。否则明天同一时间它还会再触发。设置示例设置每天下午2点30分15秒触发闹钟。#define RTCALRM (*(volatile uint32_t*)0xFFFFFB04) // 注意32位访问 #define DAYALRM (*(volatile uint16_t*)0xFFFFFB1C) void SetAlarm_Daily(uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) { // 构造RTCALRM值注意保留位清零 uint32_t alarm_val 0; alarm_val | ((uint32_t)(hour 0x1F) 24); // HOURS bit 28-24 alarm_val | ((uint32_t)(min 0x3F) 16); // MINUTES bit 21-16 alarm_val | (sec 0x3F); // SECONDS bit 5-0 // Bit 23-22, 15-6 自动为0 RTCALRM alarm_val; // 设置日闹钟 DAYALRM (day 0x1FF); // DAYSAL bit 8-0 } // 调用SetAlarm_Daily(0, 14, 30, 15); // 日设为0或特定值时14下午2点2.2.3 看门狗定时器寄存器WATCHDOG—— 系统守护者地址0xFFFFFB0A。看门狗是系统可靠性的最后一道防线。MC68SZ328的看门狗相对简单但配置不当会导致系统不断意外复位。关键位EN (Bit 0)看门狗使能。复位后默认为1使能。这是一个非常重要的细节如果你在初始化阶段没有及时喂狗系统可能很快就会被看门狗复位。ISEL (Bit 1)中断选择。0超时触发系统复位默认1超时触发中断。通常我们选择复位模式因为中断模式如果服务程序卡死就失去了看门狗的意义。INTF (Bit 7)中断标志位。超时发生时置1写1清除。CNTR (Bits 9-8)计数器值。这是一个只读的2位计数器由RTC的1Hz信号驱动。当计数到10二进制10时触发超时事件。向这两位写入任何值都会将计数器复位到0。这就是“喂狗”的操作。工作流程与注意事项初始化上电后应尽快决定是否使用看门狗。如果不用第一时间将EN位清零。如果使用则配置ISEL通常为0然后立即进行一次“喂狗”写CNTR。喂狗操作必须在计数器达到10之前定期建议在计数器达到5-8之间向CNTR位写入任意值通常写0以复位计数器。这个“定期”必须在10秒内完成。精度问题手册特别指出由于依赖1Hz信号计数器精度平均为±0.5秒。对于需要更精确喂狗间隔的应用建议轮询RTCISR寄存器的1HZ标志位以此作为精确的1秒基准来安排喂狗而不是依赖粗略的时间估算。调试影响在调试阶段特别是单步执行时代码执行会远慢于看门狗超时时间导致不断复位无法调试。此时可以临时在初始化代码中禁用看门狗EN0待主要功能调试完成后再启用。2.2.4 中断系统寄存器RTCISR, RTCIENR—— 事件响应核心RTC的强大在于其丰富的中断源。管理中断需要两个寄存器配合RTCISR中断状态寄存器0xFFFFFB0E只读严格说是写1清除。当某个事件如1秒到、闹钟响、看门狗超时发生时对应的状态位会被硬件置1。即使该中断未使能状态位也会置1。通过读取该寄存器可以判断事件来源。RTCIENR中断使能寄存器0xFFFFFB10读写。你想让哪个事件触发CPU中断就把对应的使能位置1。这是中断的“开关”。重要中断源ALM (Bit 2): 闹钟中断。当RTCALRM/DAYALRM匹配时置位。1HZ (Bit 4): 1秒中断。每秒触发一次可用于更新软件时钟、任务调度。MIN (Bit 1): 1分钟中断。HR (Bit 5): 1小时中断。DAY (Bit 3): 日中断午夜。SW (Bit 0): 秒表中断。当STPWCH寄存器倒计时结束时触发。INTF (Bit 7, 在WATCHDOG寄存器中): 看门狗中断标志当ISEL1时。RIS[7:0] (Bit 15-8): 8个可编程频率的实时中断RTI频率从4Hz到512Hz由分频器产生用于高精度定时。配置与处理流程初始化在RTCIENR中使能所需的中断源例如使能1HZ和ALM。中断服务程序ISR读取RTCISR判断是哪个事件触发的中断。执行相应的处理逻辑例如更新显示、执行任务。关键一步向RTCISR中已发生事件的位写入1以清除该状态位。这是中断响应的标准操作不清除会导致中断持续触发。对于单次闹钟在ALM中断的ISR中还需清除RTCIENR.ALM位。实时中断RTI频率选择RISx中断的频率由内部固定分频链决定见手册Table 13-9。你需要根据任务周期选择合适频率的中断。例如需要一个约125ms的定时可以启用RIS18Hz。2.3 秒表功能STPWCH—— 简易倒计时器秒表寄存器STPWCH,0xFFFFFB12提供了一个简单的倒计时功能最大62分钟。工作原理向CNT位域Bits 5-0写入一个1-62之间的值代表分钟数。使能秒表中断RTCIENR.SW 1。此后每过一分钟由MIN事件驱动CNT值自动减1。当减到0时触发秒表中断RTCISR.SW置位并且CNT会保持为-1即所有位为10x3F。使用要点倒计时精度约为±0.5分钟。一次倒计时结束后CNT值为0x3F。必须重新写入一个非零且小于63的值才能启动下一次倒计时。直接写入0x3F是无效的。可以轮询RTCISR.MIN位来获得更精确的分钟信号从而手动管理更高精度的长定时。3. 脉冲宽度调制PWM模块详解与应用实战PWM模块是MC68SZ328的另一个亮点尤其是PWM 1其内置的5字节FIFO使其非常适合进行音频播放。PWM 2则是一个更通用的16位PWM适合电机控制、LED调光等。3.1 PWM模块架构与模式解析MC68SZ328有两个独立的PWM模块PWM 18位带FIFO和PWM 216位无FIFO。它们的输出可以独立PWMO2或通过逻辑组合PWMO1引出。三种工作模式播放模式Playback主要用于音频重建。PWM 1的FIFO持续输出存储的音频采样数据每个采样值决定了一个PWM周期内高电平的宽度从而在外部通过低通滤波器后还原出模拟音频波形。音调模式Tone生成固定频率和占空比的方波可用于驱动蜂鸣器发出简单提示音。D/A模式当输出端连接一个合适的低通滤波器时固定的PWM占空比对应一个稳定的直流电压此时PWM相当于一个数模转换器DAC。3.2 PWM 1配置从音频播放到简单音调PWM 1是功能更复杂的一个我们重点剖析。3.2.1 时钟链与采样率计算PWM 1的时钟路径是时钟源SYSCLK或CLK32 - 7位预分频器PRESCALER - 分频器CLKSEL - PCLK。PCLK是驱动PWM计数器的最终时钟。输出频率公式手册Eqn. 14-1PWMO_Freq PCLK / (PERIOD 2)对于音频播放我们更关心采样率Sample Rate。在播放模式下每个PWM周期输出一个采样点。因此PWM的输出频率就是音频的采样率。计算示例假设系统时钟SYSCLK 16.58 MHz我们希望得到16kHz的音频采样率。选择CLKSEL %01 (Divide by 4)。此时PCLK SYSCLK / 4 4.145 MHz。根据公式16000 4145000 / (PERIOD 2)。解得PERIOD (4145000 / 16000) - 2 ≈ 257.125。取整为2570x101。实际采样率F_actual 4145000 / (257 2) ≈ 15992.3 Hz误差很小可接受。**预分频器PRESCALER**用于进一步降低频率通常用于生成极低频率的音调。其分频系数为(PRESCALER 1)。3.2.2 关键寄存器配置步骤配置PWM 1播放音频需要按顺序操作以下几个寄存器PWM 1周期寄存器PWMP1,0xFFFFF504根据上述公式计算并设置PERIOD值决定PWM基础频率即音频采样率。PWM 1控制寄存器PWMC1,0xFFFFF500这是核心控制寄存器。CLKSRC选择SYSCLK默认或CLK3232.768kHz用于极低功耗/低频。PRESCALER通常设为0不分频用于音频。CLKSEL选择主分频比对应目标采样率范围。REPEAT样本重复。这是一个提升音质和降低CPU负载的技巧。例如播放8kHz采样的音频时如果硬件以16kHz运行可以将REPEAT设为01重复一次这样每个样本被播放两次将PWM的载波频率从8kHz提升到16kHz超出人耳敏感范围更容易被简单的低通滤波器滤除从而减少噪音。IRQEN使能FIFO中断。当FIFO快空时剩余1或0字节触发中断让你有机会及时填充新数据。EN最后才置1在配置好所有参数前保持PWM禁用。PWM 1样本寄存器PWMS1,0xFFFFF502这是数据入口。可以写入单个8位样本写入低字节SAMPLE1也可以写入一个16位字高字节SAMPLE0低字节SAMPLE1自动按序压入FIFO。样本值0-255直接决定了PWM脉冲的宽度占空比。FIFO管理策略PWM 1有一个5字节的FIFO。中断标志IRQ在FIFO剩余字节数1时置位。最佳策略是在中断服务程序中一次性写入4个字节两个16位样本或四个8位样本这样效率最高。对于16kHz采样率中断周期是500µs1/16000 * 4对CPU负荷适中。3.2.3 音频播放实战代码框架#define PWMC1 (*(volatile uint16_t*)0xFFFFF500) #define PWMS1 (*(volatile uint16_t*)0xFFFFF502) #define PWMP1 (*(volatile uint8_t*)0xFFFFF504) #define PWMCNT1 (*(volatile uint8_t*)0xFFFFF505) // 假设使用16.58MHz SYSCLK目标16kHz采样率 #define PWM_PERIOD_16KHZ (257) // 计算得出的值 // 音频数据缓冲区 extern const uint8_t audio_data[]; extern uint32_t audio_index, audio_length; void PWM1_Audio_Init(void) { // 1. 禁用PWM PWMC1 ~(1 4); // EN bit 0 // 2. 配置周期采样率 PWMP1 PWM_PERIOD_16KHZ; // 3. 配置控制寄存器SYSCLK源预分频016kHz分频重复1次使能中断 uint16_t ctrl_val 0; ctrl_val | (0 15); // CLKSRC SYSCLK ctrl_val | (0 8); // PRESCALER 0 ctrl_val | (1 6); // IRQEN 1 (使能中断) ctrl_val | (1 2); // REPEAT 01 (重复一次) ctrl_val | (1 0); // CLKSEL 01 (除以4) // 注意先不设置EN位 PWMC1 ctrl_val; // 4. 预填充一些数据到FIFO可选防止一开始就中断 // ... // 5. 最后使能PWM PWMC1 | (1 4); // EN 1 } // PWM 1中断服务程序 void __attribute__((interrupt)) PWM1_IRQ_Handler(void) { // 读取状态清除中断标志读操作自动清除IRQ位 uint16_t status PWMC1; // 检查FIFO是否可用FIFOAV位并填充数据 if ((PWMC1 (1 5)) (audio_index audio_length)) { // FIFOAV1 // 一次性写入4个8位样本两个16位字 // 假设audio_data是8位单声道数据 uint16_t sample_pair1 ((uint16_t)audio_data[audio_index] 8) | audio_data[audio_index1]; uint16_t sample_pair2 ((uint16_t)audio_data[audio_index2] 8) | audio_data[audio_index3]; PWMS1 sample_pair1; PWMS1 sample_pair2; audio_index 4; if(audio_index audio_length) { // 播放完毕可以禁用中断或PWM PWMC1 ~(1 6); // 关闭中断使能 IRQEN0 } } }3.3 PWM 2配置通用PWM信号生成PWM 2更简单是一个标准的16位PWM发生器没有FIFO适合生成固定或缓慢变化的PWM信号。核心公式输出频率F_pwm F_in / ( (CLKSEL_DIV) * (PERIOD 1) )F_in是输入时钟SYSCLK。CLKSEL_DIV是CLKSEL位域选择的分频系数4, 8, 16, ..., 512。PERIOD是PWMP2寄存器的值0-65535。占空比Duty Cycle (WIDTH 1) / (PERIOD 1)WIDTH是PWMW2寄存器的值。当WIDTH PERIOD时占空比为100%常高。当WIDTH 0且PERIOD 0时占空比为1/(PERIOD1)一个很窄的脉冲。特殊警告手册注明当PERIOD 0时输出永远为低占空比0%。配置流程根据所需频率和系统时钟计算并设置PWMC2.CLKSEL和PWMP2。根据所需占空比计算并设置PWMW2。设置PWMC2.POL选择极性正常或反转。重要设置PWMC2.LOAD 1以加载新的周期和脉宽值。此位会自动清除。最后设置PWMC2.PWMEN 1使能PWM输出。示例生成1kHz占空比50%的PWM波SYSCLK16.58MHz选择较大的分频以得到合适的PERIOD值。选CLKSEL110Divide by 256。F_in_div 16.58e6 / 256 ≈ 64765.625 Hz计算PERIODPERIOD (F_in_div / F_pwm) - 1 (64765.625 / 1000) - 1 ≈ 63.765取整64。 实际频率64765.625 / (641) ≈ 996.4 Hz。计算WIDTH50%占空比WIDTH (PERIOD 1) * 0.5 - 1 65*0.5 -1 31.5取整32。 实际占空比(321)/(641) ≈ 50.77%。配置代码#define PWMC2 (*(volatile uint16_t*)0xFFFFF510) #define PWMP2 (*(volatile uint16_t*)0xFFFFF512) #define PWMW2 (*(volatile uint16_t*)0xFFFFF514) void PWM2_Init_1kHz_50Duty(void) { // 1. 禁用PWM2 PWMC2 ~(1 4); // PWMEN 0 // 2. 配置周期和脉宽 PWMP2 64; PWMW2 32; // 3. 配置控制寄存器分频256正常极性 uint16_t ctrl_val 0; ctrl_val | (6 0); // CLKSEL 110 (除以256) ctrl_val | (0 5); // POL 0 (正常极性) PWMC2 ctrl_val; // 4. 加载新配置 PWMC2 | (1 8); // LOAD 1 // 5. 使能PWM2 PWMC2 | (1 4); // PWMEN 1 }4. 常见问题排查与实战经验总结即使按照手册配置在实际项目中依然会遇到各种问题。以下是我总结的几个典型场景和解决方案。4.1 RTC模块常见问题问题RTC闹钟不触发。检查1RTC使能了吗确认RTCCTL.RTCEN 1。检查2中断使能了吗确认RTCIENR.ALM 1并且CPU全局中断已开启。检查3时间设置正确吗确保TOD时钟时、分、秒、日已经正确设置并运行。闹钟是比较当前TOD时间和闹钟寄存器值。检查4中断状态位清除了吗在闹钟ISR中是否对RTCISR.ALM位写了1来清除它未清除会阻止下次触发。检查5寄存器写入顺序建议先写DAYALRM再写RTCALRM。虽然理论上任意顺序但有些硬件对跨寄存器的时间比较有微妙要求。问题看门狗导致系统不断复位。检查1初始化时是否立即喂狗或禁用了复位后看门狗默认是使能的。必须在几秒内进行第一次喂狗操作写WATCHDOG.CNTR。检查2喂狗间隔是否超过10秒看门狗计数器约10秒溢出。确保主循环或定时任务中喂狗间隔远小于10秒。检查3在长时间阻塞的操作中如等待外部响应是否喂狗需要在阻塞循环中加入喂狗操作。问题读取的秒或分钟数跳变不准。原因直接读取正在运行的计数器可能遇到“翻转”问题。例如在23:59:59读取时可能先读了秒和分在读取小时前时间变成了00:00:00导致出一个非法时间23:59:00。解决方案实现一个“两次读取法”或“影子寄存器法”。连续读取两次TOD时间如果两次读取的秒数相同说明没有在读取过程中发生进位则数据有效否则重新读取。4.2 PWM模块常见问题问题PWM 1播放音频有严重杂音或失真。检查1采样率匹配吗确保PWM周期寄存器计算出的频率与你音频数据的原始采样率一致或通过REPEAT功能成倍提升。用错误的采样率播放会导致音调变化和噪声。检查2FIFO下溢了吗如果中断服务程序填充数据不够快FIFO会被读空导致输出波形断裂产生“咔嗒”声。优化ISR代码或使用DMA如果MCU支持来填充数据。检查3低通滤波器设计正确吗PWM输出是数字方波必须经过低通滤波器才能还原为平滑的音频。滤波器的截止频率应略高于音频最高频率如4kHz并远低于PWM载波频率如16kHz。不合适的滤波器会导致高频噪声载波泄漏或音频失真。检查4电源噪声音频电路对电源噪声敏感。确保PWM输出引脚和音频放大器部分的电源有良好的去耦加104、10uF电容。问题PWM 2输出频率或占空比与计算值不符。检查1LOAD位操作了吗修改PWMP2或PWMW2后必须设置PWMC2.LOAD1新值才会生效。这是一个常见的遗漏点。检查2时钟源和分频设置对吗确认PWMC2.CLKSEL设置正确并且你计算时使用的F_inSYSCLK频率是准确的。检查3PERIOD0的特殊情况如果PERIOD设为0输出将恒为低无论WIDTH设为何值。检查4输出引脚配置确认PWMO2引脚已正确配置为外设功能而非GPIO这通常需要通过另一个“引脚功能选择”寄存器来设置。问题PWM输出无信号。检查1PWM模块使能了吗PWMC1.EN或PWMC2.PWMEN必须为1。检查2输出引脚极性检查PWMC2.POL位。如果设为反转1而占空比是100%那么输出将是常低看起来像没信号。检查3外设时钟门控在一些微控制器中外设模块有独立的时钟门控。虽然MC68SZ328手册未明确提及但需确认系统时钟是否确实供给到了PWM模块通常RTC和PWM使用独立时钟域需检查相关控制寄存器。4.3 调试技巧使用示波器这是调试PWM和RTC相关功能最直观的工具。可以直接测量PWMO引脚波形验证频率、占空比是否正确。对于RTC可以测量每秒中断对应的GPIO翻转来验证1Hz中断是否准确。软件仿真在IDE的仿真器中可以单步跟踪寄存器写入的值观察中断标志位的变化这对于理解配置流程和排查逻辑错误非常有效。简化测试先抛开复杂应用如播放整个音频文件用最简代码测试基本功能。例如让PWM 2输出一个1Hz的方波用LED观察或让RTC每秒触发一个中断翻转LED。基础功能通了再叠加复杂逻辑。查阅勘误表Errata老型号的微控制器参考手册可能存在印刷错误或未记录的硬件特性。尝试在网络上搜索“MC68SZ328 Errata”可能会发现一些关键信息。