该模式仅可使用TCPWM作为外部资源。
该模式本质上是在边沿检测中断里将Counter寄存器值循环记录到预先设置的buffer。
MCAL 配置
Port配置
Icu配置
配置时间戳回调通知:
配置中断
对于有Os的系统是在Os中配置,本篇不介绍。
对于没有Os的系统,可使用Cypress官方提供的SDL库实现,以下是实现代码:
#define MCAL_PROJECT_CB_BUTTON_ICU_IRQ_NUMBER 277
#define MCAL_PROJECT_CB_BUTTON_ICU_IRQ_HANDLER Icu_Isr_Vector_277_Cat2
//开中断
Cy_SysInt_SetSystemIrqVector((cy_en_intr_t)MCAL_PROJECT_CB_BUTTON_ICU_IRQ_NUMBER, MCAL_PROJECT_CB_BUTTON_ICU_IRQ_HANDLER);
Cy_SysInt_InitIRQ( &(cy_stc_sysint_irq_t) { .sysIntSrc = (cy_en_intr_t)MCAL_PROJECT_CB_BUTTON_ICU_IRQ_NUMBER, .intIdx = CPUIntIdx3_IRQn, .isEnabled = true } );
NVIC_EnableIRQ(CPUIntIdx3_IRQn);
代码
初始化
//初始化ICU模块
Icu_Init(&IcuConf_IcuConfigSet_IcuConfigSet_0);
//时间戳模式初始化
Icu_StartTimestamp(IcuConf_IcuChannel_IcuChannel_0,&icuTime,1,1);
Icu_EnableNotification(IcuConf_IcuChannel_IcuChannel_0);//必须使能才能触发IcuTimestampNotification回调。
其中Icu_StartTimestamp(); 的 NotifyInterval 参数解释:
NotifyInterval = x 表示每捕捉到x次边沿(x次中断),触发一次用户通知的回调,即图中IcuTimestampNotification 配置的函数。
中断回调处理:
Icu_ValueType icuTime;
Icu_ValueType icuTimeLast=0,icuTimeMeas=0;
void IcuTimestampNotification_0(void)
{
if (icuTime > icuTimeLast)
{
icuTimeMeas = icuTime - icuTimeLast;
}
else
{
icuTimeMeas = icuTime + 65536 - icuTimeLast;
}
icuTimeLast=icuTime;
}
可选使用DMA实现
要点
使能对应DMA
The ICU Driver’s environment must guarantee that DMA is enabled (DW:CTL:ENABLED=1) when DMA is used. The ICU Driver cannot access the global register (i.e.,DW:CTL:ENABLED bit) directly because this setting affects other modules that access to the same register.
使用DMA时,ICU驱动程序的环境必须保证已启用DMA(DW:CTL:ENABLED = 1)。 ICU驱动程序无法直接访问全局寄存器(即DW:CTL:ENABLED位),因为此设置会影响访问同一寄存器的其他模块。
配置Trigger MUX
对照Trigger Multiplexer复用关系图,将要启用DMA的外设连接到对应的DMA通道。如果使能了dma完成中断则还需要初始化中断。
Icu配置有所不同
需要勾选DMA并配置通道:
注意:使能DMA后,IcuTimestampNotification 无需使能,即使使能了也并不会进入。
代码
/**************/
/* Interrrupt */
/**************/
/* Int1 -> DW0-ch.8 */
stc_sysint_irq_cfg.sysIntSrc = cpuss_interrupts_dw0_8_IRQn;
stc_sysint_irq_cfg.intIdx = CPUIntIdx3_IRQn;
stc_sysint_irq_cfg.isEnabled = true;
Cy_SysInt_InitIRQ(&stc_sysint_irq_cfg);
Cy_SysInt_SetSystemIrqVector(stc_sysint_irq_cfg.sysIntSrc, Icu_DwIsr_Vector_160_Cat2);
NVIC_EnableIRQ(CPUIntIdx3_IRQn);
//ICU
Cy_PDMA_Disable(DW0);//DMA
Icu_Init(&IcuConf_IcuConfigSet_IcuConfigSet_0);
Icu_StartTimestamp(IcuConf_IcuChannel_IcuChannel_0, icuTime, 100, 1);//时间戳模式
Cy_PDMA_Enable(DW0);//DMA
/***************/
/* Trigger MUX */
/***************/
Cy_TrigMux_Connect((TRIG_IN_MUX_3_TCPWM_16_TR_OUT03 & 0xFFF),
(TRIG_OUT_MUX_3_PDMA0_TR_IN8 & 0xFFF),
0u,
TRIGGER_TYPE_CPUSS_DW0_TR_IN__LEVEL,
1u);