【STM32】STM32F407产生互补PWM输出

搜了一大堆,网上基本都是F103的例子,F4的很少,然而又需要用到,这里发一下调试过程吧

首先看一下什么是互补的PWM,直接上图,第二张是把Y轴移动了一下,方便理解(Multisim仿真截图),我的简单理解就是当A输出1B输出0,我高的时候你低,你低的时候我高。他们两的频率是一样的,振幅也是一样的。

1.关于输出通道问题

      由《STM32F4xx中文参考手册》可知(见下图),只有高级定时器TIM1和TIM8可以输出两路互补信号。其中OCx为主输出,OCxN为互补输出。这句话的意思是:如果我用TIM1输出两路互补的PWM信号。TIM1_CH1为主输出,那么TIM1_CH1N为互补输出。这是固定的。

                                         

     我在这里使用的是TIM1的通道1,查数据手册可知,用到的引脚为PA8(主输出),PA7(互补输出)。注:我的芯片为STM32F407VET6.

 

2.库函数配置

step1:结构体

// 结构体声明
GPIO_InitTypeDef GPIO_InitStructure;          // GPIO
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  // 定时器
TIM_OCInitTypeDef  TIM_OCInitStructure;       // 通道
TIM_BDTRInitTypeDef TIM_BDTRStructure;      // 刹车与死区

step2:时钟配置

// 时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);  	// TIM1时钟使能    
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 	// 使能GPIOA时钟	

step3:时钟配置

// IO复用
GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_TIM1); // GPIOA7_8复用为定时器1
// IO复用
GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_TIM1); // GPIOA7_8复用为定时器1

step4:GPIO配置

// GPIO配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8;           // 引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        // 复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	// 速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      // 推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        // 上拉
GPIO_Init(GPIOA,&GPIO_InitStructure);              // 配置

step5:定时器1配置

// 定时器配置
TIM_TimeBaseStructure.TIM_Prescaler=84-1;  // 定时器分频84M/84=1M
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseStructure.TIM_Period=25000-1;   // 自动重装载值25000,1M / 25000 =40Hz
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);// 初始化定时器1

step6:死区和刹车配置

  死区:在这里理解为翻转变化时给的一个延时,如下图所示,

  刹车:  这里没有用到,不做赘述,大概意思是可以通过这个功能切断所有输出。

// 刹车死区配置
TIM_BDTRStructure.TIM_AutomaticOutput=TIM_AutomaticOutput_Enable;// 自动输出功能使能
TIM_BDTRStructure.TIM_Break=TIM_Break_Disable;//失能刹车输入
//TIM_BDTRStructure.TIM_BreakPolarity=TIM_BreakPolarity_High; //刹车输入管脚极性高 
TIM_BDTRStructure.TIM_DeadTime=168; //输出打开和关闭状态之间的延时 84M/84=1us,84M/168=2us 
TIM_BDTRStructure.TIM_LOCKLevel=TIM_LOCKLevel_OFF;// 锁电平参数: 不锁任何位
TIM_BDTRStructure.TIM_OSSIState=TIM_OSSIState_Disable; //设置在运行模式下非工作状态选项
TIM_BDTRStructure.TIM_OSSRState=TIM_OSSRState_Disable; //设置在运行模式下非工作状态选项
TIM_BDTRConfig(TIM3,&TIM_BDTRStructure);

死区时间配置及计算见下图:

  TIM_BDTRStructure.TIM_DeadTime=0x01; //死区时间1us

通过查找STM32F4的应用手册,我们可以看到,死区时间由寄存器BDTR的位UTG[7:0]控制,如下图所示,死区时间等于步长(Tdts)乘以用户设定的数字。

step7:PWM输出配置

  // 定时器比较输出通道配置
  TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; 
  TIM_OCInitStructure.TIM_Pulse=0; 	//占空比:12500/25000*100%=50%
  TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;  //输出极性高
  TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable; //输出使能
  TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Reset; // 输出空闲电平低

  // 互补输出配置
  TIM_OCInitStructure.TIM_OutputNState=TIM_OutputNState_Enable; //互补输出使能
  TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCNPolarity_High;	// 互补端输出极性高
  TIM_OCInitStructure.TIM_OCNIdleState=TIM_OCNIdleState_Reset; //互补输出空闲电平低
  
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);  // OC1
  TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);   //配置

3.实验结果

       使用示波器对IO口进行测量,调至合适位置,用手机拍照记录如下:

全部代码如下:

