|
|
@@ -0,0 +1,371 @@ |
|
|
|
/** |
|
|
|
* @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[3] = |
|
|
|
{ |
|
|
|
NULL, ///< TIM10 |
|
|
|
NULL, ///< TIM11 |
|
|
|
NULL ///< TIM13 |
|
|
|
}; |
|
|
|
|
|
|
|
/* 中断注册回调参数列表 */ |
|
|
|
static void *ArgList[3] = |
|
|
|
{ |
|
|
|
NULL, ///< TIM10 |
|
|
|
NULL, ///< TIM11 |
|
|
|
NULL ///< TIM13 |
|
|
|
}; |
|
|
|
|
|
|
|
/* 可用定时器列表 */ |
|
|
|
static char *TimNameList[] = |
|
|
|
{ |
|
|
|
"tim10", ///< TIM10 |
|
|
|
"tim11", ///< TIM11 |
|
|
|
"tim13", ///< TIM13 |
|
|
|
"tim14" ///< TIM14 |
|
|
|
}; |
|
|
|
|
|
|
|
/* 可用定时器列表参数 */ |
|
|
|
static TIM_TypeDef *TimType[] = |
|
|
|
{ |
|
|
|
TIM10, ///< TIM10 |
|
|
|
TIM11, ///< TIM11 |
|
|
|
TIM13, ///< TIM13 |
|
|
|
TIM13 ///< 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 == TIM10) |
|
|
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,ENABLE); |
|
|
|
else if (tim->TIM == TIM11) |
|
|
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,ENABLE); |
|
|
|
else if (tim->TIM == TIM13) |
|
|
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,ENABLE); |
|
|
|
else if (tim->TIM == TIM14) |
|
|
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); |
|
|
|
else |
|
|
|
return -1; |
|
|
|
|
|
|
|
TIM_InternalClockConfig(tim->TIM); |
|
|
|
|
|
|
|
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; |
|
|
|
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; |
|
|
|
TIM_TimeBaseInitStructure.TIM_Period=per; |
|
|
|
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; |
|
|
|
TIM_TimeBaseInit(tim->TIM, &TIM_TimeBaseInitStructure); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @brief 定时器复位 |
|
|
|
* @details |
|
|
|
* |
|
|
|
* @param[in] *tim 定时器结构体指针 |
|
|
|
* |
|
|
|
* @return 无 |
|
|
|
*/ |
|
|
|
void TimDeInit(TIM_OBJ *tim) |
|
|
|
{ |
|
|
|
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_PrescalerConfig(tim->TIM, psc, TIM_PSCReloadMode_Immediate); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @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); |
|
|
|
|
|
|
|
NVIC_InitStructure.NVIC_IRQChannel=TIM8_UP_TIM13_IRQn; |
|
|
|
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 == TIM10) |
|
|
|
{ |
|
|
|
CallBackFuncList[0] = registerFunc; |
|
|
|
ArgList[0] = pArg; |
|
|
|
} |
|
|
|
else if (tim->TIM == TIM11) |
|
|
|
{ |
|
|
|
CallBackFuncList[1] = registerFunc; |
|
|
|
ArgList[1] = pArg; |
|
|
|
} |
|
|
|
else if (tim->TIM == TIM13) |
|
|
|
{ |
|
|
|
CallBackFuncList[2] = registerFunc; |
|
|
|
ArgList[2] = pArg; |
|
|
|
} |
|
|
|
else |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @brief PWM初始化 |
|
|
|
* @details |
|
|
|
* |
|
|
|
* @param[in] *tim 定时器结构体指针 |
|
|
|
* @param[in] pulse 脉冲宽度 |
|
|
|
* |
|
|
|
* @return 无 |
|
|
|
*/ |
|
|
|
void PwmInit(TIM_OBJ *tim) |
|
|
|
{ |
|
|
|
TIM_OCInitTypeDef TIM_OCInitStructure; |
|
|
|
|
|
|
|
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 定时器10、11、13、14更新中断服务函数 |
|
|
|
* @details |
|
|
|
* |
|
|
|
* @param[in] 无 |
|
|
|
* |
|
|
|
* @return 无 |
|
|
|
*/ |
|
|
|
void TIM8_UP_TIM13_IRQHandler(void) |
|
|
|
{ |
|
|
|
if (TIM_GetITStatus(TIM10,TIM_IT_Update) == SET) |
|
|
|
{ |
|
|
|
if (ArgList[0] != NULL) |
|
|
|
CallBackFuncList[0](ArgList[0]); |
|
|
|
TIM_ClearITPendingBit(TIM10, TIM_IT_Update); |
|
|
|
} |
|
|
|
else if (TIM_GetITStatus(TIM11,TIM_IT_Update) == SET) |
|
|
|
{ |
|
|
|
if (ArgList[1] != NULL) |
|
|
|
CallBackFuncList[1](ArgList[1]); |
|
|
|
TIM_ClearITPendingBit(TIM11, TIM_IT_Update); |
|
|
|
} |
|
|
|
else if (TIM_GetITStatus(TIM11,TIM_IT_Update) == SET) |
|
|
|
{ |
|
|
|
if (ArgList[2] != NULL) |
|
|
|
CallBackFuncList[2](ArgList[2]); |
|
|
|
TIM_ClearITPendingBit(TIM12, TIM_IT_Update); |
|
|
|
} |
|
|
|
else |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @brief 获取定时器 |
|
|
|
* @details |
|
|
|
* |
|
|
|
* @param[in] *timName 定时器名称 |
|
|
|
* @param "timx" x : 10、11、13、14 |
|
|
|
* |
|
|
|
* @return TIM_OBJ 定时器结构体 |
|
|
|
*/ |
|
|
|
TIM_OBJ GetTimObj(char *timName) |
|
|
|
{ |
|
|
|
TIM_OBJ tim; |
|
|
|
|
|
|
|
for (uint8_t i = 0; i < sizeof(TimNameList) / sizeof(TimNameList[0]); i++) |
|
|
|
{ |
|
|
|
if (strcmp(timName, TimNameList[i]) == 0) |
|
|
|
{ |
|
|
|
tim.TIM = TimType[i]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
tim.init = &TimInit; |
|
|
|
tim.deInit = &TimDeInit; |
|
|
|
tim.setPsc = &TimSetPsc; |
|
|
|
tim.setPer = &TimSetPer; |
|
|
|
tim.open = &TimOpen; |
|
|
|
tim.close = &TimClose; |
|
|
|
tim.openIrq = &TimOpenIrq; |
|
|
|
tim.closeIrq = &TimCloseIrq; |
|
|
|
tim.registerIrq = &TimRegisterIrq; |
|
|
|
tim.pwmInit = &PwmInit; |
|
|
|
tim.pwmDeInit = &PwmDeInit; |
|
|
|
tim.pwmSetPulse = &PwmSetPulse; |
|
|
|
|
|
|
|
return tim; |
|
|
|
} |