十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于英飞凌XMC4000实现BiSS-C编码器接口的硬件驱动设计

基于英飞凌XMC4000实现BiSS-C编码器接口的硬件驱动设计 1. 项目背景与BISS协议的价值最近在做一个伺服驱动器的项目需要用到高精度的绝对值编码器。市面上常见的方案无非是SSI、EnDat、BiSS-C这些。在选型的时候我发现一个挺有意思的现象很多工程师一提到绝对值编码器接口第一反应就是SSI或者觉得BiSS-C是“高级货”用起来复杂。但实际上对于英飞凌XMC4000系列这种内置了强大的POSIF位置接口和CCU4/CCU8捕获比较单元模块的MCU来说实现BiSS协议尤其是BiSS C模式连续模式有着天然的优势而且能省下一笔不小的专用接口芯片成本。我手头这个项目电机端用的是支持BiSS C协议的单圈绝对值编码器分辨率是17位131072线。客户要求低成本、高可靠性还要能快速响应。如果外挂一个BiSS协议芯片虽然省事但BOM成本一下就上去了板子面积也紧张。所以我决定基于XMC4000的硬件资源从底层撸一个BiSS C模式的驱动程序。折腾了小半个月从协议分析、硬件配置到软件调试总算把轮子造好了位置读取稳定零延迟效果相当不错。这个驱动程序的完整工程我已经整理好放在了文末的链接里大家可以免费下载、参考和使用。今天这篇文章我就把这套驱动背后的设计思路、XMC4000硬件如何巧妙适配BiSS协议、代码的关键实现细节以及调试过程中踩过的几个“坑”毫无保留地分享出来。无论你是正在评估XMC4000用于运动控制还是单纯对BiSS协议底层实现感兴趣相信这篇长文都能给你带来实实在在的参考价值。2. BiSS协议核心机制与XMC4000的硬件契合点在动手写代码之前必须吃透BiSS协议特别是BiSS C连续模式。它和我们更熟悉的SSI协议在电气层很像都是两根数据线时钟MA、数据线SLO加上电源和地但通信机制有本质区别。SSI是主机单向发时钟从机编码器在时钟沿下输出数据属于纯粹的同步串行接口。而BiSS C是一种双向、全双工的同步串行协议它允许在同一个数据帧内主机向从机发送控制命令如请求位置、设置参数同时从机向主机回传传感器数据如位置值、状态信息。一个完整的BiSS C数据帧由主机发起以一段“起始序列”开始紧接着是主机发送的“命令段”CDM然后是从机响应的“数据段”DAT最后以“停止位”结束。时钟MA由主机产生在整个帧周期内是连续的。关键在于数据线SLO是双向的在命令段主机驱动SLO线向从机发送命令位在数据段主机释放SLO线改为输入模式从机驱动SLO线向主机回传数据位。这个“半双工切换”的时序要求非常严格是软件实现的核心难点之一。为什么说XMC4000特别适合干这个活儿这要归功于它内置的几个外设模块的巧妙组合。POSIF位置接口这是XMC4000为电机控制和编码器接口量身定做的模块。它的“霍尔模式”或“增量编码器接口模式”通常用于处理ABZ信号但它的“外部事件”触发和“模式切换”功能在这里可以大放异彩。我们可以配置POSIF使其输出一个与编码器时钟MA同步的、可精确控制脉冲个数和周期的时钟信号。这比用通用定时器模拟时钟要稳定和精确得多。CCU4/CCU8捕获/比较单元我们需要一个高精度的定时器来产生数据帧的时序并精确控制命令段和数据段的切换点。CCU4/CCU8的定时器配合其“影子传输”和“调制”功能可以生成非常精准的延时确保在正确的时钟边沿切换SLO数据线的方向。USIC通用串行接口通道虽然BiSS不是标准的UART或SPI但USIC模块的灵活性超乎想象。它的“数据缓冲”和“移位”功能可以方便地处理命令和数据的串并转换。更重要的是USIC可以与POSIF、CCU4等模块通过“服务请求线”进行硬件联动实现“时钟输出N个脉冲后自动触发数据读取”这样的硬实时操作几乎不占用CPU资源。我的设计思路就是用POSIF产生精准的MA时钟序列用CCU4定时器管理整个数据帧的时序阶段起始、命令、数据、停止用USIC配合GPIO的方向切换来处理SLO线上的双向数据传输并通过硬件连接SR让它们协同工作。这样CPU只需要在帧开始前准备好命令字在帧结束后读取数据缓冲区即可中间过程全由硬件自动完成效率极高确定性极强。3. 驱动程序详细设计与模块化实现整个驱动程序我把它分成了几个层次清晰的模块这样便于移植和维护。核心模块包括硬件抽象层HAL、协议时序层、数据链路层和应用接口层。3.1 硬件抽象层配置引脚、时钟与中断首先是最底层的硬件配置。我选择的是XMC4500 Relax Kit开发板但代码对XMC4100/4200/4400系列都是通用的。引脚分配MA (Clock): 使用POSIF0_OUT0引脚例如 P1.2。配置POSIF模块工作在“模式输出”状态由内部模式控制器驱动。SLO (Data): 使用一个支持双向功能的USIC通道引脚例如 P1.3对应USIC0_CH0_DX0。同时需要将该引脚对应的GPIO配置为“硬件控制”模式让USIC模块自动管理输入输出方向。时钟配置 BiSS C的时钟频率fMA需要根据编码器手册设定。我的编码器最高支持10MHz。为了留有余量并减少噪声我设定为5MHz。XMC4000的系统时钟SYSCLK是120MHz通过配置POSIF的时钟分频可以很容易得到5MHz的时钟输出。关键在于这个时钟只在数据帧期间产生帧间保持低电平这需要配置POSIF的模式控制寄存器。中断与服务请求 中断不是必须的但用好了能大幅提升效率。我配置了三个关键的中断/事件CCU4周期匹配中断标志一个完整数据帧的结束。在此中断中读取USIC接收缓冲区的位置数据并置位一个“数据就绪”标志。USIC接收缓冲区满中断作为备用机制确保数据被及时读取。POSIF模式切换事件通过SR服务请求连接到CCU4用于在命令段结束后自动触发数据段定时器实现硬件级的状态切换这是保证时序精度的关键。注意XMC的中断优先级需要仔细规划。CCU4的帧结束中断优先级应设为最高以确保位置数据被及时处理避免丢失。USIC中断优先级可以稍低。避免在中断服务程序中进行复杂计算或函数调用只做标志位设置和数据搬运。3.2 协议时序层的核心用CCU4充当“交响乐指挥”这是整个驱动最精妙的部分。我把一个CCU4定时器例如CCU40_CC40配置为“单次触发”模式它的一个周期就对应一个BiSS C数据帧的总时间。将这个周期时间划分为多个比较匹配CCy事件每个事件代表帧内的一个关键时间点CCy1: 起始序列结束开始输出MA时钟并发送命令位。CCy2: 命令段结束立即切换SLO线方向为输入准备接收数据位。CCy3: 数据段结束停止MA时钟帧结束。如何实现以我的编码器17位数据6位CRC1位错误位2位停止位共26位数据段命令段假设为8位为例帧总时间 (起始位时间) (8个命令位时间) (26个数据位时间)。设置CCU4定时器周期寄存器等于这个总时间以系统时钟周期为单位。设置比较寄存器1CCy1的值 起始位时间。设置比较寄存器2CCy2的值 起始位时间 8个命令位时间。当定时器启动运行到CCy1时通过硬件连接触发POSIF开始输出时钟同时触发USIC开始发送命令字。运行到CCy2时产生一个事件。这个事件通过SR连接会立即改变配置好的GPIO端口方向控制寄存器将SLO引脚从输出模式切换为输入模式。同时它也会触发USIC从发送模式切换到接收模式。这一切都在硬件层面瞬间完成没有软件延迟确保了切换点与某个时钟下降沿精确对齐这是软件模拟无法做到的。运行到周期结束CCy3时产生中断通知CPU帧传输完毕。3.3 数据链路层实现USIC的灵活运用USIC模块在这里扮演了“串行数据引擎”的角色。我将其配置为“SPI”模式的基本框架但进行了大量自定义。发送命令段将8位命令字例如请求位置的命令是0x55写入USIC的发送缓冲寄存器TBUF。配置USIC的发送控制使其在收到来自CCU4/CCy1的触发信号后在MA时钟的下降沿将数据移位到SLO线上。发送位数设置为8。关键点配置USIC的“传输控制”逻辑使其在发送完8位后自动停止并可以产生一个“发送完成”事件。这个事件可以用于其他联动。接收数据段在CCy2事件切换SLO方向后USIC需要立即准备接收。配置USIC的接收部分在MA时钟的上升沿采样SLO线上的数据。接收位数设置为26。同样配置其在接收满26位后自动停止并将数据存入接收缓冲寄存器RBUF。在CCU4周期结束中断里直接从RBUF读取这26位原始数据。CRC校验 BiSS C数据段包含6位CRC。我在驱动里实现了一个高效的查表法CRC计算函数uint8_t BISS_CalculateCRC6(uint32_t data)。每次收到数据后提取出22位位置数据和6位CRC重新计算CRC并与收到的CRC比对。如果不匹配则置位错误标志应用层可以选择丢弃该次数据或进行错误计数。3.4 应用接口层封装为了让上层应用如位置环、通讯程序调用简单我提供了几个简洁的API// 初始化函数 BISS_Status_t BISS_Encoder_Init(BISS_Config_t *config); // 启动一次位置查询非阻塞式 BISS_Status_t BISS_Encoder_RequestPosition(void); // 检查数据是否就绪 bool BISS_Encoder_IsDataReady(void); // 获取位置值并清除就绪标志 BISS_Status_t BISS_Encoder_GetPosition(int32_t *position); // 获取编码器状态错误、警告等 uint8_t BISS_Encoder_GetStatus(void);初始化时需要传入一个配置结构体包含时钟频率、数据位数、命令字等参数。RequestPosition函数会启动CCU4定时器随后硬件自动完成一次完整的帧通信。应用层可以在主循环中轮询IsDataReady或者在帧结束中断的服务程序里直接调用GetPosition。4. 调试过程中的关键问题与解决方案理论很美好调试过程却是一路坎坷。下面分享几个最具代表性的问题及其解决方法。4.1 时序抖动与数据错位硬件联动的必要性最初版本我尝试用CPU在中断里手动切换GPIO方向。即在命令段发送完最后一个位的中断里立刻将SLO引脚配置为输入。实测发现位置数据时不时会错一位CRC校验经常失败。问题根因中断响应有延迟而且这个延迟不确定受其他中断影响。这就导致SLO方向切换的时刻相对于MA时钟边沿是漂移的。可能切换早了还在命令段最后一个时钟的下降沿也可能切换晚了已经错过了数据段第一个时钟的上升沿采样点。解决方案彻底放弃软件切换采用上文所述的“CCU4事件通过SR触发GPIO方向切换”的硬件联动方案。具体实现是将CCU4的CCy2匹配事件输出连接到GPIO端口的方向控制寄存器输入选择器。通过配置端口硬件控制寄存器HWSEL使得当这个特定事件到来时硬件自动将引脚模式从输出变为输入。实测波形显示切换点与时钟边沿的对齐误差在2个系统时钟周期约16.7ns 120MHz以内完全满足BiSS协议要求。4.2 起始序列与编码器同步问题BiSS C协议要求主机在发送时钟前先发送一个至少2个MA时钟周期的高电平作为起始序列。我的编码器如果没检测到这个起始序列就不会响应后续的命令。踩坑过程一开始我简单地让POSIF先输出几个高电平时钟再开始正式帧。但发现编码器偶尔无响应。用逻辑分析仪抓取波形发现在“起始高电平”和“正式帧的第一个时钟下降沿”之间有一个非常短暂的低电平毛刺。解决方案问题出在POSIF的模式切换控制上。POSIF从“输出固定高电平”模式切换到“输出时钟”模式时内部逻辑会产生一个时钟周期的紊乱。解决方法是利用POSIF的“模式延迟”功能。配置两个模式模式0输出高电平、模式1输出时钟。设置从模式0切换到模式1时延迟1个POSIF时钟周期再生效。同时将起始序列的时间计入CCU4的CCy1比较值中。这样由CCU4统一指挥POSIF在精确的时刻从输出高电平无缝切换到输出时钟消除了毛刺。4.3 高波特率下的信号完整性与PCB布局当我把MA时钟频率调到8MHz以上时在长连接线超过1米的情况下通信错误率急剧上升。排查与解决端接电阻BiSS协议推荐在MA和SLO线上靠近主机端串联一个33-100欧姆的电阻以抑制反射。我最初为了省事没加。加上100欧姆电阻后波形过冲明显改善。PCB走线MA和SLO线必须当作差分对来处理尽管它们不是电气差分在PCB上应并行走线长度匹配远离电源和电机等噪声源。最好在它们之间铺地隔离。电源去耦编码器的5V电源一定要干净。在接口插座附近增加一个10uF钽电容和一个100nF陶瓷电容进行去耦。软件容错在驱动层增加了一个“连续错误计数器”。如果连续5帧CRC校验失败驱动程序会自动将MA时钟频率降低一档例如从10MHz降到5MHz并重新初始化通信。稳定一段时间后再尝试恢复高速率。这相当于一个简单的自适应机制。5. 性能实测与不同应用场景的适配建议驱动完成后我进行了一系列测试。性能测试单次读取时间在5MHz时钟下读取一帧26位数据约5.2us加上处理时间单次位置更新周期可稳定在10us以内即100kHz的更新率。这对于绝大多数伺服系统电流环通常10-20kHz速度环1-5kHz位置环0.5-1kHz来说绰绰有余。CPU占用率采用硬件联动中断方式CPU仅在帧结束中断中花费约0.5us读取数据、校验CRC、更新变量几乎可以忽略不计。抗干扰测试在电机PWM开关16kHz环境下通信稳定。模拟电源波动在4.5V-5.5V范围内工作正常。场景化适配建议多圈绝对值编码器BiSS C协议的数据段长度是可变的。如果你的编码器是多圈的例如32位单圈12位多圈状态位只需在驱动初始化时将data_bits参数设置为总位数如45位并相应调整CCU4定时器中数据段的时间长度即可。USIC的接收位数配置也要同步修改。多个编码器菊花链BiSS支持多个传感器通过一条总线菊花链连接。主机发送的广播命令所有从机都会接收但只有被寻址的从机在数据段回复。实现此功能需要在命令字中包含从机地址并在驱动中增加地址过滤逻辑。硬件上需要为每个SLO线增加一个三态缓冲器由从机的“数据有效”信号控制。与位置环集成建议将位置读取放在一个高优先级的定时器中断如100us周期中。在该中断里调用BISS_Encoder_GetPosition获取最新位置并计算位置差增量供速度环使用。为了避免中断冲突可以将BiSS的帧结束中断优先级设置为低于这个定时器中断确保位置处理不被BiSS通信打断。低功耗应用对于电池供电设备可以在电机静止时大幅降低BiSS通信频率如从100kHz降至1kHz。在驱动中提供一个BISS_Encoder_SetUpdateRate()函数动态修改CCU4定时器的重载值即可实现。6. 与SSI、EnDat协议的对比及选型思考最后聊聊为什么在这个项目里选了BiSS而不是更常见的SSI或EnDat。SSI协议优点极其简单几乎任何MCU的SPI或GPIO都能模拟成本最低。缺点单向通信主机无法向编码器发送任何配置或诊断命令抗干扰能力相对较弱时钟频率较高时长线传输需要严格端接。结论适用于对成本极度敏感、无需配置编码器、环境干扰小的场合。用XMC4000实现SSI是“杀鸡用牛刀”。EnDat协议优点由海德汉主导性能强大功能丰富双向、全数字、高可靠性、带诊断是高端数控机床的标配。缺点协议复杂通常需要专用芯片或FPGA实现成本最高有专利授权问题。结论适用于追求极致性能、功能、可靠性的高端工业设备。用纯软件在XMC上实现EnDat主站难度和工作量都非常大。BiSS协议优点开源、免授权费双向通信可读写编码器内部寄存器硬件实现难度介于SSI和EnDat之间抗干扰能力优于SSI。缺点生态不如SSI普及不同厂家的BiSS编码器兼容性有时需要调试。结论在需要双向通信、一定可靠性、又希望控制成本的场合BiSS是绝佳选择。而XMC4000的硬件架构恰好能以一种高效、低成本的方式实现BiSS主机使其综合性价比凸显。对我这个项目而言需要偶尔读取编码器内部温度值进行过热保护双向通信且预算有限BiSSXMC4000软方案的组合就成了不二之选。这套驱动代码已经过实际项目验证稳定运行了上千小时。如果你也需要在XMC4000上连接BiSS编码器希望这个开源项目能成为你坚实的起点节省你从零摸索的时间。
返回列表