云途LE_etmr输入捕获介绍
GaoSheng Lv4

云途LE系列MCU,只需要单通道就可以实现信号的周期和占空比的捕获。其中有三个etmr模块,都是16位,通道个数8+8+2.每个etmr模块均可以用作输入捕获
image
当捕获事件发生时,需记录边沿处的etmr计数器值,在整个捕获过程完成后,将相应的计数器的值做减法,就可以得到捕获的周期和占空比

  1. 根据pinMux表选择pin脚,将期配置成输入捕获模式
  2. 使能etmr IPC时钟
  3. 配置etmr 时钟频率,选择时钟源和分频,eTmr默认使用fast bus clock
  4. 配置输入捕获的边沿以及数字滤波器,边沿有上升沿,下降沿和双边沿,当捕获信号的宽度小于滤波器的带宽时,就被忽略
  5. 配置捕获使用的eTmr计数器的最大值。建议:对于16位eTmr,最大值是0xffff

举例说明:如果使用 eTMR0 通道 1 来捕获,快速总线时钟 48MHz,分频选 48,则捕获时钟频率为 1MHz。假如捕获所得的计数器值是 1000,那么捕获到的信号周期就是 1 毫秒。因为 eTMR0 计数器是 16 位,最大值 0xFFFF,意味着通道1 有能力去捕获 65ms 宽度的 PWM 波。

使用云途的YCT工具可以生成eTmr捕获demo->Etmr_Input_Capture_Demo
image
etmr时基配置:

1
2
3
4
5
6
7
8
etmr_user_config_t ETMR_CM_Config1={
.etmrClockSource=eTMR_CLOCK_SOURCE_INTERNALCLK,//使用内部时钟(快速总线时钟)
.etmrPrescaler=24,//设置分频器
.debugMode=false,//调试模式下暂停,计数器停止计数
.syncMethod=&ETMR_CM_Config1PwmSync,
.outputTrigConfig=&ETMR_CM_Config1TrigConf,//输入捕获不需要触发器配置,此处可填 NULL
.isTofIntEnabled=false//禁止计数器溢出中断
};

输入捕获通用配置结构体

1
2
3
4
5
etmr_ic_param_t ETMR_IC_Config0={
.numChannels=2,//捕获所用总通道数
.countValue=65535,//捕获计数最大值
.inputChConfig=ETMR_IC_Config0InputCh,//捕获通道具体参数
};

捕获通道参数结构体 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
etmr_ic_ch_param_t ETMR_IC_Config0InputCh[2]={
{
.hwChannelId=0,//输入通道编号
.edge=eTMR_DUAL_EDGES, ///捕获边沿类型
.measurementType=eTMR_PERIOD_MEASUREMENT,
.filterSampleCounter=0,
.filterSamplePeriod=0,
.interruptEnable=true,
.dmaEnable=false,
.enableNotification=false,
.channelsCallbacks=NULL,
.channelsCallbacksParams=NULL,
},
{
.hwChannelId=1,//输入通道编号
.edge=eTMR_DUAL_EDGES,//捕获边沿类型
.measurementType=eTMR_PERIOD_MEASUREMENT,
.filterSampleCounter=0,
.filterSamplePeriod=0,
.interruptEnable=true,
.dmaEnable=false,
.enableNotification=false,
.channelsCallbacks=NULL,
.channelsCallbacksParams=NULL,
},
};

