要求得到下列波形,死区时间为1us,CH1,CH2,CH3之间的相位差为3us,频率为50KHz
main.c
/*********************************************
标题:定时器输出带有死区时间的PWM波形
软件平台:MDK-ARM Standard Version4.70
硬件平台:stm32f4-discovery
主频:168M
Periph_Driver_version: V1.0.0
描述:用一个定时器(TIM1),输出带有死区时间的PWM波形,要求:死区时间为1us,CH1,CH2,CH3之间的相位差为3us,频率为50KHz
代码参考自STM32F4-Discovery_FW_V1.1.0\Project\Peripheral_Examples\TIM_ComplementarySignals
author:大舟
data:2013-04-15
**********************************************/
#include "stm32f4_discovery.h"
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
uint16_t TimerPeriod = 0;
uint16_t Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0;
/* Private function prototypes */
void TIM_Config(void);
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f4xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
/* TIM1 Configuration */
TIM_Config();
/* -----------------------------------------------------------------------
1/ Generate 3 complementary PWM signals with 3 different duty cycles:
In this example TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2),
since APB2 prescaler is different from 1 (APB2 Prescaler = 2, see system_stm32f4xx.c file).
TIM1CLK = 2 * PCLK2
PCLK2 = HCLK / 2
=> TIM1CLK = 2*(HCLK / 2) = HCLK = SystemCoreClock
To get TIM1 counter clock at 168 MHz, the prescaler is computed as follows:
Prescaler = (TIM1CLK / TIM1 counter clock) - 1
Prescaler = (SystemCoreClock / 168 MHz) - 1 = 0
The objective is to generate PWM signal at 17.57 KHz:
- TIM1_Period = (SystemCoreClock / 17570) - 1
To get TIM1 output clock at 17.57 KHz, the period (ARR) is computed as follows:
ARR = (TIM1 counter clock / TIM1 output clock) - 1 = 9561
The Three Duty cycles are computed as the following description:
TIM1 Channel1 duty cycle = (TIM1_CCR1/ TIM1_ARR)* 100 = 50%
TIM1 Channel2 duty cycle = (TIM1_CCR2/ TIM1_ARR)* 100 = 25%
TIM1 Channel3 duty cycle = (TIM1_CCR3/ TIM1_ARR)* 100 = 12.5%
The Timer pulse is calculated as follows:
- TIM1_CCRx = (DutyCycle * TIM1_ARR)/ 100
2/ Insert a dead time equal to (11/SystemCoreClock) ns //这句不对,示波器里观测也不对,不是这样算的。
正确的deadtime的计算方法(经理论与示波器测试成功)
TIM_BDTRInitStructure.TIM_DeadTime=255 //这句设定的就是寄存器TIMx_BDTR的后8位,即DTG[7:0],所以最大值为255
从下面的代码中的“第五步”中,实际上就相当于TIM1->BDTR=0x71FF;
查看"STM32中文参考手册2009.pdf"的TIMx_BDTR(第248页),列寄存器TIMx_BDTR的后8位如下:
位7:0 UTG[7:0]: 死区发生器设置 (Dead-time generator setup)
这些位定义了插入互补输出之间的死区持续时间。假设DT表示其持续时间:
DTG[7:5]=0xx => DT=DTG[7:0] × Tdtg, Tdtg = Tdts;
DTG[7:5]=10x => DT=(64+DTG[5:0])