-
- 问题描述
某用户使用MC03,MCAL驱动,问题背景及软件逻辑:
- ICU模块捕获一个周期约5ms,占空比范围10%~90%的脉冲
- 10ms task中调用Icu_GetInputState获取到ICU_ACTIVE状态后调Icu_GetDutyCycleValues获取占空比
[Image]
客户问题:
实车测试时某辆车出现过持续200ms(约40个正常脉冲周期)时间内以10ms周期查询ICU状态,其状态均为ICU_IDLE的情况,导致这段时间内应用层拿不到占空比数据。
https://yt-micro.feishu.cn/wiki/UNgEwEX2RiHXDJkbKVQc62SCnTe
- 问题定位
函数Icu_Lld_Etmr_SignalMeasurementHandle()中的条件:
- 检测到TOF中断标志置位时置ICU_IDLE
- 检测到(CVAL<2000)||((MOD-CVAL)<2000)时置ICU_IDLE
用于处理以下可能出现的测量场景,目的是丢弃占空比可能计算不准的采样周期/占空比。
(一)用户配置overflow中断优先级高于InputCapture中断
假设代码中全局中断被关闭时,几乎同一时刻先来了一个脉冲边沿,后产生一个overflow中断,此时两个中断均处于pending状态。全局中断开启后先响应overflow中断,overflowtimes加1,再响应InputCapture中断进行占空比计算,此时会得到一个错误的计算值,故通过(CVAL<2000)||((MOD-CVAL)<2000)条件丢弃采样边沿靠近overflow位置处的计算。
(二)用户配置InputCapture中断优先级高于overflow中断
几乎在同一时刻产生脉冲边沿和overflow中断时,先响应InputCapture中断,查询到TOF标志后表示TOF中断还未正常响应(原因是overflow中断累加一次overflowtimes后会把TOF标志清0),overflowtimes未正常加1,此时会得到一个错误的计算值,故通过查询TOF标志丢弃本周期计算。
但是 overflow 边界过滤条件使用的是固定 tick 阈值2000。这个固定值没有考虑McuClockReferencePointFrequency、ETMR 时钟源、ETMR 分频系数等因素。
因此在不同工程、不同时钟配置下,同样的2000U对应的真实时间窗口并不一致,容易导致某些频率 / 占空比组合下的正常测量被丢弃,使InputState长时间保持ICU_IDLE,导致测量连续性较差。- 修改方案
缩短过滤的时间窗口,将固定 tick 阈值改为固定时间窗口,并根据当前 ETMR 时钟配置自动换算成 ETMR tick。
3.1 整体方案
- 在
Icu配置中增加可配置的保护时间参数。 - 在代码生成阶段将保护时间换算成 tick。
- 在
Icu_Lld_Etmr.c中使用生成出来的 tick 值替换原来的固定2000U。
3.2 新增Guard Time 配置项
在Icu配置界面的IcuGeneral新增配置项IcuGeneral.IcuEtmrMc0CaptureGuardTimeUs,用户可以自定义时间窗口。
配置规则:- 仅在 MC0 工程中显示
- 默认值为
2us - 取值范围为
1 ~ 1000us
3.3 Tick 生成逻辑
在 Icu_Cfg.h.hbs 模板中先计算guardTicks,最后只输出一次最终宏:
#define ICU_ETMR_MC0_CAPTURE_GUARD_TICKS (...)
时钟选择逻辑如下:- 当 IcuEtmrClockSource = INTERNAL_FASTBUSCLK
- 使用 IcuEtmrMcuClockReferencePoint 对应的 McuClockReferencePointFrequency
- 当 IcuEtmrClockSource = EXTERNAL_CLOCK
- 使用固定 24 MHz
tick 换算公式如下:
guard_ticks = ceil(guard_time_us * etmr_clock_hz / ((IcuEtmrPrescaler + 1) * 1000000))
其中:
- 使用固定 24 MHz
- guard_time_us = IcuGeneral.IcuEtmrMc0CaptureGuardTimeUs
- etmr_clock_hz = ETMR 实际输入时钟
- IcuEtmrPrescaler + 1 = ETMR 实际分频系数
3.4 驱动侧修改
在 Icu_Lld_Etmr.c 中,原来的 MC0 ETMR 不稳定样本过滤条件:
(CurrentChannelCval < 2000U) || ((ChannelPeriodTime - CurrentChannelCval) < 2000U)
修改为:
(CurrentChannelCval < CaptureGuardTicks) ||
((ChannelPeriodTime - CurrentChannelCval) < CaptureGuardTicks)
其中:
CaptureGuardTicks = ICU_ETMR_MC0_CAPTURE_GUARD_TICKS;- 修改验证
在overflow 边界过滤条件中进行Dio电平翻转,测试在相同时间内,修改后的代码的测量被丢弃的次数明显减少,测量连续性变好。
输入信号247hz 10%占空比波形
修改前:

修改后:

- 总结
修改方案的本质是将原来固定的 2000 tick overflow 边界过滤阈值,改为一个可配置的时间窗口,并在代码生成阶段自动换算成 ETMR tick。这样可以让 MC0 ETMR 信号测量路径中的边界保护逻辑更加稳定、可配置,并且更适应不同的时钟设置。
- 问题描述
-
Y yt0069 从 MCAL BUGS 移动了该主题
快速上手云途开发生态
发帖前请查看
帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...