1. 项目概述:从手册到实践,拆解MSCAN的硬件过滤机制
如果你在汽车电子或者工业控制领域搞过嵌入式开发,那对CAN总线肯定不陌生。这玩意儿就像设备之间的“神经”,负责传递各种控制指令和状态信息。但一个CAN网络上节点那么多,消息满天飞,你的MCU要是每一条消息都去处理,CPU早就被中断淹没了,啥正经活也干不了。所以,一个核心的、由硬件完成的“守门员”角色就至关重要了——这就是标识符过滤。
我手头这份飞思卡尔(现恩智浦)56F80x系列MCU的MSCAN模块参考手册,详细描述了这套过滤机制的寄存器级实现。光看手册寄存器描述,很容易头大:IDAR、IDMR、IDHIT、BOHOLD……一堆缩写和位域。但说白了,它的核心价值就两点:第一,极大减轻CPU负担,让CPU只处理它真正关心的消息;第二,提升系统的实时性和确定性。想象一下,在汽车里,你的车窗控制模块只需要接收“升降车窗”相关的指令,而不需要去处理发动机转速或者ABS状态信息。硬件过滤就是帮你实现这个“选择性接收”的利器。
这篇文章,我就结合手册内容和我自己调这类控制器的经验,把MSCAN的标识符过滤和关键寄存器配置掰开揉碎了讲清楚。我们不止看寄存器每个位是干嘛的,更要弄明白为什么这么设计,以及在实际项目中怎么配、会踩哪些坑。无论你是刚开始接触CAN,还是想深入理解控制器底层机制,这篇文章都能给你提供可直接参考的实操指南。
2. MSCAN过滤机制核心思路拆解
2.1 硬件过滤的本质:比特级的“连连看”
MSCAN的硬件过滤,本质上是一个并行的、比特级的模式匹配器。它不依赖CPU进行软件判断,而是在消息从总线进入接收FIFO的“后台缓冲区”时,由硬件自动完成匹配检查。这个过程可以类比为邮局的分拣系统:每个邮箱(你的应用)有一个特定的邮政编码模板(IDAR,接受码),并且可以指定邮政编码的哪几位必须严格匹配,哪几位无所谓(IDMR,掩码)。只有邮编完全符合要求的信件,才会被投递到你的邮箱(触发CPU中断或置位标志位);不符合的,直接当作废信件处理(丢弃),你根本不知道它来过。
为什么必须是硬件实现?因为CAN总线速率动辄500Kbps甚至1Mbps,一个标准数据帧最短44个比特位,在1Mbps下传输只需44微秒。如果靠软件来解析标识符并决定是否接收,时间上根本来不及,会错过大量消息,更别提处理高优先级消息的实时性了。硬件过滤通常在几个比特时间内就能完成判断,是保证CAN网络效率的基石。
2.2 MSCAN的过滤器架构:两组银行,灵活配置
根据手册,MSCAN提供了多达8个独立的过滤器(Filter 0-7)。这8个过滤器在物理上分为两个“银行”(Bank):
- 第一银行(Bank 1):包含过滤器0-3,对应寄存器IDAR0-IDAR3(接受码)和IDMR0-IDMR3(掩码)。
- 第二银行(Bank 2):包含过滤器4-7,对应寄存器IDAR4-IDAR7和IDMR4-IDMR7。
这种分组有什么深意?它通常与两种过滤模式挂钩:
- 32位过滤模式:用于处理扩展帧(29位ID)。在此模式下,一个扩展帧标识符需要4个字节(32位)来存储。因此,一个完整的扩展帧过滤器需要消耗一组连续的4个过滤器。例如,你可以将过滤器0-3配置为一组,共同匹配一个29位的扩展ID模式。同理,过滤器4-7可以配置为另一组,匹配另一个扩展ID。
- 16位过滤模式:用于处理标准帧(11位ID)。一个标准帧标识符只需要2个字节(16位)来存储。因此,一个标准帧过滤器只消耗2个过滤器。例如,过滤器0和1可以配成一对,过滤器2和3配成另一对,这样第一银行就能提供2个独立的标准帧过滤规则。第二银行同理。
手册里提到:“For extended identifiers, all four acceptance and mask registers are applied. For standard identifiers, only the first two (IDAR0/1, IDMR0/1) are applied.” 这句话点明了关键:对于扩展帧,硬件会使用连续的4个接受/掩码寄存器(如IDAR0-3)进行匹配;对于标准帧,则只使用前两个(如IDAR0-1)。你在配置时,必须根据帧格式,正确设置对应数量的寄存器。
实操心得:模式选择与规划在项目初期规划CAN通信矩阵时,就要统计本节点需要接收哪些ID的消息,是标准帧多还是扩展帧多。如果扩展帧多,就要谨慎分配过滤器组,因为一个扩展帧会“占用”4个过滤器资源。如果标准帧多,资源就相对宽裕。一个常见的策略是,将需要最高实时性、最精确匹配的消息(如关键控制指令)放在靠前的过滤器(如Filter 0),因为硬件可能会按顺序检查。
3. 核心寄存器详解与配置实战
手册给出了寄存器位域图,我们结合实战来理解。
3.1 标识符接受寄存器(IDAR0-7)与掩码寄存器(IDMR0-7)
这是过滤器的核心。手册定义:
- IDAR (Identifier Acceptance Register):用户定义的接受码序列。你可以把它理解为“期望的ID模板”。
- IDMR (Identifier Mask Register):掩码寄存器,指定IDAR中哪些位是必须严格匹配的。
匹配规则:对于接收到的消息标识符的每一位,硬件执行如下操作:
- 取IDAR中对应位的值(期望值)。
- 取IDMR中对应位的值(掩码)。
- 如果IDMR中该位为0,则表示“必须匹配”。此时,接收到的ID位必须与IDAR中对应位的值完全相同,该位才算匹配通过。
- 如果IDMR中该位为1,则表示“忽略/不关心”。此时,无论接收到的ID位是0还是1,该位都算匹配通过。
- 只有当所有“必须匹配”的位都通过时,这条消息才被接受。
配置示例:接收一个特定的标准帧ID假设我们需要接收标准帧ID为0x123(二进制001 0010 0011) 的消息,并且我们不关心ID的最低3位(即允许ID在0x120到0x127范围内)。
帧格式:标准帧,IDE位为0。
IDAR配置:标准帧只使用IDAR0和IDAR1。
IDAR0: 我们需要设置高8位。0x123的高8位是0x12(二进制0001 0010)。但注意,标准帧ID在寄存器中的存储格式(见图9-38)。ID10是最高位,存储在IDR0的Bit7。所以我们需要将0x123(二进制001 0010 0011) 左移对齐到高位。IDAR0=0x48(计算:0x123<< 5,取高8位。0x123=291,左移5位=9312,高8位为0x24?这里需要仔细对齐。更稳妥的方法是按位映射:ID10对应IDAR0.7,ID9对应IDAR0.6,…,ID3对应IDAR0.0。所以0x123(001 0010 0011)的高8位(0010 0100)就是0x24。)
IDAR1: 低3位(ID2, ID1, ID0)和RTR、IDE位。我们期望的ID低3位是011。同时,IDE位必须为0(标准帧)。假设我们只接收数据帧(RTR=0)。IDAR1=0x03(二进制0000 0011)。其中,ID2=0, ID1=1, ID0=1 (来自0x123的低三位011),RTR=0,IDE=0。注意手册图9-39,ID2在Bit7,ID1在Bit6,ID0在Bit5,RTR在Bit4,IDE在Bit3。所以011放在Bit7,6,5就是0110 0000?不对,应该是011映射到高三位。我们重新按位计算:Bit7(ID2)=0, Bit6(ID1)=1, Bit5(ID0)=1, Bit4(RTR)=0, Bit3(IDE)=0。所以IDAR1=0x60?不对,0x60是0110 0000,我们的值在Bit7-5是011,即0110 0000,确实是0x60。但Bit4和Bit3是0,所以还是0x60。这里容易出错,强烈建议在代码中使用位域操作或清晰的���位宏定义,而不是直接写十六进制数。
IDMR配置:我们希望忽略ID的低3位(ID2, ID1, ID0)。
IDMR0: 对应IDAR0的8位,我们希望所有位都必须匹配,所以全部设为0。IDMR1: 对应IDAR1的8位。我们需要忽略ID2, ID1, ID0(即IDMR1的Bit7,6,5),所以将这些位置1。RTR和IDE位我们要求匹配(Bit4和Bit3置0)。低3位保留位(Bit2-0)按手册说明保留。IDMR1=0xE0(二进制1110 0000)。这样,Bit7,6,5为1表示忽略,接收到的ID在这三位可以是任意值,都能通过过滤。
关键点:掩码寄存器中,1代表忽略(Don‘t Care),0代表必须匹配。这个逻辑和有些网络子网掩码(1代表网络位)是反的,初学时极易混淆,务必注意。
3.2 标识符命中指示器(IDHIT)
手册中提到了一个非常实用的功能:IDHIT指示器。当一条消息成功通过过滤并进入接收前台缓冲区(RXFG)时,IDHIT[2:0]这三个位会指示这条消息具体是命中了哪个过滤器(0-7)。
它的价值在哪里?
- 高效分拣:在中断服务程序(ISR)中,你不需要用软件去比较接收到的ID来判断消息类型。直接读取
IDHIT值,通过一个查表或switch-case语句,就能立刻知道这条消息对应哪个业务逻辑处理函数,极大提升了中断响应效率。 - 调试利器:当你发现某个预期的消息没有收到时,可以检查
IDHIT。如果它显示命中了某个过滤器,说明硬件过滤是成功的,问题可能出在后续的读取或处理环节;如果根本没命中任何过滤器(或命中了一个错误的),那问题肯定出在IDAR/IDMR的配置上。
3.3 总线关闭管理与BOHOLD位
CAN节点在遭遇严重错误(如持续发送错误)时,会进入“总线关闭”状态,这是一种自我保护机制,防止故障节点拖垮整个网络。手册中CTRL1寄存器的BORM位和MISC寄存器的BOHOLD位共同管理这一过程。
- BORM (Bus-Off Recovery Mode):此位决定总线关闭后的恢复模式。如果
BORM=1,则节点进入总线关闭后,不会自动尝试恢复,而是等待软件干预。 - BOHOLD (Bus-off State Hold Until User Request):当
BORM=1且节点进入总线关闭状态后,此位被硬件自动置1。此时,节点将一直保持在总线关闭状态。
软件恢复流程:
- 节点因错误计数超过255而进入总线关闭状态,
BOHOLD位被置1。 - CPU通过轮询或错误中断检测到这一状态。
- 软件必须主动将
BOHOLD位写0,以请求模块从总线关闭状态中恢复。 - MSCAN模块收到请求后,会执行恢复序列(等待128次出现11个连续的隐性位),然后重新尝试接入总线。
避坑指南:总线关闭恢复很多新手会忽略这个配置。如果你的节点在出现严重错误后“死掉了”,再也无法通信,请务必检查
BORM和BOHOLD的配置。如果设置了手动恢复(BORM=1),就必须在软件中实现状态监控和恢复逻辑。一个健壮的设计是:在错误中断服务程序中,检查错误状态寄存器,如果发现总线关闭(BOHOLD=1),则在适当的延时后(例如等待1秒),清除BOHOLD位发起恢复,并重置错误计数器。切忌在高速循环中不断清除BOHOLD,这可能导致节点在未准备好的情况下反复冲击总线。
3.4 错误计数器寄存器(RXERR, TXERR)
RXERR和TXERR寄存器分别反映了接收和发送错误计数器的值。根据CAN协议,当任何一个错误计数器值超过127时,节点进入“错误被动”状态(Error Passive),此时它仍然能收发数据,但在发生错误时只能发送被动错误标志,不能主动中断错误帧。当发送错误计数器超过255时,节点进入“总线关闭”状态。
手册中的警告需要特别注意:“Reading this register when in any other mode other than sleep or initialization modes may return an incorrect value.” 这意味着,在正常操作模式下,直接读取这两个寄存器可能得到错误的值!这是因为错误计数器可能正在被硬件实时更新,直接读取可能抓到中间状态。
正确的做法是什么?通常,你不需要频繁读取具体的错误计数值。更关心的是节点状态(主动/被动/关闭)。这个状态可以通过CANSTAT寄存器(或MSCAN中类似的状态位)来获取。错误计数器主要用于深度调试和网络健康状况评估。如果必须读取,一个稳妥的方法是在短暂关闭CAN中断或进入初始化模式的瞬间进行读取,但这会中断通信,需谨慎操作。
4. 消息缓冲区结构与数据存取实操
4.1 缓冲区组织:统一的13字节结构
手册指出,MSCAN的接收和发送消息缓冲区具有相同的13字节内存结构。这简化了驱动程序设计。这13个字节包括:
- 字节 0-3 (IDR0-IDR3):标识符寄存器。根据IDE位决定是标准帧格式(使用IDR0-1)还是扩展帧格式(使用IDR0-3)。
- 字节 4-11 (DSR0-DSR7):数据段寄存器。最多8个字节的数据载荷。
- 字节 12 (DLR):数据长度码寄存器。低4位(DLC3-DLC0)表示数据字节数(0-8)。
- 字节 13 (TBPR):仅发送缓冲区有。发送缓冲区优先级寄存器。用于在多个待发送消息间进行硬件仲裁,值越小优先级越高。
- 字节 14-15 (TSRH-TSRL):时间戳寄存器(高字节和低字节)。需要在
CTRL0寄存器中使能TIME位。当消息被成功发送或接收时,由硬件自动写入一个内部自由运行定时器的值。
4.2 标准帧与扩展帧的标识符存储差异
这是配置时最容易出错的地方之一。必须根据IDE位的值,以不同的方式解读IDR0-IDR3。
对于扩展帧 (IDE=1):
IDR0: 存储ID28-ID21(高8位)。IDR1: 存储ID20-ID18、SRR位(固定为1)、IDE位(固定为1)、ID17-ID15。IDR2: 存储ID14-ID7。IDR3: 存储ID6-ID0、RTR位。
对于标准帧 (IDE=0):
IDR0: 存储ID10-ID3(高8位)。注意,标准帧ID只有11位,所以IDR0的Bit7是ID10。IDR1: 存储ID2-ID0、RTR位、IDE位(固定为0)。IDR1的高5位(Bit7-Bit3)用于存储ID的低3位和RTR、IDE。IDR2和IDR3: 在标准帧下未使用,读取为不确定值。
在软件中处理接收消息的通用方法:
// 假设已经将RXFG缓冲区的13个字节读入了一个结构体 `can_msg_t` can_msg_t msg; // 1. 判断帧格式 if (msg.IDR1 & 0x08) { // 检查IDE位 (IDR1的Bit3) // 扩展帧处理 uint32_t ext_id = 0; ext_id = ((uint32_t)(msg.IDR0 & 0xFF)) << 21; // ID28-ID21 ext_id |= ((uint32_t)(msg.IDR1 & 0xE0)) << 13; // ID20-ID18 ext_id |= ((uint32_t)(msg.IDR1 & 0x07)) << 15; // ID17-ID15 ext_id |= ((uint32_t)(msg.IDR2 & 0xFF)) << 7; // ID14-ID7 ext_id |= ((uint32_t)(msg.IDR3 & 0xFE)) >> 1; // ID6-ID0 (注意RTR位在最低位) // RTR位在 msg.IDR3 & 0x01 // SRR位在 (msg.IDR1 >> 4) & 0x01,扩展帧下应为1 } else { // 标准帧处理 uint16_t std_id = 0; std_id = ((uint16_t)(msg.IDR0 & 0xFF)) << 3; // ID10-ID3 移到高位 std_id |= ((uint16_t)(msg.IDR1 & 0xE0)) >> 5; // ID2-ID0 移到低位 // RTR位在 (msg.IDR1 >> 4) & 0x01 // IDE位已知为0 } // 2. 获取数据长度 uint8_t dlc = msg.DLR & 0x0F; // 3. 获取数据 uint8_t data[8]; for(int i=0; i<dlc; i++) { data[i] = msg.DSR[i]; }4.3 时间戳功能的启用与应用
时间戳功能对于网络性能分析、节点同步、故障诊断极其有用。启用步骤:
- 在初始化阶段,设置
CTRL0寄存器的TIME位为1。 - 当一条消息被成功发送或接收(在ACK间隙采样点),硬件会自动将内部CAN位定时器的当前值捕获到该消息缓冲区的
TSRH和TSRL寄存器中。 - 对于发送缓冲区,CPU只能在发送完成(缓冲区变空)后读取时间戳。对于接收缓冲区,则可以在读取消息数据时一并读取。
注意事项:
- 这个定时器是自由运行的,会溢出。软件需要处理溢出情况,通常采用计算差值的方式来判断时间间隔。
- 时间戳的精度取决于CAN总线的位定时。例如,在1Mbps速率下,一个位时间是1微秒,时间戳的每个计数就代表1微秒。你可以用它来精确测量消息周期、网络延迟等。
5. 中断机制与实战配置
5.1 四大中断源及其应用场景
MSCAN提供了四个独立的中断向量,可以分别屏蔽:
- 发送中断 (TXE):当至少一个发送缓冲区为空(或未调度)时触发。这意味着CPU可以加载新的消息到空闲缓冲区进行发送。应用:用于实现非阻塞发送。发送函数将消息填入缓冲区并启动发送后立即返回,发送完成由中断通知。
- 接收中断 (RXF):当一条消息被成功接收并移入RXFG时触发。应用:最常用的中断,用于及时处理接收到的消息。
- 唤醒中断 (WUPIF):当CAN模块处于睡眠模式,且总线上有活动时触发。前提:必须使能
CTRL0中的WUPE位。应用:用于低功耗系统,节点平时休眠,被总线活动唤醒。 - 错误中断 (CSCIF, OVRIF):当接收FIFO溢出、错误状态改变(如进入错误被动、总线关闭)时触发。应用:用于网络监控和故障处理,是保证系统鲁棒性的关键。
5.2 中断服务程序(ISR)编写要点
手册特别强调了一个关键点:“It must be guaranteed the CPU clears only the bit causing the current interrupt. ... bit manipulation instructions (BSET) must not be used to clear interrupt bits.”
为什么?因为RFLG和TFLG寄存器中的中断标志位是通过“写1清除”的。如果你使用BSET(位设置)指令,意图清除某个标志位(比如RXF),但此时另一个中断事件恰好发生(比如发送完成TXE0置位),BSET指令可能会意外地将这个新置位的标志也清除掉,导致该中断事件丢失。
正确的做法: 在ISR中,先读取RFLG/TFLG寄存器值,判断具体是哪个中断源,然后向该特定位写入1,其他位写入0,来清除标志。或者,更安全的做法是,将读取到的中断标志值直接写回寄存器,因为读出的值里该标志位是1,写1即可清除它,而其他位是0,写0不会影响它们。
void CAN_ISR(void) { uint8_t rflg_val = CAN_RFLG; uint8_t tflg_val = CAN_TFLG; // 处理接收中断 if (rflg_val & CAN_RFLG_RXF_MASK) { // 1. 读取RXFG中的数据 process_received_message(); // 2. 清除RXF标志(写1清除) CAN_RFLG = CAN_RFLG_RXF_MASK; // 只将RXF位置1,其他位为0 } // 处理发送中断 if (tflg_val & CAN_TFLG_TXE0_MASK) { // 发送缓冲区0空闲,可以加载下一帧 load_next_tx_message(0); // 清除TXE0标志 CAN_TFLG = CAN_TFLG_TXE0_MASK; } // ... 处理其他中断源 }5.3 从停止/等待模式唤醒
这是一个低功耗相关的特性。要使CAN模块能从MCU的STOP或WAIT模式唤醒系统:
- 首先,必须让CAN模块自身进入睡眠模式(设置
SLPRQ=1并等待SLPAK=1)。 - 然后,使能唤醒功能(
CTRL0.WUPE = 1)。 - 接着,使能唤醒中断(
RIER.WUPIE = 1)。 - 最后,才允许MCU进入低功耗模式。 当总线活动发生时,CAN模块会产生唤醒中断,将MCU从低功耗模式拉出,然后CAN模块自身也会退出睡眠模式。
6. 常见问题排查与调试技巧实录
6.1 问题:配置了过滤器,但收不到任何消息
排查步骤:
- 检查物理层:用示波器或CAN分析仪先确认总线上确实有目标消息在传输,且波形质量良好。这是最基本的一步,排除硬件问题。
- 确认模块模式:确保MSCAN模块已退出初始化模式(
INITRQ=0,INITAK=0),进入了正常工作模式。很多新手在配置完寄存器后忘记清除初始化请求位。 - 验证过滤器配置:
- 时机:IDAR和IDMR寄存器只能在初始化模式下(INITRQ=1且INITAK=1)才能写入。确认你的配置代码执行时处于此模式。
- 值计算:双重检查IDAR和IDMR的值。特别是标准帧和扩展帧的位对齐,以及掩码逻辑(1为忽略,0为匹配)。建议编写一个配置函数,输入期望的ID和掩码模式,自动计算出寄存器值,减少手动计算错误。
- 过滤器模式:确认你使用的过滤器组与帧格式匹配。不要试图用两个过滤器(标准帧配置)去匹配一个扩展帧ID。
- 检查接收使能:确认
CTRL0寄存器中的RXFRM位(如果存在)或相关接收使能位已设置。有些模块有单独的接收使能控制。 - 查看中断与标志:
- 使能接收中断(
RIER.RXFIE = 1)或轮询RFLG.RXF位。 - 如果使用了中断,确认全局中断和CAN模块中断已开启。
- 在调试时,可以暂时关闭所有过滤器(将IDMR全部设为0xFF),看是否能收到所有消息。如果能,则问题一定出在过滤器配置上。
- 使能接收中断(
6.2 问题:能收到消息,但IDHIT指示与预期不符
可能原因与解决:
- 过滤器优先级:MSCAN可能按过滤器编号顺序进行匹配。如果一条消息同时满足多个过滤器的条件,它可能命中编号最小的那个。检查你的过滤器设置是否有重叠。
- 掩码寄存器配置错误:这是最常见的原因。例如,你想匹配ID
0x123,但掩码设成了0x00(必须全匹配),而总线上来的ID因为某些原因(如发送节点问题)是0x122,就不会命中。或者相反,掩码设得太宽,命中了你不期望的过滤器。 - IDE位不匹配:你想接收扩展帧,但过滤器中IDE位掩码设为0(必须匹配)且IDAR中IDE位为0(标准帧),这永远无法匹配扩展帧。对于扩展帧过滤器,IDAR中对应的IDE位应设为1,且IDMR中该位通常设为0(必须匹配)。手册中扩展帧映射图显示IDE位在IDR1的Bit3,且固定为1。
6.3 问题:发送消息失败,错误计数器快速增长
排查思路:
- 检查波特率配置:这是头号杀手。确保发送节点和网络其他节点的波特率设置绝对一致,包括位时间采样点(通常为75%-80%)。一个不匹配的波特率会导致位采样错误,引发格式错误,发送错误计数器
TXERR会急剧上升。 - 检查终端电阻:高速CAN(ISO 11898-2)需要在总线两端各接一个120欧姆的终端电阻。缺少或电阻值不对会导致信号反射,通信质量差。
- 检查硬件连接:CAN_H和CAN_L是否接反?线缆是否有破损?可以用万用测量总线差分电压,静态时应约为2.5V。
- 查看错误状态:读取错误状态寄存器,看具体是哪种错误(位错误、填充错误、CRC错误等)。这能帮你定位是发送问题、接收问题还是总线冲突问题。
- 监听总线:使用CAN分析仪监听,看你的节点是否真的在发送报文,报文内容是否正确。有时软件配置了发送,但可能因为缓冲区优先级(TBPR)���发送控制位(TXEx)没设置对,导致消息并未真正被调度发送。
6.4 调试技巧:利用接收FIFO和溢出标志
MSCAN通常有一个深度为2或更多的接收FIFO。这意味着在CPU处理前一条消息时,硬件可以继续接收下一条消息而不会丢失(只要FIFO未满)。
- FIFO溢出(OVRIF):如果CPU处理速度太慢,导致FIFO满了之后还有新消息到来,就会发生溢出。
RFLG寄存器中的RXF位和OVRIF位都会置位。在ISR中,应该先读取消息,再清除RXF标志。如果顺序反了,在清除标志后、读取数据前,新消息可能已经覆盖了前台缓冲区。 - 性能评估:监控
OVRIF标志是否频繁置位,是评估你的中断服务程序处理速度是否跟得上总线负载的重要手段。如果频繁溢出,就需要优化代码,或者考虑使用更高效的ID过滤策略来减少不必要的中断。
最后,再分享一个寄存器配置的小技巧:在编写初始化函数时,不要一次性把所有寄存器都写一遍。应该遵循一个明确的顺序,例如:1) 进入初始化模式;2) 配置波特率相关寄存器(CTRL1中的时序参数);3) 配置过滤器(IDAR/IDMR);4) 配置中断使能(RIER,TIER);5) 配置其他功能(如时间戳TIME、唤醒WUPE);6)最后,退出初始化模式。并确保在每一步之后,必要时检查状态位(如INITAK)。