• (STM32)从零开始的RT-Thread之旅--PWM驱动ST7735调光


    上一章我们先用SPI读取到了LCD的ID,这一章则是使用PWM调光点亮屏幕,因为测试这块屏幕时,发现直接设置背光引脚为高好像无法点亮,好像必须使用PWM调光,不过反正后面调节亮度还是需要PWM,索性先打通PWM。但这其中官方留的坑还是挺多的,简单的一个PWM因为需要契合内核驱动框架调了半天。

    一如之前配置SPI的时候先配置RT-Thread Settings:

    如果图形界面没有PWM,随便右键一个图标,点击配置项。

    然后还是到board.h中定义相关的宏定义:

    看一下介绍,结合上一章所讲,大致调用流程也很清晰。如果你在CubeMX中配置了相关PWM,就会生成这两个函数:

    此时编译后会发现存在问题:

    打开pwm_config.h中可以看到PWM_CONFIG是从PWM2开始配置的:

    如果使用的PWM1则需要仿照现有的添加一个PWM1的:

     这里 tim_handle.Instance 也就是我们的PWM1对应的定时器是TIM1,名字是"pwm1",这个名字和我们之前用SPI4注册"spi40"设备时用的总线名字一样,我们到时候会通过一个函数搜索到它,如官方给的例子:

    再次编译发现还回有问题,问题出在drv_pwm_setdrv_pwm_get这两个函数中,这是因为内核没有把H7系列的芯片包含进去:

    可以看到这里的内核驱动代码还不完善,其实这里主要是为了获取 tim_clock 这个变量,也就是定时器时钟,但是对于H7来说,确定用的哪个定时器很重要。详细可以参考:

    H7定时器

    这个应该是硬汉出的教程,别人转载的。这里我讲一下我是用的TIM1是怎么配置的,你可以根据需要配置你自己的定时器。这里讲解一下怎么由时钟树理解时钟走向。

    首先我们进到 HAL_RCC_GetPCLK2Freq 这个函数中,如果你定时器挂载在APB1上,则应该使用的是 HAL_RCC_GetPCLK1Freq 这个函数获取PCLK1的频率。为什么需要用这个函数?我们从时钟树上理一下,这部分时钟树如下:

    TIM1挂载在APB2下,时钟源是 rcc_timy_ker_ck ,我们需要先确定 rcc_pclk2的频率,也就是APB2总线的频率,它又来自于 rcc_hclk ,也就是AHB1/2的时钟,所以我们进入函数HAL_RCC_GetPCLK2Freq 可以看到:

    首先我们通过HAL_RCC_GetHCLKFreq()这个函数获取到HCLK的时钟频率,然后拆分后面的部分,(RCC->D2CFGR & RCC_D2CFGR_D2PPRE2)>> RCC_D2CFGR_D2PPRE2_Pos 是为了获取 RCC_D2CFGR_D2PPRE2 寄存器的值,原理如下:

    获取到 RCC_D2CFGR_D2PPRE2 寄存器的值后,查表:

    比如这个寄存器的值是 110,即6,D1CorePrescTable[6] = 3,HCLK的时钟右移3,相当于除以8,正好和上图中计算110:rcc_pclk2的情况相同。然后根据这个时钟去计算定时器时钟,这又分为两个情况:

    源码中我们可以看到在使用 HAL_RCC_GetPCLK2Freq 获取定时器时钟的情况中只有乘2这一种情况:

    但其实应该是两种情况,我这里在CubeMX中 D2PPRE2 寄存器选择的是除以2,所以这里乘2是没有关系的: 

    如果在CubeMX中D2PPRE2选择1,你会发现定时器那里会自动选为除以1,但是选1的话可以看到会有如下提示:

    APB2最大只能120MHz,选1则系统主频最高只能240MHz了。 

    修改完这里,编译即可正常通过。然后我们就可以开始调用官方给的接口函数控制PWM了:

    1. #include
    2. #include
    3. #include "mpwm.h"
    4. #include
    5. struct rt_device_pwm *pwm_lcd;
    6. static uint32_t mpulse = 0;
    7. void mpwm_set(uint32_t pulse)
    8. {
    9. mpulse = pulse;
    10. rt_pwm_set(pwm_lcd,2,1000,pulse);
    11. }
    12. uint32_t mpwm_get(void)
    13. {
    14. return mpulse;
    15. }
    16. void mpwm_init(void)
    17. {
    18. pwm_lcd = (struct rt_device_pwm *)rt_device_find("pwm1");
    19. if(!pwm_lcd)
    20. {
    21. rt_kprintf("pwm1 can't find\n");
    22. }
    23. rt_pwm_enable(pwm_lcd,2);
    24. rt_pwm_set(pwm_lcd,2,1000,0);
    25. }

    这里简单写了几个接口函数,实际直接使用,发现并没有输出,主要的坑已经全踩过了!懒得给官方提PR了,留给后人完善吧。

    STM32的PWM所使用定时的初始化在内核驱动 drv_pwm.c 文件中的 stm32_pwm_init的 stm32_hw_pwm_init 函数里:

    注意上图红色方框,你使用哪个定时器就需要添加哪个定时器的时钟使能。其次高级定时器一些额外的设置也需要添加,你如果不知道你用的定时器需不需要添加这些,请参照你使用CubeMX生成的定时器配置,我这里是在main.c中:

    根据上面函数的配置,添加到这个函数里: 

    我这里使用的TIM1需要配置刹车和死区配置。添加完这些,你会发现还是无法使用PWM输出,这是因为是使能函数有问题:

    在同个文件中还有pwm使能函数,这个函数中所使用的 HAL_TIM_PWM_Start 函数只对普通定时器有效,TIM1是高级定时器,所以应该使用的函数是:HAL_TIMEx_PWMN_Start 。我这里不考虑其他情况,只针对我自己的工程做以下修改:

    此时再使用PWM即可正常使用。 

    下一章:

    (STM32)从零开始的RT-Thread之旅--SPI驱动ST7735(2)

    附:

    drv_pwm.c(仅供参考):

    1. /*
    2. * Copyright (c) 2006-2018, RT-Thread Development Team
    3. *
    4. * SPDX-License-Identifier: Apache-2.0
    5. *
    6. * Change Logs:
    7. * Date Author Notes
    8. * 2018-12-13 zylx first version
    9. */
    10. #include
    11. #include
    12. #include
    13. #ifdef RT_USING_PWM
    14. #include "drv_config.h"
    15. #define DRV_DEBUG
    16. #define LOG_TAG "drv.pwm"
    17. #include
    18. #define MAX_PERIOD 65535
    19. #define MIN_PERIOD 3
    20. #define MIN_PULSE 2
    21. extern void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
    22. enum
    23. {
    24. #ifdef BSP_USING_PWM1
    25. PWM1_INDEX,
    26. #endif
    27. #ifdef BSP_USING_PWM2
    28. PWM2_INDEX,
    29. #endif
    30. #ifdef BSP_USING_PWM3
    31. PWM3_INDEX,
    32. #endif
    33. #ifdef BSP_USING_PWM4
    34. PWM4_INDEX,
    35. #endif
    36. #ifdef BSP_USING_PWM5
    37. PWM5_INDEX,
    38. #endif
    39. #ifdef BSP_USING_PWM6
    40. PWM6_INDEX,
    41. #endif
    42. #ifdef BSP_USING_PWM7
    43. PWM7_INDEX,
    44. #endif
    45. #ifdef BSP_USING_PWM8
    46. PWM8_INDEX,
    47. #endif
    48. #ifdef BSP_USING_PWM9
    49. PWM9_INDEX,
    50. #endif
    51. #ifdef BSP_USING_PWM10
    52. PWM10_INDEX,
    53. #endif
    54. #ifdef BSP_USING_PWM11
    55. PWM11_INDEX,
    56. #endif
    57. #ifdef BSP_USING_PWM12
    58. PWM12_INDEX,
    59. #endif
    60. #ifdef BSP_USING_PWM13
    61. PWM13_INDEX,
    62. #endif
    63. #ifdef BSP_USING_PWM14
    64. PWM14_INDEX,
    65. #endif
    66. #ifdef BSP_USING_PWM15
    67. PWM15_INDEX,
    68. #endif
    69. #ifdef BSP_USING_PWM16
    70. PWM16_INDEX,
    71. #endif
    72. #ifdef BSP_USING_PWM17
    73. PWM17_INDEX,
    74. #endif
    75. };
    76. struct stm32_pwm
    77. {
    78. struct rt_device_pwm pwm_device;
    79. TIM_HandleTypeDef tim_handle;
    80. rt_uint8_t channel;
    81. char *name;
    82. };
    83. static struct stm32_pwm stm32_pwm_obj[] =
    84. {
    85. #ifdef BSP_USING_PWM1
    86. PWM1_CONFIG,
    87. #endif
    88. #ifdef BSP_USING_PWM2
    89. PWM2_CONFIG,
    90. #endif
    91. #ifdef BSP_USING_PWM3
    92. PWM3_CONFIG,
    93. #endif
    94. #ifdef BSP_USING_PWM4
    95. PWM4_CONFIG,
    96. #endif
    97. #ifdef BSP_USING_PWM5
    98. PWM5_CONFIG,
    99. #endif
    100. #ifdef BSP_USING_PWM6
    101. PWM6_CONFIG,
    102. #endif
    103. #ifdef BSP_USING_PWM7
    104. PWM7_CONFIG,
    105. #endif
    106. #ifdef BSP_USING_PWM8
    107. PWM8_CONFIG,
    108. #endif
    109. #ifdef BSP_USING_PWM9
    110. PWM9_CONFIG,
    111. #endif
    112. #ifdef BSP_USING_PWM10
    113. PWM10_CONFIG,
    114. #endif
    115. #ifdef BSP_USING_PWM11
    116. PWM11_CONFIG,
    117. #endif
    118. #ifdef BSP_USING_PWM12
    119. PWM12_CONFIG,
    120. #endif
    121. #ifdef BSP_USING_PWM13
    122. PWM13_CONFIG,
    123. #endif
    124. #ifdef BSP_USING_PWM14
    125. PWM14_CONFIG,
    126. #endif
    127. #ifdef BSP_USING_PWM15
    128. PWM15_CONFIG,
    129. #endif
    130. #ifdef BSP_USING_PWM16
    131. PWM16_CONFIG,
    132. #endif
    133. #ifdef BSP_USING_PWM17
    134. PWM17_CONFIG,
    135. #endif
    136. };
    137. static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
    138. static struct rt_pwm_ops drv_ops =
    139. {
    140. drv_pwm_control
    141. };
    142. static rt_err_t drv_pwm_enable(TIM_HandleTypeDef *htim, struct rt_pwm_configuration *configuration, rt_bool_t enable)
    143. {
    144. /* Converts the channel number to the channel number of Hal library */
    145. rt_uint32_t channel = 0x04 * (configuration->channel - 1);
    146. // if (!enable)
    147. // {
    148. // HAL_TIM_PWM_Stop(htim, channel);
    149. // }
    150. // else
    151. // {
    152. // HAL_TIM_PWM_Start(htim, channel);
    153. // }
    154. if (!enable)
    155. {
    156. HAL_TIMEx_PWMN_Stop(htim, channel);
    157. }
    158. else
    159. {
    160. HAL_TIMEx_PWMN_Start(htim, channel);
    161. }
    162. return RT_EOK;
    163. }
    164. static rt_err_t drv_pwm_get(TIM_HandleTypeDef *htim, struct rt_pwm_configuration *configuration)
    165. {
    166. /* Converts the channel number to the channel number of Hal library */
    167. rt_uint32_t channel = 0x04 * (configuration->channel - 1);
    168. rt_uint64_t tim_clock;
    169. #if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
    170. if (htim->Instance == TIM9 || htim->Instance == TIM10 || htim->Instance == TIM11)
    171. #elif defined(SOC_SERIES_STM32L4)
    172. if (htim->Instance == TIM15 || htim->Instance == TIM16 || htim->Instance == TIM17)
    173. #elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7)
    174. if (0)
    175. #elif defined(SOC_SERIES_STM32H7)
    176. if (1)
    177. #endif
    178. {
    179. #if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0)
    180. tim_clock = HAL_RCC_GetPCLK2Freq() * 2;
    181. #endif
    182. }
    183. else
    184. {
    185. #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
    186. tim_clock = HAL_RCC_GetPCLK1Freq();
    187. #else
    188. tim_clock = HAL_RCC_GetPCLK1Freq() * 2;
    189. #endif
    190. }
    191. if (__HAL_TIM_GET_CLOCKDIVISION(htim) == TIM_CLOCKDIVISION_DIV2)
    192. {
    193. tim_clock = tim_clock / 2;
    194. }
    195. else if (__HAL_TIM_GET_CLOCKDIVISION(htim) == TIM_CLOCKDIVISION_DIV4)
    196. {
    197. tim_clock = tim_clock / 4;
    198. }
    199. /* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */
    200. tim_clock /= 1000000UL;
    201. configuration->period = (__HAL_TIM_GET_AUTORELOAD(htim) + 1) * (htim->Instance->PSC + 1) * 1000UL / tim_clock;
    202. configuration->pulse = (__HAL_TIM_GET_COMPARE(htim, channel) + 1) * (htim->Instance->PSC + 1) * 1000UL / tim_clock;
    203. return RT_EOK;
    204. }
    205. static rt_err_t drv_pwm_set(TIM_HandleTypeDef *htim, struct rt_pwm_configuration *configuration)
    206. {
    207. rt_uint32_t period, pulse;
    208. rt_uint64_t tim_clock, psc;
    209. /* Converts the channel number to the channel number of Hal library */
    210. rt_uint32_t channel = 0x04 * (configuration->channel - 1);
    211. #if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
    212. if (htim->Instance == TIM9 || htim->Instance == TIM10 || htim->Instance == TIM11)
    213. #elif defined(SOC_SERIES_STM32L4)
    214. if (htim->Instance == TIM15 || htim->Instance == TIM16 || htim->Instance == TIM17)
    215. #elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
    216. if (0)
    217. #elif defined(SOC_SERIES_STM32H7)
    218. if (1)
    219. #endif
    220. {
    221. #if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0)
    222. tim_clock = HAL_RCC_GetPCLK2Freq() * 2;
    223. #endif
    224. }
    225. else
    226. {
    227. #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
    228. tim_clock = HAL_RCC_GetPCLK1Freq();
    229. #else
    230. tim_clock = HAL_RCC_GetPCLK1Freq() * 2;
    231. #endif
    232. }
    233. /* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */
    234. tim_clock /= 1000000UL;
    235. period = (unsigned long long)configuration->period * tim_clock / 1000ULL ;
    236. psc = period / MAX_PERIOD + 1;
    237. period = period / psc;
    238. __HAL_TIM_SET_PRESCALER(htim, psc - 1);
    239. if (period < MIN_PERIOD)
    240. {
    241. period = MIN_PERIOD;
    242. }
    243. __HAL_TIM_SET_AUTORELOAD(htim, period - 1);
    244. pulse = (unsigned long long)configuration->pulse * tim_clock / psc / 1000ULL;
    245. if (pulse < MIN_PULSE)
    246. {
    247. pulse = MIN_PULSE;
    248. }
    249. else if (pulse > period)
    250. {
    251. pulse = period;
    252. }
    253. __HAL_TIM_SET_COMPARE(htim, channel, pulse - 1);
    254. __HAL_TIM_SET_COUNTER(htim, 0);
    255. /* Update frequency value */
    256. HAL_TIM_GenerateEvent(htim, TIM_EVENTSOURCE_UPDATE);
    257. return RT_EOK;
    258. }
    259. static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
    260. {
    261. struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
    262. TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)device->parent.user_data;
    263. switch (cmd)
    264. {
    265. case PWM_CMD_ENABLE:
    266. return drv_pwm_enable(htim, configuration, RT_TRUE);
    267. case PWM_CMD_DISABLE:
    268. return drv_pwm_enable(htim, configuration, RT_FALSE);
    269. case PWM_CMD_SET:
    270. return drv_pwm_set(htim, configuration);
    271. case PWM_CMD_GET:
    272. return drv_pwm_get(htim, configuration);
    273. default:
    274. return RT_EINVAL;
    275. }
    276. }
    277. static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device)
    278. {
    279. rt_err_t result = RT_EOK;
    280. TIM_HandleTypeDef *tim = RT_NULL;
    281. TIM_OC_InitTypeDef oc_config = {0};
    282. TIM_MasterConfigTypeDef master_config = {0};
    283. TIM_ClockConfigTypeDef clock_config = {0};
    284. TIM_BreakDeadTimeConfigTypeDef break_dead_time_config = {0};
    285. RT_ASSERT(device != RT_NULL);
    286. //Add TIMx CLK enable
    287. __HAL_RCC_TIM1_CLK_ENABLE();
    288. tim = (TIM_HandleTypeDef *)&device->tim_handle;
    289. /* configure the timer to pwm mode */
    290. tim->Init.Prescaler = 0;
    291. tim->Init.CounterMode = TIM_COUNTERMODE_UP;
    292. tim->Init.Period = 200;
    293. tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    294. #if defined(SOC_SERIES_STM32H7)
    295. tim->Init.RepetitionCounter = 0;
    296. #endif
    297. #if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32H7)
    298. tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    299. #endif
    300. if (HAL_TIM_PWM_Init(tim) != HAL_OK)
    301. {
    302. LOG_E("%s pwm init failed", device->name);
    303. result = -RT_ERROR;
    304. goto __exit;
    305. }
    306. clock_config.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    307. if (HAL_TIM_ConfigClockSource(tim, &clock_config) != HAL_OK)
    308. {
    309. LOG_E("%s clock init failed", device->name);
    310. result = -RT_ERROR;
    311. goto __exit;
    312. }
    313. master_config.MasterOutputTrigger = TIM_TRGO_RESET;
    314. #if defined(SOC_SERIES_STM32H7)
    315. master_config.MasterOutputTrigger2 = TIM_TRGO_RESET;
    316. #endif
    317. master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    318. if (HAL_TIMEx_MasterConfigSynchronization(tim, &master_config) != HAL_OK)
    319. {
    320. LOG_E("%s master config failed", device->name);
    321. result = -RT_ERROR;
    322. goto __exit;
    323. }
    324. oc_config.OCMode = TIM_OCMODE_PWM1;
    325. oc_config.Pulse = 0;
    326. oc_config.OCPolarity = TIM_OCPOLARITY_HIGH;
    327. #if defined(SOC_SERIES_STM32H7)
    328. oc_config.OCNPolarity = TIM_OCNPOLARITY_LOW;
    329. #endif
    330. oc_config.OCFastMode = TIM_OCFAST_DISABLE;
    331. oc_config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
    332. oc_config.OCIdleState = TIM_OCIDLESTATE_RESET;
    333. /* config pwm channel */
    334. if (device->channel & 0x01)
    335. {
    336. if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_1) != HAL_OK)
    337. {
    338. LOG_E("%s channel1 config failed", device->name);
    339. result = -RT_ERROR;
    340. goto __exit;
    341. }
    342. }
    343. if (device->channel & 0x02)
    344. {
    345. if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_2) != HAL_OK)
    346. {
    347. LOG_E("%s channel2 config failed", device->name);
    348. result = -RT_ERROR;
    349. goto __exit;
    350. }
    351. }
    352. if (device->channel & 0x04)
    353. {
    354. if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_3) != HAL_OK)
    355. {
    356. LOG_E("%s channel3 config failed", device->name);
    357. result = -RT_ERROR;
    358. goto __exit;
    359. }
    360. }
    361. if (device->channel & 0x08)
    362. {
    363. if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_4) != HAL_OK)
    364. {
    365. LOG_E("%s channel4 config failed", device->name);
    366. result = -RT_ERROR;
    367. goto __exit;
    368. }
    369. }
    370. #if defined(SOC_SERIES_STM32H7)
    371. break_dead_time_config.OffStateRunMode = TIM_OSSR_DISABLE;
    372. break_dead_time_config.OffStateIDLEMode = TIM_OSSI_DISABLE;
    373. break_dead_time_config.LockLevel = TIM_LOCKLEVEL_OFF;
    374. break_dead_time_config.DeadTime = 0;
    375. break_dead_time_config.BreakState = TIM_BREAK_DISABLE;
    376. break_dead_time_config.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
    377. break_dead_time_config.BreakFilter = 0;
    378. break_dead_time_config.Break2State = TIM_BREAK2_DISABLE;
    379. break_dead_time_config.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
    380. break_dead_time_config.Break2Filter = 0;
    381. break_dead_time_config.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
    382. if (HAL_TIMEx_ConfigBreakDeadTime(tim, &break_dead_time_config) != HAL_OK)
    383. {
    384. LOG_E("%s break_dead_time config failed", device->name);
    385. result = -RT_ERROR;
    386. goto __exit;
    387. }
    388. #endif
    389. /* pwm pin configuration */
    390. HAL_TIM_MspPostInit(tim);
    391. /* enable update request source */
    392. __HAL_TIM_URS_ENABLE(tim);
    393. __exit:
    394. return result;
    395. }
    396. static void pwm_get_channel(void)
    397. {
    398. #ifdef BSP_USING_PWM1_CH1
    399. stm32_pwm_obj[PWM1_INDEX].channel |= 1 << 0;
    400. #endif
    401. #ifdef BSP_USING_PWM1_CH2
    402. stm32_pwm_obj[PWM1_INDEX].channel |= 1 << 1;
    403. #endif
    404. #ifdef BSP_USING_PWM1_CH3
    405. stm32_pwm_obj[PWM1_INDEX].channel |= 1 << 2;
    406. #endif
    407. #ifdef BSP_USING_PWM1_CH4
    408. stm32_pwm_obj[PWM1_INDEX].channel |= 1 << 3;
    409. #endif
    410. #ifdef BSP_USING_PWM2_CH1
    411. stm32_pwm_obj[PWM2_INDEX].channel |= 1 << 0;
    412. #endif
    413. #ifdef BSP_USING_PWM2_CH2
    414. stm32_pwm_obj[PWM2_INDEX].channel |= 1 << 1;
    415. #endif
    416. #ifdef BSP_USING_PWM2_CH3
    417. stm32_pwm_obj[PWM2_INDEX].channel |= 1 << 2;
    418. #endif
    419. #ifdef BSP_USING_PWM2_CH4
    420. stm32_pwm_obj[PWM2_INDEX].channel |= 1 << 3;
    421. #endif
    422. #ifdef BSP_USING_PWM3_CH1
    423. stm32_pwm_obj[PWM3_INDEX].channel |= 1 << 0;
    424. #endif
    425. #ifdef BSP_USING_PWM3_CH2
    426. stm32_pwm_obj[PWM3_INDEX].channel |= 1 << 1;
    427. #endif
    428. #ifdef BSP_USING_PWM3_CH3
    429. stm32_pwm_obj[PWM3_INDEX].channel |= 1 << 2;
    430. #endif
    431. #ifdef BSP_USING_PWM3_CH4
    432. stm32_pwm_obj[PWM3_INDEX].channel |= 1 << 3;
    433. #endif
    434. #ifdef BSP_USING_PWM4_CH1
    435. stm32_pwm_obj[PWM4_INDEX].channel |= 1 << 0;
    436. #endif
    437. #ifdef BSP_USING_PWM4_CH2
    438. stm32_pwm_obj[PWM4_INDEX].channel |= 1 << 1;
    439. #endif
    440. #ifdef BSP_USING_PWM4_CH3
    441. stm32_pwm_obj[PWM4_INDEX].channel |= 1 << 2;
    442. #endif
    443. #ifdef BSP_USING_PWM4_CH4
    444. stm32_pwm_obj[PWM4_INDEX].channel |= 1 << 3;
    445. #endif
    446. #ifdef BSP_USING_PWM5_CH1
    447. stm32_pwm_obj[PWM5_INDEX].channel |= 1 << 0;
    448. #endif
    449. #ifdef BSP_USING_PWM5_CH2
    450. stm32_pwm_obj[PWM5_INDEX].channel |= 1 << 1;
    451. #endif
    452. #ifdef BSP_USING_PWM5_CH3
    453. stm32_pwm_obj[PWM5_INDEX].channel |= 1 << 2;
    454. #endif
    455. #ifdef BSP_USING_PWM5_CH4
    456. stm32_pwm_obj[PWM5_INDEX].channel |= 1 << 3;
    457. #endif
    458. #ifdef BSP_USING_PWM6_CH1
    459. stm32_pwm_obj[PWM6_INDEX].channel |= 1 << 0;
    460. #endif
    461. #ifdef BSP_USING_PWM6_CH2
    462. stm32_pwm_obj[PWM6_INDEX].channel |= 1 << 1;
    463. #endif
    464. #ifdef BSP_USING_PWM6_CH3
    465. stm32_pwm_obj[PWM6_INDEX].channel |= 1 << 2;
    466. #endif
    467. #ifdef BSP_USING_PWM6_CH4
    468. stm32_pwm_obj[PWM6_INDEX].channel |= 1 << 3;
    469. #endif
    470. #ifdef BSP_USING_PWM7_CH1
    471. stm32_pwm_obj[PWM7_INDEX].channel |= 1 << 0;
    472. #endif
    473. #ifdef BSP_USING_PWM7_CH2
    474. stm32_pwm_obj[PWM7_INDEX].channel |= 1 << 1;
    475. #endif
    476. #ifdef BSP_USING_PWM7_CH3
    477. stm32_pwm_obj[PWM7_INDEX].channel |= 1 << 2;
    478. #endif
    479. #ifdef BSP_USING_PWM7_CH4
    480. stm32_pwm_obj[PWM7_INDEX].channel |= 1 << 3;
    481. #endif
    482. #ifdef BSP_USING_PWM8_CH1
    483. stm32_pwm_obj[PWM8_INDEX].channel |= 1 << 0;
    484. #endif
    485. #ifdef BSP_USING_PWM8_CH2
    486. stm32_pwm_obj[PWM8_INDEX].channel |= 1 << 1;
    487. #endif
    488. #ifdef BSP_USING_PWM8_CH3
    489. stm32_pwm_obj[PWM8_INDEX].channel |= 1 << 2;
    490. #endif
    491. #ifdef BSP_USING_PWM8_CH4
    492. stm32_pwm_obj[PWM8_INDEX].channel |= 1 << 3;
    493. #endif
    494. #ifdef BSP_USING_PWM9_CH1
    495. stm32_pwm_obj[PWM9_INDEX].channel |= 1 << 0;
    496. #endif
    497. #ifdef BSP_USING_PWM9_CH2
    498. stm32_pwm_obj[PWM9_INDEX].channel |= 1 << 1;
    499. #endif
    500. #ifdef BSP_USING_PWM9_CH3
    501. stm32_pwm_obj[PWM9_INDEX].channel |= 1 << 2;
    502. #endif
    503. #ifdef BSP_USING_PWM9_CH4
    504. stm32_pwm_obj[PWM9_INDEX].channel |= 1 << 3;
    505. #endif
    506. #ifdef BSP_USING_PWM12_CH1
    507. stm32_pwm_obj[PWM12_INDEX].channel |= 1 << 0;
    508. #endif
    509. #ifdef BSP_USING_PWM12_CH2
    510. stm32_pwm_obj[PWM12_INDEX].channel |= 1 << 1;
    511. #endif
    512. }
    513. static int stm32_pwm_init(void)
    514. {
    515. int i = 0;
    516. int result = RT_EOK;
    517. pwm_get_channel();
    518. for (i = 0; i < sizeof(stm32_pwm_obj) / sizeof(stm32_pwm_obj[0]); i++)
    519. {
    520. /* pwm init */
    521. if (stm32_hw_pwm_init(&stm32_pwm_obj[i]) != RT_EOK)
    522. {
    523. LOG_E("%s init failed", stm32_pwm_obj[i].name);
    524. result = -RT_ERROR;
    525. goto __exit;
    526. }
    527. else
    528. {
    529. LOG_D("%s init success", stm32_pwm_obj[i].name);
    530. /* register pwm device */
    531. if (rt_device_pwm_register(&stm32_pwm_obj[i].pwm_device, stm32_pwm_obj[i].name, &drv_ops, &stm32_pwm_obj[i].tim_handle) == RT_EOK)
    532. {
    533. LOG_D("%s register success", stm32_pwm_obj[i].name);
    534. }
    535. else
    536. {
    537. LOG_E("%s register failed", stm32_pwm_obj[i].name);
    538. result = -RT_ERROR;
    539. }
    540. }
    541. }
    542. __exit:
    543. return result;
    544. }
    545. INIT_DEVICE_EXPORT(stm32_pwm_init);
    546. #endif /* RT_USING_PWM */

  • 相关阅读:
    DNS大全(114DNS 、阿里DNS、百度DNS 、360 DNS、Google DNS)
    Linux libreoffice安装 word转pdf 中文乱码(缺少字体解决)
    C# 实现腾讯云多路直播流的云端混合录制
    2022年最新青海机动车签字授权人模拟考试及答案
    【线性代数】【一】1.2 消元法与方程组的矩阵表示
    Azure 机器学习 - Azure机器学习产品和技术介绍全览
    咨询第三方软件测试机构报价时,软件企业应该准备什么?
    CesiumJS PrimitiveAPI 高级着色入门 - 从参数化几何与 Fabric 材质到着色器 - 下篇
    使用 ModSecurity 和 ELK 进行持续安全监控
    for循环命名
  • 原文地址:https://blog.csdn.net/qwe5959798/article/details/127898473