基质喷涂
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.

493 lines
16 KiB

  1. //
  2. // Created by iflyt on 2025/2/28.
  3. //
  4. #include "tim_pwm.h"
  5. #include "main.h"
  6. #include <stm32f4xx_hal.h>
  7. /*
  8. GPIO的TIM通道:
  9. TIM1_CH1, PA8, PE9,
  10. TIM1_CH2, PA9, PE11
  11. TIM1_CH3, PA10, PE13
  12. TIM1_CH4, PA11, PE14
  13. TIM2_CH1, PA15 (429439) 407
  14. TIM2_CH2, PA1, PB3
  15. TIM2_CH3, PA2, PB10
  16. TIM2_CH4, PA3, PB11
  17. TIM3_CH1, PA6, PB4, PC6
  18. TIM3_CH2, PA7, PB5, PC7
  19. TIM3_CH3, PB0, PC8
  20. TIM3_CH4, PB1, PC9
  21. TIM4_CH1, PB6, PD12
  22. TIM4_CH2, PB7, PD13
  23. TIM4_CH3, PB8, PD14
  24. TIM4_CH4, PB9, PD15
  25. TIM5_CH1, PA0, PH10
  26. TIM5_CH2, PA1, PH11
  27. TIM5_CH3, PA2, PH12
  28. TIM5_CH4, PA3, PI10
  29. TIM8_CH1, PC6, PI5
  30. TIM8_CH2, PC7, PI6
  31. TIM8_CH3, PC8, PI7
  32. TIM8_CH4, PC9, PI2
  33. TIM9_CH1, PA2, PE5
  34. TIM9_CH2, PA3, PE6
  35. TIM10_CH1, PB8, PF6
  36. TIM11_CH1, PB9, PF7
  37. TIM12_CH1, PB14, PH6
  38. TIM12_CH2, PB15, PH9
  39. TIM13_CH1, PA6, PF8
  40. TIM14_CH1, PA7, PF9
  41. APB1 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14
  42. APB2 TIM1, TIM8 ,TIM9, TIM10, TIM11
  43. APB1 TIMxCLK = SystemCoreClock / 2; 84M
  44. APB2 TIMxCLK = SystemCoreClock; 168M
  45. */
  46. /*
  47. *********************************************************************************************************
  48. * : bsp_RCC_GPIO_Enable
  49. * : 使GPIO时钟
  50. * : GPIOx GPIOA - GPIOI
  51. * :
  52. *********************************************************************************************************
  53. */
  54. void bsp_RCC_GPIO_Enable(GPIO_TypeDef* GPIOx)
  55. {
  56. if (GPIOx == GPIOA) __HAL_RCC_GPIOA_CLK_ENABLE();
  57. else if (GPIOx == GPIOB) __HAL_RCC_GPIOB_CLK_ENABLE();
  58. else if (GPIOx == GPIOC) __HAL_RCC_GPIOC_CLK_ENABLE();
  59. else if (GPIOx == GPIOD) __HAL_RCC_GPIOD_CLK_ENABLE();
  60. else if (GPIOx == GPIOE) __HAL_RCC_GPIOE_CLK_ENABLE();
  61. else if (GPIOx == GPIOF) __HAL_RCC_GPIOF_CLK_ENABLE();
  62. else if (GPIOx == GPIOG) __HAL_RCC_GPIOG_CLK_ENABLE();
  63. else if (GPIOx == GPIOH) __HAL_RCC_GPIOH_CLK_ENABLE();
  64. else if (GPIOx == GPIOI) __HAL_RCC_GPIOI_CLK_ENABLE();
  65. }
  66. /*
  67. *********************************************************************************************************
  68. * : bsp_RCC_TIM_Enable
  69. * : 使TIM RCC
  70. * : TIMx TIM1 - TIM14
  71. * :
  72. *********************************************************************************************************
  73. */
  74. void bsp_RCC_TIM_Enable(TIM_TypeDef* TIMx)
  75. {
  76. if (TIMx == TIM1) __HAL_RCC_TIM1_CLK_ENABLE();
  77. else if (TIMx == TIM2) __HAL_RCC_TIM2_CLK_ENABLE();
  78. else if (TIMx == TIM3) __HAL_RCC_TIM3_CLK_ENABLE();
  79. else if (TIMx == TIM4) __HAL_RCC_TIM4_CLK_ENABLE();
  80. else if (TIMx == TIM5) __HAL_RCC_TIM5_CLK_ENABLE();
  81. else if (TIMx == TIM6) __HAL_RCC_TIM6_CLK_ENABLE();
  82. else if (TIMx == TIM7) __HAL_RCC_TIM7_CLK_ENABLE();
  83. else if (TIMx == TIM8) __HAL_RCC_TIM8_CLK_ENABLE();
  84. else if (TIMx == TIM9) __HAL_RCC_TIM9_CLK_ENABLE();
  85. else if (TIMx == TIM10) __HAL_RCC_TIM10_CLK_ENABLE();
  86. else if (TIMx == TIM11) __HAL_RCC_TIM11_CLK_ENABLE();
  87. else if (TIMx == TIM12) __HAL_RCC_TIM12_CLK_ENABLE();
  88. else if (TIMx == TIM13) __HAL_RCC_TIM13_CLK_ENABLE();
  89. else if (TIMx == TIM14) __HAL_RCC_TIM14_CLK_ENABLE();
  90. else
  91. {
  92. //Error_Handler(__FILE__, __LINE__);
  93. }
  94. }
  95. /*
  96. *********************************************************************************************************
  97. * : bsp_RCC_TIM_Disable
  98. * : TIM RCC
  99. * : TIMx TIM1 - TIM14
  100. * : TIM外设时钟名
  101. *********************************************************************************************************
  102. */
  103. void bsp_RCC_TIM_Disable(TIM_TypeDef* TIMx)
  104. {
  105. /*
  106. APB1 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14
  107. APB2 TIM1, TIM8 ,TIM9, TIM10, TIM11
  108. */
  109. if (TIMx == TIM1) __HAL_RCC_TIM1_CLK_DISABLE();
  110. else if (TIMx == TIM2) __HAL_RCC_TIM2_CLK_DISABLE();
  111. else if (TIMx == TIM3) __HAL_RCC_TIM3_CLK_DISABLE();
  112. else if (TIMx == TIM4) __HAL_RCC_TIM4_CLK_DISABLE();
  113. else if (TIMx == TIM5) __HAL_RCC_TIM5_CLK_DISABLE();
  114. else if (TIMx == TIM6) __HAL_RCC_TIM6_CLK_DISABLE();
  115. else if (TIMx == TIM7) __HAL_RCC_TIM7_CLK_DISABLE();
  116. else if (TIMx == TIM8) __HAL_RCC_TIM8_CLK_DISABLE();
  117. else if (TIMx == TIM9) __HAL_RCC_TIM9_CLK_DISABLE();
  118. else if (TIMx == TIM10) __HAL_RCC_TIM10_CLK_DISABLE();
  119. else if (TIMx == TIM11) __HAL_RCC_TIM11_CLK_DISABLE();
  120. else if (TIMx == TIM12) __HAL_RCC_TIM12_CLK_DISABLE();
  121. else if (TIMx == TIM13) __HAL_RCC_TIM13_CLK_DISABLE();
  122. else if (TIMx == TIM14) __HAL_RCC_TIM14_CLK_DISABLE();
  123. else
  124. {
  125. //Error_Handler(__FILE__, __LINE__);
  126. }
  127. }
  128. /*
  129. *********************************************************************************************************
  130. * : bsp_GetAFofTIM
  131. * : TIM AF寄存器配置
  132. * : TIMx TIM1 - TIM14
  133. * : AF寄存器配置
  134. *********************************************************************************************************
  135. */
  136. uint8_t bsp_GetAFofTIM(TIM_TypeDef* TIMx)
  137. {
  138. uint8_t ret = 0;
  139. if (TIMx == TIM1) ret = GPIO_AF1_TIM1;
  140. else if (TIMx == TIM2) ret = GPIO_AF1_TIM2;
  141. else if (TIMx == TIM3) ret = GPIO_AF2_TIM3;
  142. else if (TIMx == TIM4) ret = GPIO_AF2_TIM4;
  143. else if (TIMx == TIM5) ret = GPIO_AF2_TIM5;
  144. else if (TIMx == TIM8) ret = GPIO_AF3_TIM8;
  145. else if (TIMx == TIM9) ret = GPIO_AF3_TIM9;
  146. else if (TIMx == TIM10) ret = GPIO_AF3_TIM10;
  147. else if (TIMx == TIM11) ret = GPIO_AF3_TIM11;
  148. else if (TIMx == TIM12) ret = GPIO_AF9_TIM12;
  149. else if (TIMx == TIM13) ret = GPIO_AF9_TIM13;
  150. else if (TIMx == TIM14) ret = GPIO_AF9_TIM14;
  151. else
  152. {
  153. //Error_Handler(__FILE__, __LINE__);
  154. }
  155. return ret;
  156. }
  157. /*
  158. *********************************************************************************************************
  159. * : bsp_ConfigTimGpio
  160. * : GPIO和TIM时钟 GPIO连接到TIM输出通道
  161. * : GPIOx : GPIOA - GPIOK
  162. * GPIO_PinX : GPIO_PIN_0 - GPIO__PIN_15
  163. * TIMx : TIM1 - TIM14
  164. * :
  165. *********************************************************************************************************
  166. */
  167. void bsp_ConfigTimGpio(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinX, TIM_TypeDef* TIMx)
  168. {
  169. GPIO_InitTypeDef GPIO_InitStruct;
  170. /* 使能GPIO时钟 */
  171. bsp_RCC_GPIO_Enable(GPIOx);
  172. /* 使能TIM时钟 */
  173. bsp_RCC_TIM_Enable(TIMx);
  174. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  175. GPIO_InitStruct.Pull = GPIO_PULLUP;
  176. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  177. GPIO_InitStruct.Alternate = bsp_GetAFofTIM(TIMx);
  178. GPIO_InitStruct.Pin = GPIO_PinX;
  179. HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
  180. }
  181. /*
  182. *********************************************************************************************************
  183. * : bsp_ConfigGpioOut
  184. * : GPIO为推挽输出PWM输出0100
  185. * : GPIOx : GPIOA - GPIOK
  186. * GPIO_PinX : GPIO_PIN_0 - GPIO__PIN_15
  187. * :
  188. *********************************************************************************************************
  189. */
  190. void bsp_ConfigGpioOut(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinX)
  191. {
  192. GPIO_InitTypeDef GPIO_InitStruct;
  193. bsp_RCC_GPIO_Enable(GPIOx); /* 使能GPIO时钟 */
  194. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  195. GPIO_InitStruct.Pull = GPIO_NOPULL;
  196. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  197. GPIO_InitStruct.Pin = GPIO_PinX;
  198. HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
  199. }
  200. /*
  201. *********************************************************************************************************
  202. * : bsp_SetTIMOutPWM
  203. * : PWM信号的频率和占空比. 00GPIO输出0
  204. * 0100%GPIO输出1.
  205. * : GPIOx : GPIOA - GPIOK
  206. * GPIO_Pin : GPIO_PIN_0 - GPIO__PIN_15
  207. * TIMx : TIM1 - TIM14
  208. * _ucChannel使1 - 4
  209. * _ulFreq : PWM信号频率Hz (100MHz0
  210. * _ulDutyCycle : PWM信号占空比: 500050.00%
  211. * :
  212. *********************************************************************************************************
  213. */
  214. void bsp_SetTIMOutPWM(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TIM_TypeDef* TIMx, uint8_t _ucChannel,
  215. uint32_t _ulFreq, uint32_t _ulDutyCycle)
  216. {
  217. TIM_HandleTypeDef TimHandle = {0};
  218. TIM_OC_InitTypeDef sConfig = {0};
  219. uint16_t usPeriod;
  220. uint16_t usPrescaler;
  221. uint32_t pulse;
  222. uint32_t uiTIMxCLK;
  223. const uint16_t TimChannel[6+1] = {0, TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4};
  224. if (_ucChannel > 6)
  225. {
  226. //Error_Handler(__FILE__, __LINE__);
  227. }
  228. if (_ulDutyCycle == 0)
  229. {
  230. //bsp_RCC_TIM_Disable(TIMx); /* 关闭TIM时钟, 可能影响其他通道 */
  231. bsp_ConfigGpioOut(GPIOx, GPIO_Pin); /* 配置GPIO为推挽输出 */
  232. HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_RESET); /* PWM = 0 */
  233. return;
  234. }
  235. else if (_ulDutyCycle == 10000)
  236. {
  237. //bsp_RCC_TIM_Disable(TIMx); /* 关闭TIM时钟, 可能影响其他通道 */
  238. bsp_ConfigGpioOut(GPIOx, GPIO_Pin); /* 配置GPIO为推挽输出 */
  239. HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_SET); /* PWM = 1 */
  240. return;
  241. }
  242. /* 下面是PWM输出 */
  243. bsp_ConfigTimGpio(GPIOx, GPIO_Pin, TIMx); /* 使能GPIO和TIM时钟,并连接TIM通道到GPIO */
  244. /*-----------------------------------------------------------------------
  245. system_stm32f4xx.c void SetSysClock(void)
  246. HCLK = SYSCLK / 1 (AHB1Periph)
  247. PCLK2 = HCLK / 2 (APB2Periph)
  248. PCLK1 = HCLK / 4 (APB1Periph)
  249. APB1 prescaler != 1, APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2;
  250. APB2 prescaler != 1, APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock;
  251. APB1 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13,TIM14
  252. APB2 TIM1, TIM8 ,TIM9, TIM10, TIM11
  253. ----------------------------------------------------------------------- */
  254. if ((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM9) || (TIMx == TIM10) || (TIMx == TIM11))
  255. {
  256. /* APB2 定时器时钟 = 168M */
  257. uiTIMxCLK = SystemCoreClock;
  258. }
  259. else
  260. {
  261. /* APB1 定时器 = 84M */
  262. uiTIMxCLK = SystemCoreClock / 2;
  263. }
  264. if (_ulFreq < 100)
  265. {
  266. usPrescaler = 10000 - 1; /* 分频比 = 10000 */
  267. usPeriod = (uiTIMxCLK / 10000) / _ulFreq - 1; /* 自动重装的值 */
  268. }
  269. else if (_ulFreq < 3000)
  270. {
  271. usPrescaler = 100 - 1; /* 分频比 = 100 */
  272. usPeriod = (uiTIMxCLK / 100) / _ulFreq - 1; /* 自动重装的值 */
  273. }
  274. else /* 大于4K的频率,无需分频 */
  275. {
  276. usPrescaler = 0; /* 分频比 = 1 */
  277. usPeriod = uiTIMxCLK / _ulFreq - 1; /* 自动重装的值 */
  278. }
  279. pulse = (_ulDutyCycle * usPeriod) / 10000;
  280. HAL_TIM_PWM_DeInit(&TimHandle);
  281. #if 1
  282. // Clock straight from internal clock.
  283. // This can be used to chain clocks to get super-long timer periods
  284. // much longer than maximum settings of a single timer would allow.
  285. TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  286. sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  287. if (HAL_TIM_ConfigClockSource(&TimHandle, &sClockSourceConfig) != HAL_OK) {
  288. Error_Handler();
  289. }
  290. #endif
  291. /* PWM频率 = TIMxCLK / usPrescaler + 1)/usPeriod + 1)*/
  292. TimHandle.Instance = TIMx;
  293. TimHandle.Init.Prescaler = usPrescaler;
  294. TimHandle.Init.Period = usPeriod;
  295. TimHandle.Init.ClockDivision = 0;
  296. TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
  297. TimHandle.Init.RepetitionCounter = 0;
  298. TimHandle.Init.AutoReloadPreload = 0;
  299. if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK)
  300. {
  301. //Error_Handler(__FILE__, __LINE__);
  302. }
  303. /* 配置定时器PWM输出通道 */
  304. sConfig.OCMode = TIM_OCMODE_PWM1;
  305. sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
  306. sConfig.OCFastMode = TIM_OCFAST_DISABLE;
  307. sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  308. sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  309. sConfig.OCIdleState = TIM_OCIDLESTATE_RESET;
  310. /* 占空比 */
  311. sConfig.Pulse = pulse;
  312. if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TimChannel[_ucChannel]) != HAL_OK)
  313. {
  314. //Error_Handler(__FILE__, __LINE__);
  315. }
  316. /* 启动PWM输出 */
  317. if (HAL_TIM_PWM_Start(&TimHandle, TimChannel[_ucChannel]) != HAL_OK)
  318. {
  319. //Error_Handler(__FILE__, __LINE__);
  320. }
  321. }
  322. /*
  323. *********************************************************************************************************
  324. * : bsp_SetTIMforInt
  325. * : TIM和NVIC
  326. * : TIMx :
  327. * _ulFreq : Hz 0
  328. * _PreemptionPriority :
  329. * _SubPriority :
  330. * :
  331. *********************************************************************************************************
  332. */
  333. /*
  334. TIM定时中断服务程序范例
  335. void TIM6_DAC_IRQHandler(void)
  336. {
  337. if((TIM6->SR & TIM_FLAG_UPDATE) != RESET)
  338. {
  339. TIM6->SR = ~ TIM_FLAG_UPDATE;
  340. //添加用户代码
  341. }
  342. }
  343. */
  344. void bsp_SetTIMforInt(TIM_TypeDef* TIMx, uint32_t _ulFreq, uint8_t _PreemptionPriority, uint8_t _SubPriority)
  345. {
  346. TIM_HandleTypeDef TimHandle = {0};
  347. uint16_t usPeriod;
  348. uint16_t usPrescaler;
  349. uint32_t uiTIMxCLK;
  350. /* 使能TIM时钟 */
  351. bsp_RCC_TIM_Enable(TIMx);
  352. /*-----------------------------------------------------------------------
  353. system_stm32f4xx.c void SetSysClock(void)
  354. HCLK = SYSCLK / 1 (AHB1Periph)
  355. PCLK2 = HCLK / 2 (APB2Periph)
  356. PCLK1 = HCLK / 4 (APB1Periph)
  357. APB1 prescaler != 1, APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2;
  358. APB2 prescaler != 1, APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock;
  359. APB1 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13,TIM14
  360. APB2 TIM1, TIM8 ,TIM9, TIM10, TIM11
  361. ----------------------------------------------------------------------- */
  362. if ((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM9) || (TIMx == TIM10) || (TIMx == TIM11))
  363. {
  364. /* APB2 定时器时钟 = 168M */
  365. uiTIMxCLK = SystemCoreClock;
  366. }
  367. else
  368. {
  369. /* APB1 定时器 = 84M */
  370. uiTIMxCLK = SystemCoreClock / 2;
  371. }
  372. if (_ulFreq < 100)
  373. {
  374. usPrescaler = 10000 - 1; /* 分频比 = 10000 */
  375. usPeriod = (uiTIMxCLK / 10000) / _ulFreq - 1; /* 自动重装的值 */
  376. }
  377. else if (_ulFreq < 3000)
  378. {
  379. usPrescaler = 100 - 1; /* 分频比 = 100 */
  380. usPeriod = (uiTIMxCLK / 100) / _ulFreq - 1; /* 自动重装的值 */
  381. }
  382. else /* 大于4K的频率,无需分频 */
  383. {
  384. usPrescaler = 0; /* 分频比 = 1 */
  385. usPeriod = uiTIMxCLK / _ulFreq - 1; /* 自动重装的值 */
  386. }
  387. /*
  388. = TIMxCLK / usPrescaler + 1/usPeriod + 1
  389. */
  390. TimHandle.Instance = TIMx;
  391. TimHandle.Init.Prescaler = usPrescaler;
  392. TimHandle.Init.Period = usPeriod;
  393. TimHandle.Init.ClockDivision = 0;
  394. TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
  395. TimHandle.Init.RepetitionCounter = 0;
  396. TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  397. if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
  398. {
  399. //Error_Handler(__FILE__, __LINE__);
  400. }
  401. /* 使能定时器中断 */
  402. __HAL_TIM_ENABLE_IT(&TimHandle, TIM_IT_UPDATE);
  403. /* 配置TIM定时更新中断 (Update) */
  404. {
  405. uint8_t irq = 0; /* 中断号, 定义在 stm32h7xx.h */
  406. if (TIMx == TIM1) irq = TIM1_UP_TIM10_IRQn;
  407. else if (TIMx == TIM2) irq = TIM2_IRQn;
  408. else if (TIMx == TIM3) irq = TIM3_IRQn;
  409. else if (TIMx == TIM4) irq = TIM4_IRQn;
  410. else if (TIMx == TIM5) irq = TIM5_IRQn;
  411. else if (TIMx == TIM6) irq = TIM6_DAC_IRQn;
  412. else if (TIMx == TIM7) irq = TIM7_IRQn;
  413. else if (TIMx == TIM8) irq = TIM8_UP_TIM13_IRQn;
  414. else if (TIMx == TIM9) irq = TIM1_BRK_TIM9_IRQn;
  415. else if (TIMx == TIM10) irq = TIM1_UP_TIM10_IRQn;
  416. else if (TIMx == TIM11) irq = TIM1_TRG_COM_TIM11_IRQn;
  417. else if (TIMx == TIM12) irq = TIM8_BRK_TIM12_IRQn;
  418. else if (TIMx == TIM13) irq = TIM8_UP_TIM13_IRQn;
  419. else if (TIMx == TIM14) irq = TIM8_TRG_COM_TIM14_IRQn;
  420. else
  421. {
  422. // Error_Handler(__FILE__, __LINE__);
  423. }
  424. HAL_NVIC_SetPriority((IRQn_Type)irq, _PreemptionPriority, _SubPriority);
  425. HAL_NVIC_EnableIRQ((IRQn_Type)irq);
  426. }
  427. HAL_TIM_Base_Start(&TimHandle);
  428. }
  429. /***************************** (END OF FILE) *********************************/