【Autosar】MCAL - ICU(NXP - S32K14x)

MCAL - ICU(NXP - S32K14x)

MCAL - 汇总

  • 配置工具:EB Tresos Studio
  • 芯片类型:S32K146

1. 概述

ICU(Input Capture Unit)输入捕获的作用是监测输入信号的边沿跳变,以此来测量输入信号的频率、占空比、高/低电平持续时间。

1.1 FlexTimer模块ICU介绍

1.1.1 输入捕获工作原理

输入捕获模块监测输入信号(channel input),通过边沿监测模块将捕获到的信号与设定的监测边沿(上升沿/下降沿)比较,如果匹配则将当前的FTM Counter值存到Cnv中并且触发中断,此时用户可以读取并记录Cnv值。

例如我设置的是上升沿捕获,FTM时钟频率为1MHz,第一次触发时程序记录Cnv值为1000,第二次触发时记录Cnv值为2000,此时可以计算信号周期period = (2000-1000) * 1000 / 1000000 = 1ms = 1KHz

在这里插入图片描述

捕获边沿可以设置为上边沿/下边沿/双边沿,通过设置ELSB/ELSA来设定。双边沿是触发任意一个都会记录并触发中断,这种情况下可以计算输入信号的占空比。

在这里插入图片描述

1.1.2 过滤器

输入捕获模块配有滤波器(用户开启),输入信号的稳定时间需要满足规定采样时间,才会将信号传给边缘边沿,否则信号将被过滤。过滤器的采样时间如下图所示:

在这里插入图片描述

过滤器的采样时间参考下图:

在这里插入图片描述

1.1.3 双边沿捕获工作原理

Dual Edge Capture Mode - 双边沿捕获 。在这种模式下,只有一路输入,但是有2路通道进行捕获,多了一路通道用于记录数据,可以很方便的监测信号的占空比和周期。例如将通道0配置为上升沿捕获、通道1配置为下降沿捕获,当监测到上升沿时数据记录到C0V中,捕获到下降沿时数据记录到C1V中,我们可以使能通道1的 中断,当通道1中断触发后,可以通过C1V-C0V得到占空比,当再次触发后,利用当前值和历史值去计算周期(NXP处理方式))。
注意此模式只能用于偶数通道:0、2、4、6

在这里插入图片描述

S32K-RM中对配置有一个说明:在双边沿监捕获模式下,通道需要配置为上升沿或下降沿捕获(在此处我并没有看到允许配置为1:1)。当两个通道配置不同,一个上升沿,一个下降沿时,可以监测占空比。当两个通道配置相同时,可以监测周期。

在这里插入图片描述

对于CnV和C(n+1)V的读取,S32K参考手册的Read coherency mechanism中有介绍:注意数据读取的时候要先读取C(n)V再去读取C(n+1)V

在这里插入图片描述

2. API

函数描述
Icu_InitICU模块初始化
Icu_DeInitICU模块恢复至默认状态
Icu_SetActivationCondition设置触发边沿
Icu_EnableNotification使能中断回调
Icu_DisableNotification禁用中断回调
Icu_StartTimestamp开始时间戳模式
Icu_StopTimestamp停止时间戳模式
Icu_GetTimestampIndex获当前时间戳序号
Icu_StartSignalMeasurement开始信号测量
Icu_StopSignalMeasurement停止信号测量
Icu_GetDutyCycleValues获取占空比、周期值

3. 配置介绍

3.1 IcuChannel

3.1.1 General

在这里插入图片描述

IcuHwIP:硬件模块选择

IcuFtmChannelRef:硬件模块选择了FTM,此处就要打开并且选择对应的FTM通道(LPIT/PORT/LPTMR 同理)

IcuDefaultStartEdge:默认开始捕获边沿(例如选择上边沿,那么只有监测到上边沿才会开始测量,配置的是ELSB/ELSA寄存器)

IcuMeasurementMode:测量模式

IcuOverflowNotification:溢出中断回调

3.1.2 IcuSignalEdgeDetection

当测量模式选择ICU_MODE_SIGNAL_EDGE_DETECT的时候需要打开。

在这里插入图片描述

IcuSignalNotification:中断回调

3.1.3 IcuSignalMeasurement

当测量模式选择ICU_MODE_SIGNAL_MEASUREMENT的时候需要打开。

在这里插入图片描述

IcuSignalMeasurementProperty:信号测量方式(占空比、周期、高电平时间、低电平时间)

3.1.4 IcuTimestampMeasurement

当测量模式选择ICU_MODE_TIMESTAMP的时候需要打开。

在这里插入图片描述

IcuTimestampMeasurementProperty:时间戳测量方式(回环、线性)

IcuTimestampNotification:中断回调

3.2 IcuFtm

3.2.1 Ftm Modules

在这里插入图片描述

Ftm Hardware Module:FTM模块选择

ICU FlexTimer Prescaler:FTM时钟分频系数

IcuFlexTimer Clock source:时钟源选择

3.2.2 IcuFtmChannels

在这里插入图片描述

Ftm Channel:FTM通道选择

3.3 IcuHwInterruptConfigList

中断使能配置,根据对应的通道配置选择对应的中断。

在这里插入图片描述

3.4 捕获模式介绍

3.4.1 时间戳

时间戳测量方式:

  1. ICU_CIRCULAR_BUFFER:回环,数据存满后从0开始继续存储
  2. ICU_LINEAR_BUFFER:线性,数据存满后测量停止。
    在这里插入图片描述