获取eTmr的状态结构体中获取捕获结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
typedef struct
{
etmr_clock_source_t etmrClockSource; /*!< Clock source used by eTMR counter 使用的时钟源 */
uint32_t etmrSourceClockFrequency; /*!< The clock frequency is used for counting 时钟频率 */
etmr_channel_state_t etmrChnMode[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< Mode of operation for eTMR 使用的操作模式*/
uint32_t etmrPeriod; /*!< This field is used only in PWM mode to store signal period PWM周期值,仅在PWM模式下有效 */
uint32_t etmrModValue; /*!< This field is used only in input capture mode to store MOD value */
etmr_pwm_update_option_t typeOfUpdate[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< Type of update for PWM update */
etmr_pwm_align_mode_t alignMode[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< Align mode of PWM update */
uint32_t dutyCycle[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< Duty cycle of PWM update */
uint32_t offset[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< Offset of pulse for asymmetric mode */
etmr_ic_measurement_type_t measurementType[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< Measurement type */
etmr_ic_capture_edge_t captureEdge[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< Input capture edge */
uint8_t icOvfCnt[FEATURE_eTMR_CHANNEL_MAX_COUNT][CAPTURE_COUNT]; /*!< eTMR channel capture overflow count */
uint8_t icOvfCntTemp; /*!< eTMR overflow count */
uint8_t icCnt[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< Count of enter into input capture interrupt */
uint8_t icCapPol[FEATURE_eTMR_CHANNEL_MAX_COUNT][CAPTURE_COUNT]; /*!< eTMR channel capture polarity */
uint32_t icCntVal[FEATURE_eTMR_CHANNEL_MAX_COUNT][CAPTURE_COUNT]; /*!< eTMR channel capture value */
uint32_t measurementPeriod[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< Store period */
uint32_t measurementPosPulseCnt[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< Positive pulse count value */
uint32_t measurementNegPulseCnt[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< Negative pulse count value */
uint32_t measurementCapCnt[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< Store capture value */
bool measurementComplete[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< eTMR input capture measurement complete signal */
void *channelsCallbacksParams[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< The parameters of callback function 回调函数参数*/
ic_callback_t channelsCallbacks[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< The callback function 回调函数*/
bool enableNotification[FEATURE_eTMR_CHANNEL_MAX_COUNT]; /*!< The notification on the callback application 回调通知标志*/
} etmr_state_t;

SDK 捕获相关函数可以在etmr_ic_driver.c找到
image

下面的 ECU_InCapGetValAndPol() 函数是使用示例,它调用了上面的某些函数,可以实现对输入信号周期和占空比的捕获,描述如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void ECU_InCapGetValAndPol(uint32_t InCapNo, uint32_t *duty, uint32_t *period, uint8_t *firstcap_polarity)
{
uint8_t inputed_num;
uint8_t etmr_num, channel_sn;
uint8_t *firstcap_polarity_temp;
uint32_t *duty_temp, *period_temp;
duty_temp = duty;
period_temp = period;
firstcap_polarity_temp = firstcap_polarity;
/* 将 InCapNo 转换成 eTMR instance 号和捕获通道 ID */
inputed_num = InCapNo;
etmr_num = inputed_num / 8;
channel_sn = inputed_num % 8;
/* 检查整个信号的捕获过程有没有完成 */
if(etmrStatePtr[etmr_num]->measurementComplete)
{
/* 清捕获完成标志 */
etmrStatePtr[etmr_num]->measurementComplete = false;
/* 读取捕获的信号占空比 */
*duty_temp = eTMR_DRV_GetInputCaptureMeasurementDuty(etmr_num, channel_sn);
/* 读取捕获的信号周期 */
*period_temp = eTMR_DRV_GetInputCaptureMeasurementPeriod(etmr_num, channel_sn);
/* 读取第一次捕获的信号极性 */
*firstcap_polarity_temp = eTMR_DRV_GetInputCaptureFirstDutyLevelPol(etmr_num);
/* 清捕获中断进入次数,为下一次整个信号的捕获做准备 */
eTMR_DRV_ClearInputCaptureCount(etmr_num);
} }

补充一个YTM中的同步机制
eTMR为一些同计数相关的寄存器设计了缓冲寄存器(Buffered Registers),或者被称为“影子寄存器”(Shadow Registers)。影子寄存器对用户来说是不可见的。当启用影子模式后(eTMR_SYNC[REGLD] != 0),用户通过APB总线向拥有影子寄存器的真实寄存器中写数时,实际由硬件控制先写到影子寄存器中,当预设的同步触发信号到来之时,硬件自动将影子寄存器中的数值写入到实际的寄存器中生效。如下图所示。
image


https://mp.weixin.qq.com/s/b4z5IHIf_Wt7YAfEf8CmWQ
《AN0048_LE0_etmr_input_capture_zh_review》

本站由 提供部署服务