#include "../main/SystemInclude.h" /**------------------------------------------------------------------------ * @brief LPTimer 基础初始化(内部调用) * @note 配置为定时器/计数器模式,时钟源由 LPTIM_CLK_ENABLE_LSE 宏决定, * 预分频系数固定为 DIV2(LSI 或 LSE 频率除以2),禁用自由运行模式。 * @param lptimer: LPTIM1 或 LPTIM2 * @example 内部使用,不直接调用 **/ static void LPTIM_Init(LPTIM_TypeDef *lptimer) { LPTIM_InitTypeDef LPTIM_InitStructure; /* 1. 初始化LPTimer Base */ LPTIM_InitStructure.Mode = LPTIM_MODE_TIMER_COUNTER; // 定时器模式 #if LPTIM_CLK_ENABLE_LSE LHL_RCC_LSEConfig(ENABLE); LPTIM_InitStructure.Clock = LPTIM_CLOCKSOURCE_LSE; // LPTIM时钟源LSE #else LHL_RCC_LSEConfig(DISABLE); LPTIM_InitStructure.Clock = LPTIM_CLOCKSOURCE_LSI; // LPTIM时钟源LSI #endif LPTIM_InitStructure.Prescaler = LPTIM_PRESCALER_DIV2; // 预分频系数2 变成 16384 为1s LPTIM_InitStructure.FreeRunning = DISABLE; // 禁用自由运行模式 LHL_LPTIM_Init(lptimer, &LPTIM_InitStructure); } /*==================================================================================*/ /*LPTimer1==========================================================================*/ /*==================================================================================*/ /**------------------------------------------------------------------------ * @brief 启动 LPTIM1,产生周期性中断 * @note 时钟频率为 32768Hz,预分频 DIV2 后实际时钟为 16384Hz。 * 周期计算:计数值 uploadCounter = (16384/1000) * t(ms) = 16.384 * t * 例如 t=125ms,uploadCounter≈2048。 * @param uploadCounter: 自动重装载值(范围 1~65535),对应定时周期 * @example StartLPTimer1(2048); // 启动 125ms 周期定时器 **/ void StartLPTimer1(u16 uploadCounter)//125ms 250ms ...... { /* 1. 初始化LPTimer Base */ LHL_LPTIM_DeInit(LPTIM1); LPTIM_Init(LPTIM1); /* 2. 开启LPTimer中断 */ LHL_LPTIM_ITConfig(LPTIM1, ENABLE); NVIC_EnableIRQ(LPTIM1_IRQn); /* 3. 启动LPTimer1 */ LHL_LPTIM_Start(LPTIM1, uploadCounter); } /**------------------------------------------------------------------------ * @brief 重置 LPTIM1 周期(运行时修改) * @note 先停用定时器,更新比较值 CMR,再重新使能,计数器从 0 重新开始。 * @param uploadCounter: 新的重装载值 计算方式16.384 * t * @example ResetLPTimer1(4096); // 将周期改为 250ms **/ void ResetLPTimer1(u16 uploadCounter) { LPTIM1->CSR &= ~LPTIM_CSR_TEN_Msk;// 1. 禁用定时器 LPTIM1->CSR |= LPTIM_CSR_TCF_Msk; // 2. 清除比较中断标志 LPTIM1->CMR = uploadCounter; // 3. 设置新的比较值 LPTIM1->CSR |= LPTIM_CSR_TEN_Msk; // 4. 重新使能 → 计数器从 0 开始 } /**------------------------------------------------------------------------ * @brief 停止 LPTIM1 * @note 禁用定时器并使能位 TEN 清零,清除比较中断标志。 * @param 无 * @example StopLPTimer1(); **/ void StopLPTimer1(void) { LPTIM1->CSR &= ~LPTIM_CSR_TEN_Msk;// 1. 禁用定时器 LPTIM1->CSR |= LPTIM_CSR_TCF_Msk; // 2. 清除比较中断标志 } /*==================================================================================*/ /*LPTimer2==========================================================================*/ /*==================================================================================*/ /**------------------------------------------------------------------------ * @brief 启动 LPTIM2,产生周期性中断 * @note 同 LPTIM1,时钟频率 32768Hz,预分频 DIV2,周期计算相同。 * @param uploadCounter: 自动重装载值 * @example StartLPTimer2(2048); // 启动 125ms 周期定时器 **/ void StartLPTimer2(u16 uploadCounter)//125ms 250ms ...... { /* 1. 初始化LPTimer Base */ LHL_LPTIM_DeInit(LPTIM2); LPTIM_Init(LPTIM2); /* 2. 开启LPTimer中断 */ LHL_LPTIM_ITConfig(LPTIM2, ENABLE); NVIC_EnableIRQ(LPTIM2_IRQn); /* 3. 启动LPTimer1和2 */ LHL_LPTIM_Start(LPTIM2, uploadCounter); } /**------------------------------------------------------------------------ * @brief 重置 LPTIM2 周期(运行时修改) * @param uploadCounter: 新的重装载值 计算方式16.384 * t * @example ResetLPTimer2(4096); **/ void ResetLPTimer2(u16 uploadCounter) { LPTIM2->CSR &= ~LPTIM_CSR_TEN_Msk;// 1. 禁用定时器 LPTIM2->CSR |= LPTIM_CSR_TCF_Msk; // 2. 清除比较中断标志 LPTIM2->CMR = uploadCounter; // 3. 设置新的比较值 LPTIM2->CSR |= LPTIM_CSR_TEN_Msk; // 4. 重新使能 → 计数器从 0 开始 } /**------------------------------------------------------------------------ * @brief 停止 LPTIM2 * @example StopLPTimer2(); **/ void StopLPTimer2(void) { LPTIM2->CSR &= ~LPTIM_CSR_TEN_Msk;// 1. 禁用定时器 LPTIM2->CSR |= LPTIM_CSR_TCF_Msk; // 2. 清除比较中断标志 } /*==================================================================================*/ /*低功耗定时器回调函数====================================================================*/ /*==================================================================================*/ /**------------------------------------------------------------------------ * @brief 注册 LPTIM1/LPTIM2 中断回调函数 * @param lptimer: LPTIM1 或 LPTIM2 * @param lptim_irq_callback: 用户回调函数指针(无参数无返回值) * @note 每个定时器只能注册一个回调函数(若需多源,可自行扩展)。 * 注册时会自动清除中断标志并开启 NVIC 中断。 * @example lptimer_register_irq_callback(LPTIM1, my_callback); **/ static lptimer_irq_callback_t lptim1_irq_callback,lptim2_irq_callback ; void lptimer_register_irq_callback(LPTIM_TypeDef *lptimer ,lptimer_irq_callback_t lptim_irq_callback) { if(lptimer == LPTIM1) { lptim1_irq_callback = lptim_irq_callback;//赋值回调函数 LHL_LPTIM_ClearPending(LPTIM1);// 清除中断标志 NVIC_EnableIRQ(LPTIM1_IRQn);//开启中断 } else if(lptimer == LPTIM2) { lptim2_irq_callback = lptim_irq_callback; LHL_LPTIM_ClearPending(LPTIM2);// 清除中断标志 NVIC_EnableIRQ(LPTIM2_IRQn); } } /**------------------------------------------------------------------------ * @brief LPTIM1 中断服务函数 * @note 调用已注册的回调函数(若存在),然后清除中断标志。 * @param 无 **/ void LPTIM1_IRQHandler(void) { // 如果有中断发生且注册了回调函数 if (lptim1_irq_callback != NULL) lptim1_irq_callback();// 调用用户注册的回调函数 LHL_LPTIM_ClearPending(LPTIM1); // 清除中断标志 } /**------------------------------------------------------------------------ * @brief LPTIM2 中断服务函数 * @note 调用已注册的回调函数(若存在),然后清除中断标志。 * @param 无 **/ void LPTIM2_IRQHandler(void) { // 如果有中断发生且注册了回调函数 if (lptim2_irq_callback != NULL) lptim2_irq_callback();// 调用用户注册的回调函数 LHL_LPTIM_ClearPending(LPTIM2); // 清除中断标志 }