/** * @file time.h * @author zhangcheng * @brief 定时器及PWM输出接口文件 * @version v0.1 * @date 2025-08-06 * * @copyright Copyright (c) 2025 */ #include "../../system/inc/system.h" #include "../inc/time.h" /* 中断注册回调函数类型 */ typedef void (*Func)(void *pArg); /* 中断注册回调函数列表 */ static Func CallBackFuncList[] = { NULL, ///< TIM2 NULL ///< TIM10 }; /* 中断注册回调参数列表 */ static void *ArgList[] = { NULL, ///< TIM2 NULL ///< TIM10 }; /* 可用定时器列表 */ static char *TimNameList[] = { "tim2", ///< TIM2 "tim10", ///< TIM10 "tim11", ///< TIM11 "tim13", ///< TIM13 "tim14" ///< TIM14 }; /* 可用定时器列表参数 */ static TIM_TypeDef *TimType[] = { TIM2, ///< TIM2 TIM10, ///< TIM10 TIM11, ///< TIM11 TIM13, ///< TIM13 TIM14 ///< TIM14 }; /** * @brief 定时器初始化 * @details * * @param[in] *tim 定时器结构体指针 * @param[in] psc 定时器预分频系数 * @param[in] per 定时器重装载值 * * @return int8_t 返回结果 * @retval 0 成功 * @retval -1 失败 */ int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; if (tim->TIM == TIM2) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_TIM2); TIM_SelectInputTrigger(tim->TIM, TIM_TS_ETRF); TIM_ETRClockMode2Config(tim->TIM, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0); } else if (tim->TIM == TIM10) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,ENABLE); TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; } else if (tim->TIM == TIM11) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,ENABLE); TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; } else if (tim->TIM == TIM13) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,ENABLE); TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; } else if (tim->TIM == TIM14) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; } else return -1; if (tim->TIM != TIM2) TIM_InternalClockConfig(tim->TIM); TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period=per; TIM_TimeBaseInitStructure.TIM_Prescaler=psc; TIM_TimeBaseInit(tim->TIM, &TIM_TimeBaseInitStructure); // TIM_GenerateEvent(tim->TIM, TIM_EventSource_Update); TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update); return 0; } /** * @brief 定时器复位 * @details * * @param[in] *tim 定时器结构体指针 * * @return 无 */ void TimDeInit(TIM_OBJ *tim) { if (tim->TIM == TIM2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,DISABLE); else if (tim->TIM == TIM10) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,DISABLE); else if (tim->TIM == TIM11) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,DISABLE); else if (tim->TIM == TIM13) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,DISABLE); else if (tim->TIM == TIM14) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,DISABLE); else return; TIM_Cmd(tim->TIM, DISABLE); TIM_DeInit(tim->TIM); } /** * @brief 设置定时器预分频 * @details * * @param[in] *tim 定时器结构体指针 * @param[in] psc 定时器预分频系数 * * @return 无 */ void TimSetPsc(TIM_OBJ *tim, uint16_t psc) { TIM_ITConfig(tim->TIM, TIM_IT_Update, DISABLE); TIM_PrescalerConfig(tim->TIM, psc, TIM_PSCReloadMode_Immediate); TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update); TIM_ITConfig(tim->TIM, TIM_IT_Update, ENABLE); } /** * @brief 设置定时器重载值 * @details * * @param[in] *tim 定时器结构体指针 * @param[in] per 定时器重装载值 * * @return 无 */ void TimSetPer(TIM_OBJ *tim, uint32_t per) { TIM_SetAutoreload(tim->TIM, per); } /** * @brief 开启定时器 * @details * * @param[in] *tim 定时器结构体指针 * * @return 无 */ void TimOpen(TIM_OBJ *tim) { TIM_Cmd(tim->TIM, ENABLE); } /** * @brief 关闭定时器 * @details * * @param[in] *tim 定时器结构体指针 * * @return 无 */ void TimClose(TIM_OBJ *tim) { TIM_Cmd(tim->TIM, DISABLE); } /** * @brief 开启定时器更新中断 * @details * * @param[in] *tim 定时器结构体指针 * * @return 无 */ void TimOpenIrq(TIM_OBJ *tim) { NVIC_InitTypeDef NVIC_InitStructure; TIM_ITConfig(tim->TIM, TIM_IT_Update, ENABLE); TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update); if (tim->TIM == TIM2) NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn; else if(tim->TIM == TIM10) NVIC_InitStructure.NVIC_IRQChannel=TIM1_UP_TIM10_IRQn; else return; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=7; NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure); } /** * @brief 关闭定时器更新中断 * @details * * @param[in] *tim 定时器结构体指针 * * @return 无 */ void TimCloseIrq(TIM_OBJ *tim) { TIM_ITConfig(tim->TIM, TIM_IT_Update, DISABLE); TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update); } /** * @brief 注册定时器中断回调函数 * @details * * @param[in] *tim 定时器结构体指针 * @param[in] registerFunc 回调函数地址 * @note 回调函数格式 void (*registerFunc)(void *pArg) * * @return 无 */ void TimRegisterIrq(TIM_OBJ *tim, void (*registerFunc)(void *pArg), void *pArg) { if (tim->TIM == TIM2) { CallBackFuncList[0] = registerFunc; ArgList[0] = pArg; } else if (tim->TIM == TIM10) { CallBackFuncList[1] = registerFunc; ArgList[1] = pArg; } else return; } /** * @brief PWM初始化 * @details * * @param[in] *tim 定时器结构体指针 * @param[in] pulse 脉冲宽度 * * @return 无 */ void PwmInit(TIM_OBJ *tim) { TIM_OCInitTypeDef TIM_OCInitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); GPIO_PinAFConfig(GPIOF, GPIO_PinSource6, GPIO_AF_TIM10); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOF,&GPIO_InitStructure); TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = ENABLE; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC1Init(tim->TIM, &TIM_OCInitStructure); } /** * @brief PWM复位 * @details * * @param[in] *tim 定时器结构体指针 * * @return 无 */ void PwmDeInit(TIM_OBJ *tim) { TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OutputState = DISABLE; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC1Init(tim->TIM, &TIM_OCInitStructure); } /** * @brief 设置PWM脉冲宽度 * @details * * @param[in] *tim 定时器结构体指针 * @param[in] pulse PWM脉冲宽度 * * @return 无 */ void PwmSetPulse(TIM_OBJ *tim, uint32_t pulse) { TIM_SetCompare1(tim->TIM, pulse); } /** * @brief 定时器2更新中断服务函数 * @details * * @param[in] 无 * * @return 无 */ void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2,TIM_IT_Update) == SET) { if (CallBackFuncList[0] != NULL) CallBackFuncList[0](ArgList[0]); TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } } /** * @brief 定时器13更新中断服务函数 * @details * * @param[in] 无 * * @return 无 */ void TIM1_UP_TIM10_IRQHandler(void) { if (TIM_GetITStatus(TIM10,TIM_IT_Update) == SET) { if (ArgList[1] != NULL) CallBackFuncList[1](ArgList[1]); TIM_ClearITPendingBit(TIM10, TIM_IT_Update); } } /** * @brief 获取定时器 * @details * * @param[in] *timName 定时器名称 * @note "timx" x : 10、11、13、14 * @param[out] *timObj 接收定时器参数地址 * * @return int8_t 返回结果 * @retval 0 成功 * @retval -1 失败 */ int8_t GetTimObj(char *timName, TIM_OBJ *timObj) { uint8_t getTimFlag = 0; if (!timObj) return -1; for (uint8_t i = 0; i < sizeof(TimNameList) / sizeof(TimNameList[0]); i++) { if (strcmp(timName, TimNameList[i]) == 0) { timObj->TIM = TimType[i]; getTimFlag = 1; break; } } if (!getTimFlag) return -1; timObj->init = &TimInit; timObj->deInit = &TimDeInit; timObj->setPsc = &TimSetPsc; timObj->setPer = &TimSetPer; timObj->open = &TimOpen; timObj->close = &TimClose; timObj->openIrq = &TimOpenIrq; timObj->closeIrq = &TimCloseIrq; timObj->registerIrq = &TimRegisterIrq; timObj->pwmInit = &PwmInit; timObj->pwmDeInit = &PwmDeInit; timObj->pwmSetPulse = &PwmSetPulse; return 0; }