有关AutoSar中对于Icu模块的相关描述可参考:Autosar MCAL-ICU输入捕获_autosar icu-优快云博客
配置Icu模块前,需要根据需求确定被采集信号的类型、频率和采样精度。Icu采集Pwm号常用类型有测量频率占空比和边沿触发中断两种。
- 测量频率占空比
即通过在任务重不断调用GetDutyCycleValues( )来获取信号的频率(周期)和占空比。需要确定的是被采集信号的的频率和采集周期值、占空比的精度。
- 边沿触发中断
即信号的边沿(上升沿、下降沿)会触发中断回调函数,可根据触发的是上升沿还是下降沿来在回调函数中做进一步的控制操作。需要确定的是触发边沿的类型。
与配置Pwm通道相同,配置Icu通道也需要确定使用的定时器和通道,以及配置Mcu时钟参考点。同时还要确认触发类型和触发源。

形如TC1_81_TR1使用的通道为TCPWM1_81的第二个触发源
形如TC1_M_3_TR0使用的通道为TCPWM1_259的第一个触发源 (259 = 256 + 3)
1. Port配置

TR_ONE_CNT表示ICU通道使用的是OneToOne触发源,其中1指的的定时器TCPWM1。每个定时器通道有2个触发源。
244 = 81 * 3+1
表示复用的是定时器1通道81的第二个OneToOne触发源。(如果是243代表复用的是通道81的第一个触发源)
2. Mcu时钟参考点配置
使用TCPWM通道,需在Mcu模块中配置PCLK和时钟参考点,可参考(四)PWM模块配置

选择使用的定时器和通道,引用Mcu中配置好的时钟参考点,定时器时钟频率(即采样频率)可自动生成,等于引用的时钟参考点频率。
3. 测量频率占空比模式配置

- IcuMeasurementMode:配置ICU测量模式为信号测量模式。
- IcuDefaultStartEdge :配置信号的默认周期起始边沿。

- IcuOverflowNotification:是否配置定时器溢出通知回调函数。

- IcuInputTriggerSelection:选择Port模块中配置复用的触发源。

- IcuSignalMeasurementProperty:测量属性配置为测量周期占空比。
4. 边沿触发中断模式配置

- IcuMeasurementMode:配置ICU测量模式为信号边沿检测模式。
- IcuDefaultStartEdge :配置信号检测边沿类型。

- IcuInputTriggerSelection:选择Port模块中配置复用的触发源。

- IcuSignalNotification:开启并配置通知回调函数名称。
5.使用示例
5.1 测量频率占空比
初始化
void bsp_Init_1(void)
{
Mcu_Init(&McuConf_McuModuleConfiguration_McuModuleConfiguration_0);
Mcu_SetMode(McuConf_McuModeSettingConf_McuModeSetting_CM7_0_Active);
Mcu_InitClock(McuConf_McuClockSettingConfig_McuClockSettingConfig_Active);
while(Mcu_GetPllStatus() != MCU_PLL_LOCKED)
{
}
Mcu_DistributePllClock();
Port_Init(&PortConf_PortConfigSet_PortConfigSet_0); /* PORT 初始化 */
Icu_Init(&IcuConf_IcuConfigSet_IcuConfigSet_0 ); /* ICU 初始化*/
/*开启ICU通道测量*/
Icu_StartSignalMeasurement(IcuConf_IcuChannel_IPWM07);
/* Gpt 初始化,开启10ms中断函数 */
Gpt_Init(&GptConf_GptChannelConfigSet_GptChannelConfigSet_0);
Gpt_EnableNotification(GptConf_GptChannelConfiguration_Timer_16bit_1kHz);
Gpt_StartTimer(GptConf_GptChannelConfiguration_Timer_16bit_1kHz, 10-1);
}
在10ms中断函数中调用(调用的频率要根据配置的ICU定时器频率而定,既要确保采集时间大于信号周期,又要防止定时器计数值溢出)
void Gpt_Notification_Timer_16bit_1KHz(void)
{
Icu_GetDutyCycleValues(IcuConf_IcuChannel_IPWM07, &stDutyCycleValue);
}
返回的stDutyCycleValue结构体类型为
/** \brief Type which shall contain the values, needed for calculating duty cycles. */
typedef struct
{
/* This shall be the coherent active-time measured on a channel. */
Icu_ValueType ActiveTime;
/* This shall be the coherent period-time measured on a channel. */
Icu_ValueType PeriodTime;
} Icu_DutyCycleType;
分别为32位的有效电平时间和周期时间。通过这两个参数计算周期值和频率值
/* FACTOR: 0.1% */
u16DutyRatio = (uint16)((uint32)(stDutyCycleValue.ActiveTime * 1000u) / stDutyCycleValue.PeriodTime); /* PRQA S 4391 */
/* FACTOR: 1Hz */
u16Frequence = (uint16)(CDDIcu_ConfigValue.stCfgParaOfIcuHw[u8ChnIndex].u32Clock / (stDutyCycleValue.PeriodTime));
即测量到的占空比(单位0.1%)= ActiveTime * 1000 / PeriodTime
测量到的频率(单位Hz) = 定时器时钟频率 / PeriodTime
5.2边沿触发中断
初始化
void bsp_Init_1(void)
{
Mcu_Init(&McuConf_McuModuleConfiguration_McuModuleConfiguration_0);
Mcu_SetMode(McuConf_McuModeSettingConf_McuModeSetting_CM7_0_Active);
Mcu_InitClock(McuConf_McuClockSettingConfig_McuClockSettingConfig_Active);
while(Mcu_GetPllStatus() != MCU_PLL_LOCKED)
{
}
Mcu_DistributePllClock();
Port_Init(&PortConf_PortConfigSet_PortConfigSet_0); /* PORT 初始化 */
Icu_Init(&IcuConf_IcuConfigSet_IcuConfigSet_0 ); /* ICU 初始化*/
/*使能边沿触发和通知函数*/
Icu_EnableEdgeDetection(IcuConf_IcuChannel_IPWM17);
Icu_EnableNotification(IcuConf_IcuChannel_IPWM17);
}
开启定时器中断
/*设置中断向量*/
Cy_SysInt_SetSystemIrqVector((cy_en_intr_t)tcpwm_1_interrupts_81_IRQn,Icu_Isr_Vector_516_Cat1);
/*配置中断寄存器*/
Cy_SysInt_InitIRQ( &(cy_stc_sysint_irq_t){ .sysIntSrc=(cy_en_intr_t)tcpwm_1_interrupts_81_IRQn, .intIdx = CPUIntIdx3_IRQn, .isEnabled = true});
/*开启NVIC中断*/
NVIC_EnableIRQ(CPUIntIdx3_IRQn);
在回调函数中设置变量++来测试是否触发了中断
FUNC(void, CDDICU_CODE) McalApp_CallBackISR_RtFrtHideDrHandle(void)
{
IPWM17_Notify++;
}

被折叠的 条评论
为什么被折叠?



