1. 项目概述与BISYNC协议背景
在嵌入式系统开发,尤其是涉及工业控制、传统金融终端或电信设备维护的场景里,你大概率会遇到一些“老而弥坚”的通信协议。BISYNC(Binary Synchronous Communication,二进制同步通信)就是其中之一。它诞生于上个世纪,由IBM定义,虽然现在看来效率不算高,但其设计严谨,通过硬件支持能实现非常可靠的数据传输,因此在一些对稳定性要求极高、且升级成本巨大的存量设备中,依然占据一席之地。
MPC8260 PowerQUICC II处理器中的串行通信控制器(SCC)模块,其强大之处在于它能通过可编程的寄存器,将诸如BISYNC、HDLC、UART等多种协议在硬件层面实现。这意味着协议中的字符填充、CRC计算、同步序列插入等繁琐操作都由SCC这个“协处理器”代劳,主CPU只需配置好参数和管理数据缓冲区,极大解放了算力。今天,我们就来彻底拆解SCC的BISYNC模式,不光是看手册里的寄存器位定义,更要弄明白每个配置项背后的设计意图,以及在实际编程中如何组合它们,避开那些手册里可能一笔带过、但调试时能让你抓狂的“坑”。
2. BISYNC核心机制与寄存器深度解析
理解BISYNC,首先要抓住它的几个核心机制:同步、透明模式、以及错误控制。MPC8260的SCC通过一组专用寄存器来驾驭这些机制。
2.1 同步(SYNC)与数据链路转义(DLE)机制
BISYNC协议依靠特定的同步字符(SYNC)来对齐发送和接收方的时钟。在MPC8260中,SYNC字符由BSYNC寄存器定义。但BISYNC的复杂之处在于它对控制字符(如STX、ETX)的处理。为了防止数据字段中恰好出现与控制字符相同的代码而被误解释,协议引入了DLE字符。
BDLE寄存器就是管理这一切的核心。它的作用远不止于存储一个DLE字符值(BDLE[DLE]字段)。
BDLE[V](Valid位):这是理解接收逻辑的关键。当V=1时,接收器会进入一种“警觉”状态:它会把接收到的每一个DLE字符都视为一个潜在转义序列的开始。如果紧跟着DLE的第二个字符是SYNC,SCC会丢弃这对DLE-SYNC(常用于填充或维持同步)。如果第二个字符还是DLE,SCC会认为这是数据中一个真正的DLE,将其存入缓冲区并参与块校验序列(BCS)计算。如果第二个字符既不是SYNC也不是DLE,SCC会去查控制字符表,如果是ETX等字符,则正常结束帧;如果都不是,则会报DLE follow character error。BDLE[DIS](Disable DLE stripping位):此位仅在透明模式下有意义。当DIS=1时,硬件将禁用对DLE的自动剥离。这意味着DLE-DLE、DLE-SYNC等序列会被原封不动地写入接收缓冲区。这个功能通常用于调试或需要透传所有原始字节流的场景。在正常BISYNC模式下,应保持DIS=0,让硬件自动处理转义序列,减轻软件负担。
实操心得:在调试初期,可以暂时将
DIS置1,并让接收缓冲区每个字节都触发中断(SCCM[RCH]=1),这样你就能在软件中看到原始的、未经处理的字节流,非常利于分析通信对端发来的原始数据格式,确认SYNC、DLE等字符是否正确。确认无误后,再关闭此功能以提升效率。
2.2 协议特定模式寄存器(PSMR)的配置艺术
PSMR寄存器是BISYNC模式的大脑,它决定了数据如何被加工和处理。
PSMR[CRC](CRC选择):这里有两个关键选项。01选择CRC-16(多项式X^16 + X^15 + X^2 + 1),这是BISYNC最常用的校验方式。11选择纵向冗余校验(LRC),即字节累加和校验。一个极易忽略的细节:当选择LRC时,如果不在透明模式下(PSMR[RTR]=0),收发器会自动启用字符奇偶校验。这意味着你如果使用7位数据+1位奇偶校验的格式,硬件会帮你检查每个字符的奇偶性。此时,PSMR[RPM]和PSMR[TPM]才生效,用于选择奇校验、偶校验等模式。PSMR[RBCS](接收BCS控制):这是一个可以“动态”操作的位。它允许你在接收一个数据块的过程中,临时将某个字节排除在BCS计算之外。为什么需要这个?考虑这个场景:数据块以SOH(Start of Header)开始,而协议规定SOH不参与BCS计算。你可以在检测到SOH后,在8个串行时钟周期内清除RBCS,这样SOH就被排除在校验外,然后再置位RBCS继续计算后续数据的BCS。这需要精确的定时操作,通常通过中断服务程序实现。PSMR[RTR](接收器透明模式):这是实现“字节间插”处理的关键。当RTR=1时,接收器进入透明模式。在此模式下,只有紧跟在DLE后面的控制字符才会被识别。例如,只有DLE-ETX才会被识别为帧结束,而数据中单独的ETX字符会被当作普通数据。这用于处理数据中可能包含与控制字符相同代码的情况。PSMR[DRT](发送时禁用接收器):手册提到,BISYNC通常是半双工协议,但接收器在发送时并未被物理禁用。DRT位提供了一种硬件协助:当DRT=1时,SCC在发送数据期间会自动禁用接收器,并由内部RTS信号门控。这在多站( multidrop )总线中非常有用,可以防止设备接收到自己发送的数据造成干扰。但有一个重要限制:如果使用了DRT,除非TCLK和RCLK使用同一个时钟源且CTS信号具有同步时序或始终有效,否则必须清除GSMR_H[CDS]位。配置不当会导致通信失败。
2.3 同步序列发送与GSMR_H[SYNL]的配合
同步序列在DSR寄存器中定义。GSMR_H[SYNL]位域决定了如何使用它:
00: 使用外部SYNC信号,而非DSR中的模式。01: 使用DSR低4位作为4位SYNC模式。10: 使用DSR低8位作为8位SYNC模式。11: 使用整个DSR(16位)作为SYNC模式。
PSMR[NOS]则定义了在消息之间或之前发送的SYN1-SYN2对的最小数量。这里SYN1-SYN2指的是DSR寄存器中的完整16位值,无论SYNL设置如何,发送时总是发送整个16位对。合理设置NOS可以确保接收端有足够的时间建立位同步和字符同步,特别是在线路质量不佳时。
3. 缓冲区描述符(BD)机制与实战编程
BD是SCC与主CPU之间数据交换的“契约”。CPU准备好数据缓冲区,填写BD告知SCC位置和属性;SCC完成任务后,更新BD状态通知CPU。
3.1 接收缓冲区描述符(RxBD)的关键状态位
接收完成后,CPU需要检查RxBD的状态位来判断结果:
| 状态位 | 名称 | 含义与处理策略 |
|---|---|---|
E | Empty | 1表示缓冲区空,归CPM控制;0表示缓冲区满或有错误,CPU可读写。关键:CPU处理完数据后,必须将此位置1并可能更新数据指针,才能将缓冲区重新交给CPM。 |
C | Control Character | 1表示缓冲区最后一个字节是用户定义的控制字符(来自控制字符表)。这通常意味着一个消息块的结束,软件需要据此进行解析。 |
B | BCS Received | 1表示该缓冲区包含接收到的块校验序列(BCS)。通常与C位结合判断,C=1, B=1可能表示ETX+BCS的结束。 |
DL | DLE follow error | 透明模式下,收到DLE后,下一个字符不是有效的DLE、SYNC或控制字符表条目。这通常是协议解析错误或数据损坏的标志。 |
PR | Parity Error | 字符奇偶校验错误。发生此错误时,缓冲区会立即关闭,错误字符是该缓冲区的最后一个字节。 |
CR | BCS Error | BCS校验错误。注意:此位在每个字节写入缓冲区时都会更新,反映包含该字节在内的当前BCS计算状态。它并非仅在帧结束时有效。 |
OV | Overrun | 接收FIFO溢出。意味着数据速率过高或CPU处理不及时,导致字符被覆盖丢失。 |
CD | Carrier Detect Lost | 载波检测信号在帧接收过程中丢失。在调制解调器或无线应用中指示链路中断。 |
避坑指南:
CM(连续模式)位需谨慎使用。当CM=1时,CPM在关闭BD后不会自动清除E位,而是会覆盖同一缓冲区。这适用于需要极高吞吐量、由DMA循环使用固定缓冲区的场景。但如果发生错误(如OV,CD),E位仍会被清除。若你的中断服务程序(ISR)以E位判断是否有新数据,在连续模式下就需要改变策略,例如通过数据长度字段或自定义的缓冲区索引来判断。
3.2 发送缓冲区描述符(TxBD)的精细控制
发送配置的灵活性主要体现在TxBD的控制位上:
| 控制位 | 名称 | 配置策略与影响 |
|---|---|---|
L | Last in message | 最重要的位之一。1表示此缓冲区包含消息的最后一个字符。发送完后,发送器会回到正常模式(发送SYNC或空闲序列)。如果同时TB=1,则在最后一个字符后发送BCS。 |
TB | Transmit BCS | 仅在L=1时有效。1表示在缓冲区最后一个字符后发送BCS序列。 |
BR | BCS Reset | 1表示在发送此缓冲区数据之前,重置发送器BCS累加器。这用于发送消息头(如SOH)时不将其计入校验。 |
TD | Transmit DLE | 1表示在发送此缓冲区数据之前,自动插入一个DLE字符。这在透明模式下非常有用,可以节省一个专门存放单个DLE的缓冲区。 |
TR | Transparent mode | 1表示发送器在发送此缓冲区后进入或保持在透明模式。在透明模式下,发送器会自动处理DLE插入(遇到数据DLE则再插入一个),并在发生下溢时插入DLE-SYNC对。注意:即使PSMR[CRC]设置为LRC,在透明模式下发送器仍使用CRC16计算BCS。 |
B | BCS enable | 1表示此缓冲区的字符参与BCS累加计算;0则表示排除。用于灵活控制哪些数据参与校验。 |
一个典型的数据块发送BD链配置示例:
- BD1 (消息头):
L=0, TB=0, BR=1, TD=0, TR=0, B=0。发送SOH,并重置BCS计算,且SOH本身不参与BCS。 - BD2 (数据块):
L=0, TB=0, BR=0, TD=0, TR=1, B=1。发送数据,进入透明模式,数据参与BCS。 - BD3 (结束符):
L=1, TB=1, BR=0, TD=0, TR=0, B=1。发送ETX(或其它结束符),结束透明模式,发送BCS,ETX参与BCS。
3.3 事件与状态寄存器:系统的“眼睛”和“耳朵”
SCCE/SCCM(事件/掩码寄存器):这是中断的来源。TXB(发送缓冲区完成)、RXB(接收缓冲区完成)、TXE(发送错误)是最常用的事件。RCH(收到字符)事件在需要逐字节软件处理的场景下有用,但频繁中断开销大。BSY(忙)事件提示接收端缓冲区不足,是优化系统性能的关键指标。SCCS(状态寄存器):提供实时状态,如CS(载波检测),可以在不产生中断的情况下轮询线路状态。
4. 编程实践:从初始化到数据收发的完整流程
手册第23.17节的示例代码是一个很好的起点,但我们需要理解每一步的深意,并补充细节。
4.1 初始化序列详解与增强
以下是基于手册示例的增强版初始化步骤解析:
- 端口引脚配置:这一步将处理器引脚复能为SCC所需功能(TXD, RXD, RTS, CTS, CD, CLK)。关键点:务必查阅MPC8260的硬件规范,确认这些引脚的上拉/下拉电阻配置(
PDPAR寄存器)和驱动能力(PDIR)是否适合你的外部电路。错误的驱动配置会导致信号完整性问题。 - 时钟与多路复用器配置:将
CLK3引脚连接到SCC2的收发时钟。CMXSCR寄存器的配置必须确保收发时钟同源,否则异步时钟会导致数据错位。 - 缓冲区描述符表基址:
RBASE和TBASE指向双端口RAM中的地址。重要实践:通常将BD表放在内存中对其性能更好(如32字节对齐)。并且,建议初始化一个BD环(多个BD),而不是单个BD,以避免BSY事件频繁发生。 - 执行
INIT RX AND TX PARAMETERS命令:通过写CPCR寄存器发起。这个命令是必须的,它使CPM内部指针RBPTR和TBPTR更新为RBASE和TBASE的值。忘记这一步是常见错误,会导致SCC无法找到BD。 - 配置
MRBLR:设置接收缓冲区的最大长度。经验值:这个值需要权衡。太小会导致频繁中断和BSY;太大会增加单次中断的处理延迟。对于中等速率(如64kbps)的BISYNC,256-1024字节是个合理的起点。需确保缓冲区在内存中连续。 - 配置
BSYNC,DSR,BDLE,CHARACTERx:这些寄存器定义了协议参数。CHARACTER1通常配置为ETX。扩展技巧:CHARACTER表可以定义多个控制字符(如ETX,ETB,ENQ)。每个条目由字符值和几个控制位(E, B, H)组成,用于指示该字符是否结束块、是否后跟BCS等。这赋予了硬件识别多种协议帧格式的能力。 - 初始化BD:
- RxBD: 状态字设为
0xB000。这里B是BCS received位吗?不,查看图23-6,Bit5是B,Bit11是DL。0xB000二进制是1011 0000 0000 0000,即E=1(空),W=0,I=0,C=0,B=1?这看起来可能不对。通常初始化的RxBD应该是0x9000(E=1,W=0,I=0, 其余保留位清0)。B=1通常是在接收完成后由CPM设置的。这里手册示例可能是个笔误或特定配置。安全做法:参考Section 20.2对通用BD的描述,RxBD初始状态通常为0x8000(仅E=1)或0x9000(E=1,I=1使能中断)。 - TxBD: 状态字
0xBD20。解析:0xBD20=1011 1101 0010 0000。E位是TxBD的R(Ready)位,这里bit0=0,表示缓冲区未就绪,正确。L=1(Last),TB=1(Transmit BCS),CM=1(连续模式?TxBD的CM位需谨慎),B=1(BCS enable)。这个配置描述了一个包含完整消息(含结束符和BCS)的发送缓冲区。
- RxBD: 状态字设为
- 最后使能收发器:这是一个关键顺序。先配置好所有参数和BD,最后一步才写
GSMR_L以同时置位ENT和ENR(使能发送和接收)。这可以避免SCC在未正确配置的情况下启动,产生乱码或错误。
4.2 数据收发的中断驱动编程模型
高效的BISYNC驱动通常采用中断驱动模型。
发送流程:
- 应用层准备数据,填入发送缓冲区。
- 填写TxBD:设置数据长度、缓冲区指针,以及
L,TB,I等控制位。最后将R位置1,将BD交付给CPM。 - CPM发送数据。
- 发送完成或出错时,CPM清除
R位,并根据I位设置决定是否触发TXB或TXE中断。 - 中断服务程序(ISR)检查
SCCE确认事件,读取TxBD状态字检查UN(下溢)、CT(CTS丢失)等错误。处理错误或释放已发送的缓冲区内存。 - 如果还有数据要发送,更新下一个TxBD并置位
R。
接收流程:
- 初始化时准备一个RxBD环,所有BD的
E位为1,并链接好(最后一个BD的W位为1)。 - CPM接收到数据,填满一个缓冲区后,清除该BD的
E位,并可能触发RXB中断。 - ISR检查
SCCE,找到对应的SCC通道。 - 遍历RxBD环,找到
E=0的BD。读取其状态字,检查OV,CD,PR,CR,DL等错误位。 - 根据
C和B位判断数据块边界。从缓冲区指针处读取数据长度字段,获取有效数据。 - 处理数据(如交给上层协议解析)。
- 关键一步:处理完成后,必须更新该BD——清除错误状态位(通常写0),将
E位置1(如果使用连续模式CM=1则可能不需要),并更新缓冲区指针(如果使用了动态缓冲区)。然后将BD重新交付给CPM。 - 如果发生
BSY事件,说明RxBD环耗尽,需要检查是否数据处理太慢,或者考虑增加BD数量或缓冲区大小。
4.3 透明模式下的特殊处理
透明模式(PSMR[RTR]=1)下,协议处理逻辑发生变化。发送方需要自动插入DLE,接收方需要识别DLE-XXX序列。
发送方:设置PSMR[RTR]=1并正确初始化PTCRC为CRC16预设值。在TxBD中,对于需要透明发送的数据缓冲区,设置TR=1。对于数据中可能出现的DLE字符,有两种处理方式:1)由硬件自动处理(推荐),即发送器检测到数据DLE会自动插入另一个DLE;2)在软件中预先对数据做DLE填充。
接收方:设置PSMR[RTR]=1并初始化PRCRC。接收器会剥离有效的DLE-DLE序列中的第一个DLE,将第二个作为数据。对于DLE-SYNC,两者都可能被丢弃或根据配置处理。DLE-ETX会被识别为帧结束。如果收到DLE后跟一个既非DLE、SYNC也非控制字符的字节,会置位DL错误位。
5. 高级调试技巧与常见问题排查
即使按照手册配置,在实际硬件上也可能遇到问题。以下是一些实战中总结的排查思路。
5.1 通信完全无数据
- 时钟检查:首先用示波器或逻辑分析仪测量
TCLK和RCLK引脚。确认时钟是否存在、频率是否正确、是否与数据速率匹配。SCC的时钟频率通常是波特率的16倍或32倍(取决于GSMR[CDP]等配置)。 - 引脚复用确认:再次检查
PPAR,PDIR,PSO寄存器,确保TXD, RXD等引脚已正确复能为SCC功能,并且输入/输出方向正确。 - CPM命令:确认
INIT RX AND TX PARAMETERS命令已执行成功。可以通过读取RBPTR和TBPTR来验证它们是否已被更新为RBASE和TBASE的值。 - 中断与轮询:如果使用中断,确认中断控制器(如SIU)已正确配置,中断服务程序已安装。可以暂时改为轮询
SCCE或BD的R/E位,排除中断配置问题。 - 流控信号:如果使用了CTS/RTS硬件流控,确保对方设备已准备好(CTS有效)。可以尝试在
GSMR_L中配置为忽略流控(DIAG位设置)进行测试。
5.2 能发送但不能接收,或反之
- 半/全双工配置:检查
GSMR_L中的DIAG(诊断)位。某些环回或内部连接模式用于测试。确保它被设置为正常操作模式(通常为0)。 - 收发使能位:确认
GSMR_L中的ENT(发送使能)和ENR(接收使能)都已置位。有时在修改寄存器后需要重新使能。 - 缓冲区描述符状态:对于接收,确认RxBD的
E位初始值为1(空)。对于发送,确认在启动发送前,第一个TxBD的R位已置1。 - 同步问题:接收器需要同步后才能开始接收数据。检查
GSMR_H[SYNL]和DSR中的SYNC模式设置是否正确。发送方是否在数据前发送了足够的SYNC字符(PSMR[NOS])?可以用逻辑分析仪捕捉RXD线上的信号,看是否有预期的SYNC模式。
5.3 数据错误(CRC/LRC校验失败、奇偶校验错误)
- 时钟同步与采样:这是最常见的原因。时钟频率偏差、抖动或相位不佳会导致采样错误。确保收发双方时钟精度满足要求。检查
GSMR中关于时钟边沿采样(上升沿/下降沿)的配置是否与对方设备匹配。 - 数据反转:检查
PSMR[RVD](Reverse Data)位。如果设置错误,会导致每个字符的比特位顺序(MSB/LSB)反转。 - BCS计算范围:确认哪些字符参与了BCS计算。发送方的
TxBD[B]位和BR位,接收方的PSMR[RBCS]动态控制,以及透明模式下的处理,都可能影响BCS计算范围。确保收发双方对帧起始(如SOH)、帧结束(如ETX)是否参与校验的约定一致。 - 奇偶校验模式:如果使用LRC并启用了字符奇偶校验,确保
PSMR[RPM]和PSMR[TPM]设置一致(同为奇校验或偶校验)。 - 初始值:CRC16计算需要预设值(通常为0x0000或0xFFFF)。确保
PRCRC和PTCRC已正确初始化。手册示例中初始化为0x0000,并指出发送器发送非反转的CRC,接收器检查结果是否为0。
5.4 性能问题(频繁Overrun/Underrun)
- 缓冲区大小与数量:增加
MRBLR(接收缓冲区长度)和RxBD环中BD的数量。这给了CPU更长的响应时间。 - 中断延迟:优化中断服务程序,使其尽可能短。只做最必要的操作(如将BD状态保存到队列),将数据处理移出ISR。检查系统全局中断是否被意外关闭太久。
- FIFO阈值:调整
GSMR_H[RFW](接收FIFO宽度)和GSMR_H[TFL](发送FIFO长度)。较小的FIFO可以减少数据从串行线到内存的延迟,但可能增加在高波特率下发生溢出/下溢的风险。需要根据波特率和CPU处理能力权衡。 - 使用
CM连续模式:对于发送,如果数据是连续流,可以考虑使用TxBD的CM位,避免频繁更新BD。对于接收,使用RxBD的CM位可以创建DMA式的循环缓冲区,但需要更精巧的缓冲区管理软件。
5.5 透明模式下的异常行为
- DLE处理混乱:检查
BDLE[DIS]位。在正常透明模式下应设为0。检查发送方是否在透明模式下(TxBD[TR]=1),以及接收方是否也在透明模式下(PSMR[RTR]=1)。 - CRC计算不一致:牢记手册中的警告:即使在
PSMR[CRC]设置为LRC时,只要收发器处于透明模式,它内部仍然使用CRC16算法进行BCS计算。因此,在透明模式下,PRCRC和PTCRC必须初始化为CRC16的预设值,而不是LRC的0或1。 - 控制字符不识别:在透明模式下,只有
DLE+控制字符才会被识别。确保你的帧格式符合这个约定。如果发送的是纯透明数据(无任何控制字符),则接收端永远不会因为收到控制字符而关闭缓冲区,除非缓冲区满或出错。这种情况下,你需要依赖超时或固定长度来判定帧结束。
通过以上对寄存器、BD机制、编程流程和调试技巧的层层剖析,你应该对MPC8260 SCC的BISYNC模式有了从理论到实践的全面认识。这套机制虽然复杂,但一旦掌握,就能构建出极其稳定可靠的底层通信链路。记住,阅读手册时多问几个“为什么”,配置寄存器时多想一步“如果…会怎样”,并在实际硬件上大胆测试、细心观察,这些经验远比记住某个寄存器的某个位值更重要。