ciu32f003_std_tim(1).c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /************************************************************************************************/
  2. /**
  3. * @file ciu32f003_std_tim.c
  4. * @author MCU Ecosystem Development Team
  5. * @brief TIM STD库驱动。
  6. * 实现TIM基本计数、输入捕获、输出比较等功能初始化API。
  7. *
  8. *
  9. **************************************************************************************************
  10. * @attention
  11. * Copyright (c) CEC Huada Electronic Design Co.,Ltd. All rights reserved.
  12. *
  13. **************************************************************************************************
  14. */
  15. /************************************************************************************************/
  16. /**
  17. * @addtogroup CIU32F003_STD_Driver
  18. * @{
  19. */
  20. /**
  21. * @addtogroup TIM
  22. * @{
  23. *
  24. */
  25. /************************************************************************************************/
  26. /*------------------------------------------includes--------------------------------------------*/
  27. #include "ciu32f003_std.h"
  28. #ifdef STD_TIM_PERIPHERAL_USED
  29. /*-------------------------------------------functions------------------------------------------*/
  30. /************************************************************************************************/
  31. /**
  32. * @addtogroup TIM_External_Functions
  33. * @{
  34. *
  35. */
  36. /************************************************************************************************/
  37. /**
  38. * @brief TIM初始化
  39. * @param timx TIM外设
  40. * @param tim_init_param TIM初始化结构体
  41. * @note 由于DIR位在中心对齐模式下为只读,从中心对齐模式切换到边沿对齐计数器模式(或反向),
  42. * 需要停止计数后修改,以避免造成计数异常。
  43. * @retval 无
  44. */
  45. void std_tim_init(TIM_t *timx, std_tim_basic_init_t *tim_init_param)
  46. {
  47. if(TIM1 == timx)
  48. {
  49. /* 先切换到边沿模式,才能修改DIR控制位 */
  50. timx->CR1 &= (~TIM_CR1_CMS);
  51. /* 选择计数器模式及时钟分频参数 */
  52. MODIFY_REG(timx->CR1,
  53. ((TIM_CR1_DIR | TIM_CR1_CMS) | TIM_CR1_CLK_DIV),
  54. (tim_init_param->counter_mode | tim_init_param->clock_div));
  55. /* 设置重复计数参数 */
  56. std_tim_set_repcounter(timx, tim_init_param->repeat_counter);
  57. }
  58. else if(TIM3 == timx)
  59. {
  60. /* 设置时钟分频参数 */
  61. MODIFY_REG(timx->CR1, TIM_CR1_CLK_DIV, tim_init_param->clock_div);
  62. }
  63. /* 设置自动加载值 */
  64. std_tim_set_autoreload(timx, tim_init_param->period);
  65. /* 设置预分频值 */
  66. std_tim_set_psc(timx, tim_init_param->prescaler);
  67. /* 生成一个更新事件来重新加载预预分频值 */
  68. /* 如果支持RCR模式,则更新事件也将重新加载重复计数器值 */
  69. std_tim_set_sw_trig_event(timx, TIM_EVENT_SRC_UPDATE);
  70. }
  71. /**
  72. * @brief TIM去初始化
  73. * @param timx TIM外设
  74. * @retval 无
  75. */
  76. void std_tim_deinit(TIM_t *timx)
  77. {
  78. /* 复位外设 */
  79. if(TIM1 == timx)
  80. {
  81. std_rcc_apb2_reset(RCC_PERIPH_RESET_TIM1);
  82. }
  83. else if(TIM3 == timx)
  84. {
  85. std_rcc_apb1_reset(RCC_PERIPH_RESET_TIM3);
  86. }
  87. }
  88. /**
  89. * @brief 设置std_tim_basic_init_t结构体为默认值
  90. * @param tim_init_struct TIM初始化结构体
  91. * @retval 无
  92. */
  93. void std_tim_struct_init(std_tim_basic_init_t *tim_init_struct)
  94. {
  95. tim_init_struct->prescaler = 0x0000U;
  96. tim_init_struct->counter_mode = TIM_COUNTER_MODE_UP;
  97. tim_init_struct->period = 0xFFFFU;
  98. tim_init_struct->clock_div = TIM_CLOCK_DTS_DIV1;
  99. tim_init_struct->repeat_counter = 0x0000U;
  100. }
  101. /**
  102. * @brief 配置TIM输入捕获通道
  103. * @param timx TIM外设
  104. * @param input_config TIM 输入捕获配置结构体
  105. * @param channel_id TIM 通道配置
  106. * @arg TIM_CHANNEL_1
  107. * @arg TIM_CHANNEL_2
  108. * @retval 无
  109. */
  110. void std_tim_input_capture_init(TIM_t *timx, std_tim_input_capture_init_t *input_config, uint32_t channel_id)
  111. {
  112. uint32_t tmp_value = ((channel_id & 0x01) == 0)?0U:8U;
  113. uint32_t shift_value = ((channel_id & 0x02) == 0)?0U:4U;
  114. __IO uint32_t *preg = (__IO uint32_t *)((uint32_t)(&timx->CCM1) + shift_value);
  115. /* 禁止CCxE位 */
  116. timx->CCEN &= (~(TIM_CCEN_CC1E << (channel_id << 2)));
  117. /* 选择输入源和滤波及输入预分频参数 */
  118. MODIFY_REG(*preg,
  119. ((TIM_CCM1_CC1S | TIM_CCM1_IC1F |TIM_CCM1_IC1PSC ) << tmp_value),
  120. ((input_config->input_capture_sel | (input_config->input_capture_filter << 4U) | input_config->input_capture_prescaler) << tmp_value));
  121. /* 选择极性 */
  122. std_tim_set_input_pol(timx, channel_id, input_config->input_capture_pol);
  123. }
  124. /**
  125. * @brief 设置std_tim_input_capture_init_t结构体为默认值
  126. * @param input_init_struct TIM输入捕获结构体
  127. * @retval 无
  128. */
  129. void std_tim_input_capture_struct_init(std_tim_input_capture_init_t *input_init_struct)
  130. {
  131. input_init_struct->input_capture_pol = TIM_INPUT_POL_RISING;
  132. input_init_struct->input_capture_sel = TIM_INPUT_CAPTURE_SEL_DIRECTTI;
  133. input_init_struct->input_capture_prescaler = TIM_INPUT_CAPTURE_PSC_DIV1;
  134. input_init_struct->input_capture_filter = 0x00U;
  135. }
  136. /**
  137. * @brief 配置TIM比较输出参数
  138. * @param timx TIM外设
  139. * @param output_config TIM 输出比较配置结构体
  140. * @param channel_id TIM 通道配置
  141. * @arg TIM_CHANNEL_1
  142. * @arg TIM_CHANNEL_2
  143. * @arg TIM_CHANNEL_3
  144. * @arg TIM_CHANNEL_4
  145. * @retval 无
  146. */
  147. void std_tim_output_compare_init(TIM_t *timx, std_tim_output_compare_init_t *output_config, uint32_t channel_id)
  148. {
  149. uint32_t channel_oisx = (channel_id << 1);
  150. uint32_t channel_ccxe = (channel_id << 2);
  151. /* 禁止CCxE和CCxNE位 */
  152. timx->CCEN &= (~((TIM_CCEN_CC1E | TIM_CCEN_CC1NE) << channel_ccxe));
  153. /* 选择输出比较模式 */
  154. std_tim_set_ocmode(timx, channel_id, output_config->output_compare_mode);
  155. /* 设置输出比较极性、输出使能位 */
  156. MODIFY_REG(timx->CCEN,
  157. ((TIM_CCEN_CC1P | TIM_CCEN_CC1E) << channel_ccxe),
  158. (output_config->output_pol << channel_ccxe) | (output_config->output_state << channel_ccxe));
  159. /* 配置比较匹配值 */
  160. std_tim_set_ccx_value(timx, channel_id, output_config->pulse);
  161. if (timx == TIM1)
  162. {
  163. /* 设置通道和互补输出通道的空闲状态 */
  164. MODIFY_REG(timx->CR2,
  165. ((TIM_CR2_OIS1 | TIM_CR2_OIS1N) << channel_oisx),
  166. ((output_config->output_idle_state | output_config->output_negtive_idle_state) << channel_oisx));
  167. /* 设置互补通道输出比较极性、输出使能位 */
  168. MODIFY_REG(timx->CCEN,
  169. ((TIM_CCEN_CC1NP | TIM_CCEN_CC1NE) << channel_ccxe),
  170. (output_config->output_negtive_pol << channel_ccxe) | (output_config->output_negtive_state << channel_ccxe));
  171. }
  172. }
  173. /**
  174. * @brief 设置std_tim_output_compare_init_t结构体为默认值
  175. * @param output_init_struct TIM输出结构体
  176. * @retval 无
  177. */
  178. void std_tim_output_compare_struct_init(std_tim_output_compare_init_t *output_init_struct)
  179. {
  180. output_init_struct->output_compare_mode = TIM_OUTPUT_MODE_FROZEN;
  181. output_init_struct->pulse = 0x0000U;
  182. output_init_struct->output_state = TIM_OUTPUT_DISABLE;
  183. output_init_struct->output_negtive_state = TIM_OUTPUT_NEGTIVE_DISABLE;
  184. output_init_struct->output_pol = TIM_OUTPUT_POL_HIGH;
  185. output_init_struct->output_negtive_pol = TIM_OUTPUT_NEGTIVE_POL_HIGH;
  186. output_init_struct->output_idle_state = TIM_OUTPUT_IDLE_RESET;
  187. output_init_struct->output_negtive_idle_state = TIM_OUTPUT_NEGTIVE_IDLE_RESET;
  188. }
  189. /**
  190. * @brief 断路参数初始化
  191. * @param timx TIM外设
  192. * @param bdt_init_param TIM断路参数结构体
  193. * @note 如需配置系统断路,则按照如下步骤进行配置:
  194. * 1、使能相应的系统断路源;
  195. * 2、调用std_tim_brk_source_enable()函数,禁止通道断路使能;
  196. * 3、调用std_tim_bken_enable()函数,使能BKEN。
  197. * @retval 无
  198. */
  199. void std_tim_bdt_init(TIM_t* timx, std_tim_break_init_t *bdt_init_param)
  200. {
  201. /* 配置断路基本参数 */
  202. MODIFY_REG(timx->BDT,
  203. (TIM_BDT_DTG | TIM_BDT_OSSI | TIM_BDT_OSSR),
  204. (bdt_init_param->dead_time | bdt_init_param->off_state_idle_mode | bdt_init_param->off_state_run_mode));
  205. /* 配置锁定级别,并使能断路 */
  206. MODIFY_REG(timx->BDT,
  207. (TIM_BDT_BKEN | TIM_BDT_LOCK),
  208. (bdt_init_param->break_state | bdt_init_param->lock_level));
  209. }
  210. /**
  211. * @brief 设置std_tim_break_init_t结构体为默认值
  212. * @param bdt_init_struct TIM断路参数结构体
  213. * @retval 无
  214. */
  215. void std_tim_bdt_struct_init(std_tim_break_init_t *bdt_init_struct)
  216. {
  217. bdt_init_struct->off_state_run_mode = TIM_OSSR_DISABLE;
  218. bdt_init_struct->off_state_idle_mode = TIM_OSSI_DISABLE;
  219. bdt_init_struct->lock_level = TIM_LOCK_LEVEL_OFF;
  220. bdt_init_struct->dead_time = 0x00U;
  221. bdt_init_struct->break_state = TIM_BREAK_DISABLE;
  222. }
  223. /**
  224. * @}
  225. */
  226. #endif /* STD_TIM_PERIPHERAL_USED */
  227. /**
  228. * @}
  229. */
  230. /**
  231. * @}
  232. */