// 函数名:TIM1_PWM_Init
// 参  数:None
// 返回值:None
// 描  述:使用TIM1的通道1输出两路互补的PWM
// 说  明:参考正点原子,野火论坛,在此感谢
void TIM1_PWM_Init()
{		 					 
	// 结构体声明
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
  TIM_BDTRInitTypeDef TIM_BDTRStructure;
  
	// 时钟使能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);  	//TIM3时钟使能    
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 	//使能PORTC时钟	
	
  // IO复用
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_TIM1); //
  GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_TIM1); //
	
  // IO配置
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7 | GPIO_Pin_8;//6脚未使用
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOA,&GPIO_InitStructure);              //初始化PF9
	 
   GPIO_ResetBits(GPIOA,GPIO_Pin_6);        //拉低刹车
  // 定时器配置
	TIM_TimeBaseStructure.TIM_Prescaler=84-1;  //自动重装载值1M / 25000 =40Hz
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseStructure.TIM_Period=25000-1;   //定时器分频84M/84=1M
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);//初始化定时器1
    
  // 定时器比较输出通道配置
  TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; 
  TIM_OCInitStructure.TIM_Pulse=0; 	//占空比:12500/25000*100%=50%
  TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;  //输出极性高
  TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable; //输出使能
  TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Reset; // 输出空闲电平低

  // 互补输出配置
  TIM_OCInitStructure.TIM_OutputNState=TIM_OutputNState_Enable; //互补输出使能
  TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCNPolarity_High;	// 互补端输出极性高
  TIM_OCInitStructure.TIM_OCNIdleState=TIM_OCNIdleState_Reset; //互补输出空闲电平低
  
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);  // OC1
  TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);   //配置

  // 刹车死区配置
  TIM_BDTRStructure.TIM_AutomaticOutput=TIM_AutomaticOutput_Enable;// 自动输出功能使能
  TIM_BDTRStructure.TIM_Break=TIM_Break_Disable;//失能刹车输入
  TIM_BDTRStructure.TIM_BreakPolarity=TIM_BreakPolarity_High; //刹车输入管脚极性高 
  TIM_BDTRStructure.TIM_DeadTime=0; //输出打开和关闭状态之间的延时 84-1us  168-2us 
  TIM_BDTRStructure.TIM_LOCKLevel=TIM_LOCKLevel_OFF;// 锁电平参数: 不锁任何位
  TIM_BDTRStructure.TIM_OSSIState=TIM_OSSIState_Disable; //设置在运行模式下非工作状态选项
  TIM_BDTRStructure.TIM_OSSRState=TIM_OSSRState_Disable; //设置在运行模式下非工作状态选项
  TIM_BDTRConfig(TIM1,&TIM_BDTRStructure);
  

  TIM_ARRPreloadConfig(TIM1,ENABLE);//ARPE使能 
	
  TIM_Cmd(TIM1, ENABLE);  //使能TIM3
  TIM_CtrlPWMOutputs(TIM1, ENABLE); //开启OC和OCN输出										  
}  

//主函数

int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);  //初始化延时函数
	uart_init(115200);//初始化串口波特率为115200
 	TIM1_PWM_Init();	//84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.   40  
  while(1)
	{
    TIM_SetCompare1(TIM1,12500);	//修改比较值,修改占空比50%
	}
}

 

  • 25
    点赞
  • 132
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要在STM32F407输出互补PWM波,你需要使用定时器和通道来控制输出。下面是一个简单的示例代码,用于在STM32F407上配置和生成互补PWM波: ```c #include "stm32f4xx.h" void PWM_Init(void) { // 启用定时器时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); // 配置引脚为复用功能 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOD, &GPIO_InitStructure); // 将引脚连接到定时器 GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4); // 配置定时器 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 999; // 设置PWM周期 TIM_TimeBaseStructure.TIM_Prescaler = 83; // 设置定时器时钟频率为1MHz TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); // 配置通道1和通道2为PWM模式 TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = 500; // 设置通道1的占空比为50% TIM_OC1Init(TIM4, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_OCInitStructure.TIM_Pulse = 500; // 设置通道2的占空比为50% TIM_OC2Init(TIM4, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); // 启动定时器 TIM_Cmd(TIM4, ENABLE); } int main(void) { PWM_Init(); while (1) { // 在这里添加你的代码 } } ``` 上述代码使用了定时器4(TIM4)和GPIOD的引脚12和13来生成互补PWM波。你可以根据需要修改引脚和定时器的选择,并在`main`函数中添加自己的代码。 请注意,上述代码仅提供了一个基本的配置和生成PWM波的示例。具体的配置和使用方法可能因你的需求而有所不同,请根据你的具体情况进行相应的修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vicssic

与你一起成长

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值