1. 配置对应的Port
将硬件对应Port 配置成GPIO输入即可
2. 根据PORT找到对应的TIN号
这里是TIN109
3. 根据TIN号选择TIM 通道
在手册TIM模块中,找到对应的TIN通道号,确定允许映射的TIM通道,注意在手册中包含多种封装的映射表,请首先确认映射表的封装是否正确
4. TIM时钟源配置
TIM的时钟源来自于CMU_CLK,同时通过CLK_SEL进行分频。
一共有8种分频选择
4.1 TIM时钟源频率计算
TIM属于GTM模块,整个GTM模块的时钟是有CMU分配,同时GTM模块的时钟源一共有两个来源
- GTM
- SPB
GTM 与SPB的时钟定义在MCU模块
根据配置可知,GTM SPB的时钟频率都是100M
在查看CMU的配置,CMU选择了CMU_CLOCK_0作为时钟,因此CMU_CLK的时钟频率为100M/(15+1)
TIM对应通道的时钟分频是CLOCK_0,因此最终的时钟频率是6.25M
5. ICU配置
ICU配置,只需要选择对应的边沿以及测量模式,同时关联对应的TIM通道
6. 实现代码
截取部分代码如下
void IoHwAb_Icu_MainFcuntion(void)
{
Icu_ChannelType eChannel = {0,0};
Icu_17_GtmCcu6_InputStateType eInputState = ICU_IDLE;
IoHwAb_Icu_SampleParamType ChannelSampleParam = {0,0};
Icu_17_GtmCcu6_DutyCycleType DutyCycle = {0x0};
uint8 *pChannelState =0;
uint8 *pIdleCnt = 0;
QueueStructType *pQueuePtr = NULL_PTR;
Icu_Queue_EleType *pChannelSampleParam = NULL_PTR;
for (uint8 uiChCnt =0; uiChCnt<IoHwAb_Icu_Channel_MAX; uiChCnt++)
{
pChannelState = &g_FsmStateGroup[uiChCnt]; /* 获取通道的工作状态 */
eChannel = g_IcuChannelTbl[uiChCnt]; /* 获取ICU通道号 */
pIdleCnt = &Icu_ChannelIdleCnt[uiChCnt];
pQueuePtr = &Icu_ChannelFilterQueue[uiChCnt];
pChannelSampleParam = &g_ChannelSampleParam[uiChCnt];
switch (*pChannelState)
{
case 0: /* IDLE */
Icu_17_GtmCcu6_StartSignalMeasurement(eChannel.Icu_Channel);
*pChannelState = 1;
break;
case 1: /* 开始采集 */
eInputState = Icu_17_GtmCcu6_GetInputState(eChannel.Icu_Channel);
if(eInputState == ICU_ACTIVE)
{
*pChannelState = 2; /* 激活状态,获取采集结果*/
(*pIdleCnt) = 0;
}
else
{
(*pIdleCnt)++;
if(*pIdleCnt >= ICU_IDLE_MAX)
{
*pIdleCnt = ICU_IDLE_MAX;
ChannelSampleParam.uiDuty = (uint16)Dio_ReadChannel(eChannel.Dio_Channel)*1000;
ChannelSampleParam.uiFreq = 0;
Icu_Queue_Push(pQueuePtr,ChannelSampleParam);
*pChannelSampleParam = IoHwAb_Icu_GetQueueFilterResult(pQueuePtr);
}
}
break;
case 2: /* 检测采集是否完成 */
Icu_17_GtmCcu6_GetDutyCycleValues(eChannel.Icu_Channel, &DutyCycle);
if(DutyCycle.PeriodTime !=0)
{
ChannelSampleParam.uiFreq = ICU_CLOCK_FREQ/DutyCycle.PeriodTime;
ChannelSampleParam.uiDuty = ((float)(DutyCycle.ActiveTime))/((float)(DutyCycle.PeriodTime))*1000;
Icu_Queue_Push(pQueuePtr,ChannelSampleParam);
}
*pChannelState = 3;
break;
case 3:
Icu_17_GtmCcu6_StopSignalMeasurement(eChannel.Icu_Channel);
*pChannelSampleParam = IoHwAb_Icu_GetQueueFilterResult(pQueuePtr);
*pChannelState = 0;
break;
default:
*pChannelState = 0;
break;
}
}
}