You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

439 lines
10 KiB

  1. /**
  2. * @file time.h
  3. * @author zhangcheng
  4. * @brief 定时器及PWM输出接口文件
  5. * @version v0.1
  6. * @date 2025-08-06
  7. *
  8. * @copyright Copyright (c) 2025
  9. */
  10. #include "../../system/inc/system.h"
  11. #include "../inc/time.h"
  12. /* 中断注册回调函数类型 */
  13. typedef void (*Func)(void *pArg);
  14. /* 中断注册回调函数列表 */
  15. static Func CallBackFuncList[] =
  16. {
  17. NULL, ///< TIM2
  18. NULL ///< TIM10
  19. };
  20. /* 中断注册回调参数列表 */
  21. static void *ArgList[] =
  22. {
  23. NULL, ///< TIM2
  24. NULL ///< TIM10
  25. };
  26. /* 可用定时器列表 */
  27. static char *TimNameList[] =
  28. {
  29. "tim2", ///< TIM2
  30. "tim10", ///< TIM10
  31. "tim11", ///< TIM11
  32. "tim13", ///< TIM13
  33. "tim14" ///< TIM14
  34. };
  35. /* 可用定时器列表参数 */
  36. static TIM_TypeDef *TimType[] =
  37. {
  38. TIM2, ///< TIM2
  39. TIM10, ///< TIM10
  40. TIM11, ///< TIM11
  41. TIM13, ///< TIM13
  42. TIM14 ///< TIM14
  43. };
  44. /**
  45. * @brief 定时器初始化
  46. * @details
  47. *
  48. * @param[in] *tim 定时器结构体指针
  49. * @param[in] psc 定时器预分频系数
  50. * @param[in] per 定时器重装载值
  51. *
  52. * @return int8_t 返回结果
  53. * @retval 0 成功
  54. * @retval -1 失败
  55. */
  56. int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per)
  57. {
  58. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  59. if (tim->TIM == TIM2)
  60. {
  61. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
  62. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  63. TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  64. GPIO_InitTypeDef GPIO_InitStructure;
  65. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  66. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  67. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  68. GPIO_Init(GPIOA, &GPIO_InitStructure);
  69. GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_TIM2);
  70. TIM_SelectInputTrigger(tim->TIM, TIM_TS_ETRF);
  71. TIM_ETRClockMode2Config(tim->TIM, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);
  72. }
  73. else if (tim->TIM == TIM10)
  74. {
  75. RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,ENABLE);
  76. TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  77. }
  78. else if (tim->TIM == TIM11)
  79. {
  80. RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,ENABLE);
  81. TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  82. }
  83. else if (tim->TIM == TIM13)
  84. {
  85. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,ENABLE);
  86. TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  87. }
  88. else if (tim->TIM == TIM14)
  89. {
  90. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);
  91. TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  92. }
  93. else
  94. return -1;
  95. if (tim->TIM != TIM2)
  96. TIM_InternalClockConfig(tim->TIM);
  97. TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
  98. TIM_TimeBaseInitStructure.TIM_Period=per;
  99. TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
  100. TIM_TimeBaseInit(tim->TIM, &TIM_TimeBaseInitStructure);
  101. // TIM_GenerateEvent(tim->TIM, TIM_EventSource_Update);
  102. TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update);
  103. return 0;
  104. }
  105. /**
  106. * @brief 定时器复位
  107. * @details
  108. *
  109. * @param[in] *tim 定时器结构体指针
  110. *
  111. * @return 无
  112. */
  113. void TimDeInit(TIM_OBJ *tim)
  114. {
  115. if (tim->TIM == TIM2)
  116. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,DISABLE);
  117. else if (tim->TIM == TIM10)
  118. RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,DISABLE);
  119. else if (tim->TIM == TIM11)
  120. RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,DISABLE);
  121. else if (tim->TIM == TIM13)
  122. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,DISABLE);
  123. else if (tim->TIM == TIM14)
  124. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,DISABLE);
  125. else
  126. return;
  127. TIM_Cmd(tim->TIM, DISABLE);
  128. TIM_DeInit(tim->TIM);
  129. }
  130. /**
  131. * @brief 设置定时器预分频
  132. * @details
  133. *
  134. * @param[in] *tim 定时器结构体指针
  135. * @param[in] psc 定时器预分频系数
  136. *
  137. * @return 无
  138. */
  139. void TimSetPsc(TIM_OBJ *tim, uint16_t psc)
  140. {
  141. TIM_ITConfig(tim->TIM, TIM_IT_Update, DISABLE);
  142. TIM_PrescalerConfig(tim->TIM, psc, TIM_PSCReloadMode_Immediate);
  143. TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update);
  144. TIM_ITConfig(tim->TIM, TIM_IT_Update, ENABLE);
  145. }
  146. /**
  147. * @brief 设置定时器重载值
  148. * @details
  149. *
  150. * @param[in] *tim 定时器结构体指针
  151. * @param[in] per 定时器重装载值
  152. *
  153. * @return 无
  154. */
  155. void TimSetPer(TIM_OBJ *tim, uint32_t per)
  156. {
  157. TIM_SetAutoreload(tim->TIM, per);
  158. }
  159. /**
  160. * @brief 开启定时器
  161. * @details
  162. *
  163. * @param[in] *tim 定时器结构体指针
  164. *
  165. * @return 无
  166. */
  167. void TimOpen(TIM_OBJ *tim)
  168. {
  169. TIM_Cmd(tim->TIM, ENABLE);
  170. }
  171. /**
  172. * @brief 关闭定时器
  173. * @details
  174. *
  175. * @param[in] *tim 定时器结构体指针
  176. *
  177. * @return 无
  178. */
  179. void TimClose(TIM_OBJ *tim)
  180. {
  181. TIM_Cmd(tim->TIM, DISABLE);
  182. }
  183. /**
  184. * @brief 开启定时器更新中断
  185. * @details
  186. *
  187. * @param[in] *tim 定时器结构体指针
  188. *
  189. * @return 无
  190. */
  191. void TimOpenIrq(TIM_OBJ *tim)
  192. {
  193. NVIC_InitTypeDef NVIC_InitStructure;
  194. TIM_ITConfig(tim->TIM, TIM_IT_Update, ENABLE);
  195. TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update);
  196. if (tim->TIM == TIM2)
  197. NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
  198. else if(tim->TIM == TIM10)
  199. NVIC_InitStructure.NVIC_IRQChannel=TIM1_UP_TIM10_IRQn;
  200. else
  201. return;
  202. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=7;
  203. NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
  204. NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  205. NVIC_Init(&NVIC_InitStructure);
  206. }
  207. /**
  208. * @brief 关闭定时器更新中断
  209. * @details
  210. *
  211. * @param[in] *tim 定时器结构体指针
  212. *
  213. * @return 无
  214. */
  215. void TimCloseIrq(TIM_OBJ *tim)
  216. {
  217. TIM_ITConfig(tim->TIM, TIM_IT_Update, DISABLE);
  218. TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update);
  219. }
  220. /**
  221. * @brief 注册定时器中断回调函数
  222. * @details
  223. *
  224. * @param[in] *tim 定时器结构体指针
  225. * @param[in] registerFunc 回调函数地址
  226. * @note 回调函数格式 void (*registerFunc)(void *pArg)
  227. *
  228. * @return 无
  229. */
  230. void TimRegisterIrq(TIM_OBJ *tim, void (*registerFunc)(void *pArg), void *pArg)
  231. {
  232. if (tim->TIM == TIM2)
  233. {
  234. CallBackFuncList[0] = registerFunc;
  235. ArgList[0] = pArg;
  236. }
  237. else if (tim->TIM == TIM10)
  238. {
  239. CallBackFuncList[1] = registerFunc;
  240. ArgList[1] = pArg;
  241. }
  242. else
  243. return;
  244. }
  245. /**
  246. * @brief PWM初始化
  247. * @details
  248. *
  249. * @param[in] *tim 定时器结构体指针
  250. * @param[in] pulse 脉冲宽度
  251. *
  252. * @return 无
  253. */
  254. void PwmInit(TIM_OBJ *tim)
  255. {
  256. TIM_OCInitTypeDef TIM_OCInitStructure;
  257. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
  258. GPIO_PinAFConfig(GPIOF, GPIO_PinSource6, GPIO_AF_TIM10);
  259. GPIO_InitTypeDef GPIO_InitStructure;
  260. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  261. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  262. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  263. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  264. GPIO_Init(GPIOF,&GPIO_InitStructure);
  265. TIM_OCStructInit(&TIM_OCInitStructure);
  266. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  267. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  268. TIM_OCInitStructure.TIM_OutputState = ENABLE;
  269. TIM_OCInitStructure.TIM_Pulse = 0;
  270. TIM_OC1Init(tim->TIM, &TIM_OCInitStructure);
  271. }
  272. /**
  273. * @brief PWM复位
  274. * @details
  275. *
  276. * @param[in] *tim 定时器结构体指针
  277. *
  278. * @return 无
  279. */
  280. void PwmDeInit(TIM_OBJ *tim)
  281. {
  282. TIM_OCInitTypeDef TIM_OCInitStructure;
  283. TIM_OCInitStructure.TIM_OutputState = DISABLE;
  284. TIM_OCInitStructure.TIM_Pulse = 0;
  285. TIM_OC1Init(tim->TIM, &TIM_OCInitStructure);
  286. }
  287. /**
  288. * @brief 设置PWM脉冲宽度
  289. * @details
  290. *
  291. * @param[in] *tim 定时器结构体指针
  292. * @param[in] pulse PWM脉冲宽度
  293. *
  294. * @return 无
  295. */
  296. void PwmSetPulse(TIM_OBJ *tim, uint32_t pulse)
  297. {
  298. TIM_SetCompare1(tim->TIM, pulse);
  299. }
  300. /**
  301. * @brief 定时器2更新中断服务函数
  302. * @details
  303. *
  304. * @param[in] 无
  305. *
  306. * @return 无
  307. */
  308. void TIM2_IRQHandler(void)
  309. {
  310. if (TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
  311. {
  312. if (CallBackFuncList[0] != NULL)
  313. CallBackFuncList[0](ArgList[0]);
  314. TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
  315. }
  316. }
  317. /**
  318. * @brief 定时器13更新中断服务函数
  319. * @details
  320. *
  321. * @param[in] 无
  322. *
  323. * @return 无
  324. */
  325. void TIM1_UP_TIM10_IRQHandler(void)
  326. {
  327. if (TIM_GetITStatus(TIM10,TIM_IT_Update) == SET)
  328. {
  329. if (ArgList[1] != NULL)
  330. CallBackFuncList[1](ArgList[1]);
  331. TIM_ClearITPendingBit(TIM10, TIM_IT_Update);
  332. }
  333. }
  334. /**
  335. * @brief 获取定时器
  336. * @details
  337. *
  338. * @param[in] *timName 定时器名称
  339. * @note "timx" x : 10、11、13、14
  340. * @param[out] *timObj 接收定时器参数地址
  341. *
  342. * @return int8_t 返回结果
  343. * @retval 0 成功
  344. * @retval -1 失败
  345. */
  346. int8_t GetTimObj(char *timName, TIM_OBJ *timObj)
  347. {
  348. uint8_t getTimFlag = 0;
  349. if (!timObj)
  350. return -1;
  351. for (uint8_t i = 0; i < sizeof(TimNameList) / sizeof(TimNameList[0]); i++)
  352. {
  353. if (strcmp(timName, TimNameList[i]) == 0)
  354. {
  355. timObj->TIM = TimType[i];
  356. getTimFlag = 1;
  357. break;
  358. }
  359. }
  360. if (!getTimFlag)
  361. return -1;
  362. timObj->init = &TimInit;
  363. timObj->deInit = &TimDeInit;
  364. timObj->setPsc = &TimSetPsc;
  365. timObj->setPer = &TimSetPer;
  366. timObj->open = &TimOpen;
  367. timObj->close = &TimClose;
  368. timObj->openIrq = &TimOpenIrq;
  369. timObj->closeIrq = &TimCloseIrq;
  370. timObj->registerIrq = &TimRegisterIrq;
  371. timObj->pwmInit = &PwmInit;
  372. timObj->pwmDeInit = &PwmDeInit;
  373. timObj->pwmSetPulse = &PwmSetPulse;
  374. return 0;
  375. }