时间戳模式下可以设置NotifuInterval参数。此参数的意义在于存储了指定个数的数据后再通知用户,例如我设置NotifuInterval为2,当触发了2次中断 存储了两个数据后,会触发一次回调通知,此时通过Icu_GetTimestampIndex函数可以获取到当前存储位置为2(此处大家可能会有疑问,存储了两个数据后,当前的序号不应该是1吗,由于存储完数据后,Index会先增加1,再去调用回调函数,所以是2),所以每次触发后,获取的index-1才是当前的存储位置。因此这里会存在一个问题,例如上图当第三次触发回调的时候,此时缓存位置是5,但是获取的index由于超出最大缓存范围了,获取到的是0,所以这里需要做过零点处理。

void icu_test_init(void)
{
	Icu_Init(&Icu_Config);
	INT_SYS_EnableIRQ(FTM0_Ch0_Ch1_IRQn);
	Icu_EnableNotification(0);
	Icu_StartTimestamp(0, icu_buffer, sizeof(icu_buffer) / sizeof(icu_buffer[0]), 2);
}

void Icu_channel0_notify(void)
{
	uint16_t index = 0;

	index = Icu_GetTimestampIndex(0);

	if(index == 0 )
	{
		index = sizeof(icu_buffer) / sizeof(icu_buffer[0]);
		return;
	}

	index -= 1;

	if(icu_buffer[index] > icu_buffer[index - 1])
	{
		printf("%d%\r\n", (icu_buffer[index] - icu_buffer[index - 1]) * 100 / 10000);
	}
	else
	{
		printf("%d%\r\n", (65535 - icu_buffer[index - 1]  + icu_buffer[index]) * 100 / 10000);
	}
}

3.4.2 信号测量(ICU_DUTY_CYCLE)

该模式是通过FTM双边沿捕获模式实现。

NXP对于该测量方式的实现逻辑如下图所示,开始测量时,使能通道n,触发中断保存CnV的值①(注意假设此时捕获的是上升沿),此时重新配置通道(通道n设置为下降沿捕获,通道n+1设置为上升沿捕获)并且关闭通道n中断,打开通道n+1的中断,当通道n+1中断触发后,同时获取Cnv的值②和C(n+1)V的值③,然后通过②-①得到占空比的值,通过③-①得到周期值,然后将③的值更新到历史值中。当通道n+1再次触发的时候是在⑤的位置,重复上述操作。

在这里插入图片描述

void icu_test_init(void)
{
	Icu_Init(&Icu_Config);
	INT_SYS_EnableIRQ(FTM0_Ch0_Ch1_IRQn);
	Icu_EnableNotification(0);
	Icu_StartSignalMeasurement(0);
}

// 此函数在周期任务中调用
void Icu_get_duty_period(void)
{
	float duty = 0;
	Icu_DutyCycleType data = {0};

	Icu_GetDutyCycleValues(0, &data);

	printf("duty:%f%%  period:%f(ms)\r\n", ((float)data.ActiveTime * 100 / data.PeriodTime),
											((float)data.PeriodTime * 1000 / 1000000));
}

3.5 遗留问题

从手册中可以看到,在双边沿模式下,两个通道配置的触发边沿应该是相反的,所以在EB中配置为IcuSignalMeasurement模式下,边沿触发应该选择上升沿或下降沿,不应该选择双边沿(个人理解),但是当我选择为双边沿的时候,两个通道的触发方式都是(ELSA:ELSB = 1:1),它还是能够正常工作,且工作现象与(通道n:上升沿触发 / 通道n+1:下降沿触发)相同,所以这里我没有弄明白,在双边沿捕获模式下,双通道都配置为(ELSA:ELSB = 1:1)的情况下,内部是如何工作的?两者对于输入信号的捕获难道不会冲突吗?

在这里插入图片描述

我这里设置的占空比为30%,实际试验现象与上升沿触发一致

在这里插入图片描述


参考资料:

S32K-RM.pdf - NXP

AUTOSAR_MCAL_ICU_UM[1].pdf - NXP

  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AutoSARAutomotive Open System Architecture)是一种开放式的汽车电子系统架构标准,用于汽车电子控制单元(ECU)软件开发和架构。AutoSAR Update-Bits是AutoSAR架构中用于更新ECU软件的概念。 AutoSAR Update-Bits主要用于在现有的ECU中对软件进行更新和修改。它允许汽车制造商或ECU供应商通过向ECU发送更新数据包来提供新的功能、修复错误或改进现有的软件。这些更新数据包通过AutoSAR Update-Bits的通信机制传输到ECU,并被ECU上的更新管理模块接收和解析。 AutoSAR Update-Bits的更新过程包括以下步骤: 1. 更新数据包准备:汽车制造商或ECU供应商准备包含更新的数据包,并使用AutoSAR的标准规范对其进行打包和编码。 2. 更新数据包传输:更新数据包通过车辆网络,如CAN(Controller Area Network)或FlexRay,传输到目标ECU。 3. 更新管理模块接收:目标ECU上的更新管理模块接收并验证更新数据包的完整性和正确性。 4. 更新数据包解析:更新管理模块将更新数据包解析为可执行代码,并将其存储在ECU的闪存中。 5. 系统重启:ECU完成更新后,它可能需要进行系统重启以使更新生效。 通过使用AutoSAR Update-Bits,汽车制造商和ECU供应商可以在车辆的整个生命周期中对软件进行更新和改进,而无需更换整个ECU。这不仅提供了更灵活和可持续的软件开发和维护方式,还可以显著降低生产成本和减少故障修复时间。 总之,AutoSAR Update-Bits是AutoSAR架构中用于更新ECU软件的机制,它使汽车制造商和ECU供应商能够通过传输和解析更新数据包来增强车辆的功能和安全性,提高软件的可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值