配置步骤
配置内容
生成的配置结构体如下,在Generated_Code路径下的lpTmr.c文件和lpTmr.h文件。
/*! lpTmr1 configuration structure */
const lptmr_config_t lpTmr1_config0 = {.workMode = LPTMR_WORKMODE_PULSECOUNTER,.dmaRequest = false,.interruptEnable = true,.freeRun = false,.compareValue = 1000U,.counterUnits = LPTMR_COUNTER_UNITS_TICKS,.clockSelect = LPTMR_CLOCKSOURCE_SIRCDIV2,.prescaler = LPTMR_PRESCALE_2,.bypassPrescaler = true,.pinSelect = LPTMR_PINSELECT_TRGMUX,.pinPolarity = LPTMR_PINPOLARITY_RISING,
};
只读也就是这个配置结构体前面加个const
工作模式有Timer计时器和Plus counter脉冲计数器两种
计时器的话就是用作普通计时器,脉冲计数器要选择对应的输入引脚和跟一个叫TRGMUX的模块配合使用。脉冲通过输入引脚给到TRGMUX模块,通过配置SEL寄存器选择输出到TMR模块计算脉冲数量。
DMA请求就是产生对比事件的时候请求DMA帮忙搬运下数据,不然的话就是让CPU来搬运。
中断使能是跟工作模式配合起来的。如果是计时器模式,那就是时间到达产生中断,进入中断函数。如果是脉冲计数器模式,就是脉冲到达一定数量的时候,进入中断函数。
这个中断只是允许定时器产生中断,要调用下INT_SYS_InstallHandler安装中断函数,INT_SYS_EnableIRQ使能。
/* Install IRQ handler for LPTMR interrupt */
INT_SYS_InstallHandler(LPTMR0_IRQn, &lptmrISR, (isr_t *)0);
/* Enable IRQ for LPTMR */
INT_SYS_EnableIRQ(LPTMR0_IRQn);
里面的LPTMR0_IRQn是设备名称,定死的。lptmrISR是中断时进入的函数,自己看着来写就行。
自由运行模式千万不要选,计数器会一直累加,溢出都不管。
对比值就是TMR累加到这个值就产生中断,无论工作模式是计数器模式还是脉冲计数器模式。这个是有最大数值限制的,自己看着来。
对比值单位是根据工作模式来的。如果是计时器模式,就选择微秒。如果是脉冲计数器模式,就选择次数。
输入时钟就是时钟源。
如果工作模式是计数器模式,分频数是自动适配的,不用选择引脚和极性。
如果工作模式是计数器模式,就可以选择分频数和滤波模式,并且选择映射到的引脚和极性。
极性就是在上升沿时刻计数还是下降沿时刻计数。
接口使用
会产生lptmr_driver.c文件和lptmr_driver.h文件,路径在SDK\platform\drivers\src\lptmr和SDK\platform\drivers\inc。
LPTMR_DRV_InitConfigStruct
初始化TMR配置结构体,也就是将配置结构体变成默认配置。
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_InitConfigStruct* Description : Initialize a configuration structure with default values.** Implements : LPTMR_DRV_InitConfigStruct_Activity*END**************************************************************************/
void LPTMR_DRV_InitConfigStruct(lptmr_config_t * const config)
{DEV_ASSERT(config != NULL);/* General parameters */config->dmaRequest = false;config->interruptEnable = false;config->freeRun = false;config->workMode = LPTMR_WORKMODE_TIMER;/* Counter parameters */config->clockSelect = LPTMR_CLOCKSOURCE_SIRCDIV2;config->prescaler = LPTMR_PRESCALE_2;config->bypassPrescaler = false;config->compareValue = 0u;config->counterUnits = LPTMR_COUNTER_UNITS_TICKS;/* Pulse Counter specific parameters */config->pinSelect = LPTMR_PINSELECT_TRGMUX;config->pinPolarity = LPTMR_PINPOLARITY_RISING;
}
LPTMR_DRV_Init
初始化函数,入参为TMR序号、配置结构体、是否开始计数。
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_Init* Description : Initialize a LPTMR instance based on the input configuration* structure.** When (counterUnits == LPTMR_COUNTER_UNITS_MICROSECONDS) the function will* automatically configure the timer for the input compareValue in microseconds.* The input parameters for 'prescaler' and 'bypassPrescaler' will be ignored* - their values will be adapted by the function, to best fit the input compareValue* (in microseconds) for the operating clock frequency.** LPTMR_COUNTER_UNITS_MICROSECONDS may only be used for LPTMR_WORKMODE_TIMER mode.* Otherwise the function shall not convert 'compareValue' in ticks* and this is likely to cause erroneous behavior.** When (counterUnits == LPTMR_COUNTER_UNITS_TICKS) the function will use the* 'prescaler' and 'bypassPrescaler' provided in the input configuration structure.** When (counterUnits == LPTMR_COUNTER_UNITS_TICKS), 'compareValue' must be lower* than 0xFFFFu. Only the least significant 16bits of 'compareValue' will be used.* When (counterUnits == LPTMR_COUNTER_UNITS_MICROSECONDS), 'compareValue'* may take any 32bits unsigned value.** Implements : LPTMR_DRV_Init_Activity*END**************************************************************************/
void LPTMR_DRV_Init(const uint32_t instance,const lptmr_config_t * const config,const bool startCounter)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);DEV_ASSERT(config != NULL);LPTMR_Type* const base = g_lptmrBase[instance];LPTMR_DRV_SetConfig(instance, config);/* Start the counter if requested */if (startCounter){LPTMR_Enable(base);}
}
LPTMR_DRV_SetConfig
将配置结构体的配置信息设置到序号里面的TMR当中。
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_SetConfig* Description : Configure a LPTMR instance based on the input configuration* structure.** When (counterUnits == LPTMR_COUNTER_UNITS_MICROSECONDS) the function will* automatically configure the timer for the input compareValue in microseconds.* The input parameters for 'prescaler' and 'bypassPrescaler' will be ignored* - their values will be adapted by the function, to best fit the input compareValue* (in microseconds) for the operating clock frequency.** LPTMR_COUNTER_UNITS_MICROSECONDS may only be used for LPTMR_WORKMODE_TIMER mode.* Otherwise the function shall not convert 'compareValue' in ticks* and this is likely to cause erroneous behavior.** When (counterUnits == LPTMR_COUNTER_UNITS_TICKS) the function will use the* 'prescaler' and 'bypassPrescaler' provided in the input configuration structure.** When (counterUnits == LPTMR_COUNTER_UNITS_TICKS), 'compareValue' must be lower* than 0xFFFFu. Only the least significant 16bits of 'compareValue' will be used.* When (counterUnits == LPTMR_COUNTER_UNITS_MICROSECONDS), 'compareValue'* may take any 32bits unsigned value.** Implements : LPTMR_DRV_SetConfig_Activity*END**************************************************************************/
void LPTMR_DRV_SetConfig(const uint32_t instance,const lptmr_config_t * const config)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);DEV_ASSERT(config != NULL);LPTMR_Type* const base = g_lptmrBase[instance];uint32_t configCmpValue = config->compareValue;lptmr_workmode_t configWorkMode = config->workMode;uint16_t cmpValueTicks = 0U;lptmr_prescaler_t prescVal = config->prescaler;bool prescBypass = config->bypassPrescaler;lptmr_counter_units_t configCounterUnits = config->counterUnits;if(configWorkMode == LPTMR_WORKMODE_TIMER){/* A valid clock must be selected when used in Timer Mode. */uint32_t clkFreq;clkFreq = lptmr_GetClkFreq(config->clockSelect, instance);DEV_ASSERT(clkFreq != 0U); /* Clock frequency equal to '0', signals invalid value. */if(configCounterUnits == LPTMR_COUNTER_UNITS_MICROSECONDS){bool chooseClkConfigStatus;/* When workmode is set to Timer Mode and compare value is provided in microseconds,* then the input parameters for prescale value and prescaleBypass are ignored.* The prescaleValue, prescaleBypass and cmpValue in ticks, are calculated to best fit* the input configCmpValue (in us) for the current operating clk frequency. */chooseClkConfigStatus = lptmr_ChooseClkConfig(clkFreq, configCmpValue, &prescVal, &prescBypass, &cmpValueTicks);DEV_ASSERT(chooseClkConfigStatus == true);(void) chooseClkConfigStatus;}else{DEV_ASSERT(configCounterUnits == LPTMR_COUNTER_UNITS_TICKS);DEV_ASSERT(configCmpValue <= LPTMR_CMR_COMPARE_MASK); /* Compare Value in Tick Units must fit in CMR. */cmpValueTicks = (uint16_t)(configCmpValue & LPTMR_CMR_COMPARE_MASK);}}else{/* If configWorkMode is not LPTMR_WORKMODE_TIMER, then it must be LPTMR_WORKMODE_PULSECOUNTER. */DEV_ASSERT(configWorkMode == LPTMR_WORKMODE_PULSECOUNTER);/* Only LPTMR_COUNTER_UNITS_TICKS can be used when LPTMR is configured as Pulse Counter. */DEV_ASSERT(config->counterUnits == LPTMR_COUNTER_UNITS_TICKS);/* A valid clock must be selected when glitch filter is enabled (prescaler not bypassed). */DEV_ASSERT((lptmr_GetClkFreq(config->clockSelect, instance) != 0u) || prescBypass);/* Glitch filter does not support LPTMR_PRESCALE_2. */DEV_ASSERT(prescBypass || (prescVal != LPTMR_PRESCALE_2));DEV_ASSERT(configCmpValue <= LPTMR_CMR_COMPARE_MASK); /* Compare Value in Tick Units must fit in CMR. */cmpValueTicks = (uint16_t)(configCmpValue & LPTMR_CMR_COMPARE_MASK);}/* Initialize and write configuration parameters. */LPTMR_Init(base);LPTMR_SetDmaRequest (base, config->dmaRequest);LPTMR_SetInterrupt (base, config->interruptEnable);LPTMR_SetFreeRunning (base, config->freeRun);LPTMR_SetWorkMode (base, configWorkMode);LPTMR_SetPrescaler (base, prescVal);LPTMR_SetBypass (base, prescBypass);LPTMR_SetClockSelect (base, config->clockSelect);LPTMR_SetCompareValue (base, cmpValueTicks);LPTMR_SetPinSelect (base, config->pinSelect);LPTMR_SetPinPolarity (base, config->pinPolarity);
}
LPTMR_DRV_GetConfig
获取配置结构体信息
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_GetConfig* Description : Get the current configuration of the LPTMR instance.* Always returns compareValue in LPTMR_COUNTER_UNITS_TICKS.** Implements : LPTMR_DRV_GetConfig_Activity*END**************************************************************************/
void LPTMR_DRV_GetConfig(const uint32_t instance,lptmr_config_t * const config)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);DEV_ASSERT(config != NULL);const LPTMR_Type* const base = g_lptmrBase[instance];/* Read current configuration */config->dmaRequest = LPTMR_GetDmaRequest(base);config->interruptEnable = LPTMR_GetInterruptEnable(base);config->freeRun = LPTMR_GetFreeRunning(base);config->workMode = LPTMR_GetWorkMode(base);config->prescaler = LPTMR_GetPrescaler(base);config->bypassPrescaler = LPTMR_GetBypass(base);config->clockSelect = LPTMR_GetClockSelect(base);config->compareValue = LPTMR_GetCompareValue(base);config->counterUnits = LPTMR_COUNTER_UNITS_TICKS;config->pinSelect = LPTMR_GetPinSelect(base);config->pinPolarity = LPTMR_GetPinPolarity(base);
}
LPTMR_DRV_Deinit
逆初始化
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_Deinit* Description : De-initialize the LPTMR (stop the counter and reset all registers to default value).** Implements : LPTMR_DRV_Deinit_Activity*END**************************************************************************/
void LPTMR_DRV_Deinit(const uint32_t instance)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);LPTMR_Type* const base = g_lptmrBase[instance];LPTMR_Disable(base);LPTMR_Init(base);
}
LPTMR_DRV_SetCompareValueByCount
设置对比值
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_SetCompareValueByCount* Description : Set the compare value in counter tick units, for a LPTMR instance.* Possible return values:* - STATUS_SUCCESS: completed successfully* - STATUS_ERROR: cannot reconfigure compare value (TCF not set)* - STATUS_TIMEOUT: compare value is smaller than current counter value** Implements : LPTMR_DRV_SetCompareValueByCount_Activity*END**************************************************************************/
status_t LPTMR_DRV_SetCompareValueByCount(const uint32_t instance,const uint16_t compareValueByCount)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);LPTMR_Type* const base = g_lptmrBase[instance];status_t statusCode = STATUS_SUCCESS;bool timerEnabled = LPTMR_GetEnable(base);bool compareFlag = LPTMR_GetCompareFlag(base);uint16_t counterVal;/* Check if a valid clock is selected for the timer/glitch filter */
#if (defined (DEV_ERROR_DETECT) || defined (CUSTOM_DEVASSERT))bool bypass = LPTMR_GetBypass(base);lptmr_workmode_t workMode = LPTMR_GetWorkMode(base);(void) bypass;(void) workMode;
#endif /* (defined (DEV_ERROR_DETECT) || defined (CUSTOM_DEVASSERT)) */DEV_ASSERT((lptmr_GetClkFreq(LPTMR_GetClockSelect(base), instance) != 0u) || \(bypass && (workMode == LPTMR_WORKMODE_PULSECOUNTER)));/* The compare value can only be written if counter is disabled or the compare flag is set. */if (timerEnabled && !compareFlag){statusCode = STATUS_ERROR;}else{/* Check if new value is below the current counter value */LPTMR_SetCompareValue(base, compareValueByCount);counterVal = LPTMR_GetCounterValue(base);if (counterVal >= compareValueByCount){statusCode = STATUS_TIMEOUT;}}return statusCode;
}
LPTMR_DRV_GetCompareValueByCount
获取对比值
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_GetCompareValueByCount* Description : Get the compare value of timer in ticks units.** Implements : LPTMR_DRV_GetCompareValueByCount_Activity*END**************************************************************************/
void LPTMR_DRV_GetCompareValueByCount(const uint32_t instance,uint16_t * const compareValueByCount)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);const LPTMR_Type* const base = g_lptmrBase[instance];*compareValueByCount = LPTMR_GetCompareValue(base);
}
LPTMR_DRV_SetCompareValueByUs
设置对比值,需要工作模式为计时器
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_SetCompareValueUs* Description : Set the compare value for Timer Mode in microseconds,* for a LPTMR instance.* Can be used only in Timer Mode.* Possible return values:* - STATUS_SUCCESS: completed successfully* - STATUS_ERROR: cannot reconfigure compare value* - STATUS_TIMEOUT: compare value greater then current counter value** Implements : LPTMR_DRV_SetCompareValueByUs_Activity*END**************************************************************************/
status_t LPTMR_DRV_SetCompareValueByUs(const uint32_t instance,const uint32_t compareValueUs)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);status_t returnCode = STATUS_SUCCESS;LPTMR_Type* const base = g_lptmrBase[instance];bool timerEnabled, compareFlag;lptmr_clocksource_t clkSrc;uint32_t clkFreq;uint16_t cmpValTicks, currentCounterVal;lptmr_prescaler_t prescVal;bool prescBypass, conversionStatus;/* This function can only be used if LPTMR is configured in Timer Mode. */DEV_ASSERT(LPTMR_GetWorkMode(base) == LPTMR_WORKMODE_TIMER);timerEnabled = LPTMR_GetEnable(base);compareFlag = LPTMR_GetCompareFlag(base);/* The compare value can only be written if counter is disabled or the compare flag is set. */if (timerEnabled && !compareFlag){returnCode = STATUS_ERROR;}else{clkSrc = LPTMR_GetClockSelect(base);clkFreq = lptmr_GetClkFreq(clkSrc, instance);DEV_ASSERT(clkFreq != 0U); /* Check the calculated clock frequency: '0' - invalid*//* Get prescaler value and prescaler bypass state.*/prescVal = LPTMR_GetPrescaler(base);prescBypass = LPTMR_GetBypass(base);/* Convert new compare value from microseconds to ticks. */conversionStatus = lptmr_Us2Ticks(clkFreq, prescVal, prescBypass, compareValueUs, &cmpValTicks);DEV_ASSERT(conversionStatus == true); /* Check the conversion status: compareValueUs doesn't fit for current prescaller. */(void) conversionStatus;/* Write value and check if written successfully */LPTMR_SetCompareValue(base, cmpValTicks);currentCounterVal = LPTMR_GetCounterValue(base);if (currentCounterVal >= cmpValTicks){returnCode = STATUS_TIMEOUT;}}return returnCode;
}
LPTMR_DRV_GetCompareValueByUs
获取对比值,需要工作模式为计时器
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_GetCompareValueByUs* Description : Get the compare value in microseconds representation.* Can be used only in Timer Mode.** Implements : LPTMR_DRV_GetCompareValueByUs_Activity*END**************************************************************************/
void LPTMR_DRV_GetCompareValueByUs(const uint32_t instance,uint32_t * const compareValueUs)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);DEV_ASSERT(compareValueUs != NULL);const LPTMR_Type* const base = g_lptmrBase[instance];lptmr_clocksource_t clkSrc;uint32_t clkFreq;uint16_t cmpValTicks;lptmr_prescaler_t prescVal;bool prescBypass, conversionStatus;/* This function can only be used if LPTMR is configured in Timer Mode. */DEV_ASSERT(LPTMR_GetWorkMode(base) == LPTMR_WORKMODE_TIMER);clkSrc = LPTMR_GetClockSelect(base);clkFreq = lptmr_GetClkFreq(clkSrc, instance);/* The clock frequency must be valid. */DEV_ASSERT(clkFreq != 0U);/* Get prescaler value and prescaler bypass state.*/prescVal = LPTMR_GetPrescaler(base);prescBypass = LPTMR_GetBypass(base);cmpValTicks = LPTMR_GetCompareValue(base);/* Convert current compare value from ticks to microseconds. */conversionStatus = lptmr_Ticks2Us(clkFreq, prescVal, prescBypass, cmpValTicks, compareValueUs);DEV_ASSERT(conversionStatus == true); /* Check the conversion status. */(void) conversionStatus;
}
LPTMR_DRV_GetCompareFlag
它获取的对比标志位的意思是比较事件是否触发
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_GetCompareFlag* Description : Get the current state of the Compare Flag of a LPTMR instance** Implements : LPTMR_DRV_GetCompareFlag_Activity*END**************************************************************************/
bool LPTMR_DRV_GetCompareFlag(const uint32_t instance)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);const LPTMR_Type* const base = g_lptmrBase[instance];bool compareFlag = LPTMR_GetCompareFlag(base);return compareFlag;
}
LPTMR_DRV_ClearCompareFlag
清除对比标志位
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_ClearCompareFlag* Description : Clear the Compare Flag.** Implements : LPTMR_DRV_ClearCompareFlag_Activity*END**************************************************************************/
void LPTMR_DRV_ClearCompareFlag(const uint32_t instance)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);LPTMR_Type* const base = g_lptmrBase[instance];LPTMR_ClearCompareFlag(base);
}
LPTMR_DRV_IsRunning
查看TMR是否在运行
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_IsRunning* Description : Get the running state of a LPTMR instance.* Possible return values:* - true: Timer/Counter started* - false: Timer/Counter stopped** Implements : LPTMR_DRV_IsRunning_Activity*END**************************************************************************/
bool LPTMR_DRV_IsRunning(const uint32_t instance)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);const LPTMR_Type* const base = g_lptmrBase[instance];bool runningState = LPTMR_GetEnable(base);return runningState;
}
LPTMR_DRV_SetInterrupt
设置是否开启中断
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_SetInterrupt* Description : Enable/disable the LPTMR interrupt.** Implements : LPTMR_DRV_SetInterrupt_Activity*END**************************************************************************/
void LPTMR_DRV_SetInterrupt(const uint32_t instance,const bool enableInterrupt)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);LPTMR_Type* const base = g_lptmrBase[instance];LPTMR_SetInterrupt(base, enableInterrupt);
}
LPTMR_DRV_GetCounterValueByCount
获取计数器值,需要工作模式为脉冲计数器
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_GetCounterValueTicks* Description : Get the current Counter Value in timer ticks representation.* Return:* - the counter value.** Implements : LPTMR_DRV_GetCounterValueByCount_Activity*END**************************************************************************/
uint16_t LPTMR_DRV_GetCounterValueByCount(const uint32_t instance)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);LPTMR_Type* const base = g_lptmrBase[instance];uint16_t counterVal = LPTMR_GetCounterValue(base);return counterVal;
}
LPTMR_DRV_StartCounter
开始计时
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_StartCounter* Description : Enable (start) the counter.** Implements : LPTMR_DRV_StartCounter_Activity*END**************************************************************************/
void LPTMR_DRV_StartCounter(const uint32_t instance)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);LPTMR_Type* const base = g_lptmrBase[instance];/* Check if a valid clock is selected for the timer/glitch filter */
#if (defined (DEV_ERROR_DETECT) || defined (CUSTOM_DEVASSERT))bool bypass = LPTMR_GetBypass(base);lptmr_workmode_t workMode = LPTMR_GetWorkMode(base);(void) bypass;(void) workMode;
#endif /* (defined (DEV_ERROR_DETECT) || defined (CUSTOM_DEVASSERT)) */DEV_ASSERT((lptmr_GetClkFreq(LPTMR_GetClockSelect(base), instance) != 0u) || \(bypass && (workMode == LPTMR_WORKMODE_PULSECOUNTER)));LPTMR_Enable(base);
}
LPTMR_DRV_StopCounter
停止工作
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_StopCounter* Description : Disable (stop) the counter.** Implements : LPTMR_DRV_StopCounter_Activity*END**************************************************************************/
void LPTMR_DRV_StopCounter(const uint32_t instance)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);LPTMR_Type* const base = g_lptmrBase[instance];LPTMR_Disable(base);
}
LPTMR_DRV_SetPinConfiguration
设置脉冲计数的引脚和极性
/*FUNCTION************************************************************************ Function Name : LPTMR_DRV_SetPinConfiguration* Description : Set the Input Pin configuration for Pulse Counter mode.** Implements : LPTMR_DRV_SetPinConfiguration_Activity*END**************************************************************************/
void LPTMR_DRV_SetPinConfiguration(const uint32_t instance,const lptmr_pinselect_t pinSelect,const lptmr_pinpolarity_t pinPolarity)
{DEV_ASSERT(instance < LPTMR_INSTANCE_COUNT);LPTMR_Type* const base = g_lptmrBase[instance];LPTMR_SetPinSelect(base, pinSelect);LPTMR_SetPinPolarity(base, pinPolarity);
}