完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
芯片为STM32F407ZG,使用的是高级定时器TIM1的PWM互补PWM输出。
效果: 整体的:(通道0~3分别是CH1、CH1N、CH2、CH2N。) 细节: CH1和CH1N的死区时间是0.375us(公式算出来应该是公式0.3us左右,跟逻辑分析仪的采样频率有关系) CH1和CH2、CH1N和CH2N是同步的,以前做H桥的话就需要这种吧(对角同时导通),有相位差的后面再研究。(补充:后面发现这个问题F3系列的芯片比较好实现,用非对称PWM,F4可以用TIM1和TIM8配合实现,原理利用TIM1去触发TIM8) STM32CubeMX配置: main函数 /* USER CODE BEGIN 2 */ /****普通定时器***/ HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); /****高级定时器互补输出***/ HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2); HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1); HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_2); /****寄存器方法修改比较寄存器的值,ARR的值cube配置为1000***/ TIM1->CCR1=249; TIM1->CCR2=249; /* USER CODE END 2 */ 1 2 3 4 5 6 7 8 9 10 11 12 说明: 代码中普通定时器只是为了测试! 高级定时器与普通定时器用法有微笑区别,网上查资料总是误导,很多教程都提到要用HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1)这一句,但是只有这一句CH1N会有输出,CH1就没了,走了不少弯路。 细看高级定时器的函数名,一个是PWM、一个是PWMN,而HAL_TIMEx_PWMN_Start与HAL_TIM_PWM_Start相比多了一个Ex,所在的.c文件也不相同。猜想带Ex的可能是扩展功能吧 再来看看死区时间计算吧: cubemx生成的代码如下: void MX_TIM1_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; htim1.Instance = TIM1; htim1.Init.Prescaler = 167; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 999; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 99; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } sConfigOC.Pulse = 199; if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) { Error_Handler(); } sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE; sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE; sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; sBreakDeadTimeConfig.DeadTime = 50; sBreakDeadTimeConfig.BreakState = TIM_BREAK_ENABLE; sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE; if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) { Error_Handler(); } HAL_TIM_MspPostInit(&htim1); } sBreakDeadTimeConfig.DeadTime = 50;这句就是死区时间了,怎么算,参考STM32F4xx中文参考手册.pdf DeadTime 是直接写入DTG[7:0],显然,当DeadTime <128时,最高位都是0,按照最上面的那条公式算就好了,DT=50Tdtg,其中,Tdtg=tDTS=1/164Mhz(tim1接在高速时钟APB2),算出来就是DT=501/164M=0.3048us了 个人调试心得,感谢点赞,更多问题交流,+Q:cqkz52@qq.com |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1568 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1513 浏览 1 评论
939 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
669 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1561 浏览 2 评论
1851浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
620浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
506浏览 3评论
511浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
492浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-13 05:47 , Processed in 0.650062 second(s), Total 49, Slave 42 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号