OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 16506|回复: 8

用STM32 输出两路PWM,需要两路PWM极性相反,两路PWM的占空比可以调,怎么配置啊?

[复制链接]

7

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2012-10-14
在线时间
0 小时
发表于 2014-8-6 23:02:49 | 显示全部楼层 |阅读模式
5金钱
void TIM3_PWM_Init(u16 arr,u16 psc)
{  
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟

GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射  TIM3_CH2->B5    
 // GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); 
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

   //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形 GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;  //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;  //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
 
   //初始化TIM3
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值   (TIMx->ARR 寄存器设置)
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 (TIMx->SC 寄存器设置)
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim  (TIMx->CR1 寄存器设置)
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式 (TIMx->CR1 寄存器设置)
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

//初始化TIM3 Channel2 PWM模式  
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2 (TIMx_CCMR1寄存器设置)
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能(TIMx_CCER寄存器设置)
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 (TIMx_CCER寄存器设置)
TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2

//初始化TIM3 Channel1 PWM模式  
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2 (TIMx_CCMR1寄存器设置)
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能(TIMx_CCER寄存器设置)
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 (TIMx_CCER寄存器设置)
TIM_OC1Init(TIM3, &TIM_OCInitStructure);

TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器 (TIMx_CCMR1寄存器设置)
  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

TIM_Cmd(TIM3, ENABLE);  //使能TIM3


}
我这么配置发现不行,求原子哥及各位大神帮忙啊,谢谢啦~

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

20

主题

232

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
335
金钱
335
注册时间
2013-6-1
在线时间
0 小时
发表于 2014-8-6 23:08:24 | 显示全部楼层
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  这句?
回复

使用道具 举报

7

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2012-10-14
在线时间
0 小时
 楼主| 发表于 2014-8-6 23:29:03 | 显示全部楼层
回复【2楼】Scy:
---------------------------------
我设置的通道1和通道2是在不同的PWM模式,一个是PWM1,一个是PWM2


//初始化TIM3 Channel2 WM模式  
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2 (TIMx_CCMR1寄存器设置)
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能(TIMx_CCER寄存器设置)
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 (TIMx_CCER寄存器设置)
TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2

//初始化TIM3 Channel1 WM模式  
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2 (TIMx_CCMR1寄存器设置)
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能(TIMx_CCER寄存器设置)
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高 (TIMx_CCER寄存器设置)
TIM_OC1Init(TIM3, &TIM_OCInitStructure);

后来我又试了一下两个通道都在PWM2模式下,一个设置为TIM_OCPolarity_High,另一个设置为TIM_OCPolarity_Low,还是不行啊,怎么解决啊?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-8-7 00:03:22 | 显示全部楼层
 回复【3楼】 fgq369 :
---------------------------------
参考下这里:http://www.openedv.com/posts/list/140.htm
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

5

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
189
金钱
189
注册时间
2014-10-21
在线时间
31 小时
发表于 2014-11-1 20:23:21 | 显示全部楼层
多谢你的程序,我实测了,是可以的啊,把PWM2改成1,极性是相反的,也就是通道2和1的极性
主要是烧到板子里,因为高电平的时间太短,因此led灯现象看不出来,仿真的时候是正确的,弄得我也很纳闷,后来用示波器看,与仿真是相同的
原子哥提供的好多帖子都是寄存器版本的,菜鸟表示很有压力啊。。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-11-1 21:06:40 | 显示全部楼层
回复【5楼】你干嘛:
---------------------------------
慢慢来。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

4

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2015-3-11
在线时间
0 小时
发表于 2015-4-14 10:50:38 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
原子大哥,本人想利用STM32F407ZG产生两路PWM波对两个舵机进行控制 在原子的实验9 WM波输出实验改的 由于TIM14只有CH1通道 所以又启用了一个TIM3CH1通道 ,连两个定时器都是用PWM1模式的,但是发现只有TIM14CH1对应引脚的舵机工作 同样的舵机在TIM3CH1对应的引脚下不工作 所以不是舵机的问题,而TIM3还可以产生PWM波进行灯的控制 所以也不是定时器的问题;我的tim3ch1完全按照TIM14CH1配置改的 ,请大家帮我看看是不是配置不对,难道通用定时器的配置还不一样吗?TIM14CH1对应的引脚是PF9 TIM3CH1对应的引脚是PC6 严格按照数据手册上查的 
下面是PWM.C的代码
#include "pwm.h"
#include "led.h"
#include "usart.h"
 
//////////////////////////////////////////////////////////////////////////////////  
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F407开发板
//定时器PWM 驱动代码    
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2014/5/4
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved   
//////////////////////////////////////////////////////////////////////////////////  


//TIM14 WM部分初始化 
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM14_PWM_Init(u32 arr,u32 psc)
{   
//此部分需手动修改IO口设置

GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);   //TIM14时钟使能    
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //使能PORTF时钟 

GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9复用为定时器14

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //GPIOF9
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(GPIOF,&GPIO_InitStructure);              //初始化PF9
 
TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 

TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//初始化定时器14

//初始化TIM14 Channel1 WM模式  
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
TIM_OC1Init(TIM14, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 4OC1

TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);  //使能TIM14在CCR1上的预装载寄存器
 
  TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE使能 

TIM_Cmd(TIM14, ENABLE);  //使能TIM14
 
}  

void TIM3_PWM_Init(u32 arr,u32 psc)
{   
//此部分需手动修改IO口设置

GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);   //TIM3时钟使能    
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能PORTF时钟 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;           //GPIOC6
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(GPIOC,&GPIO_InitStructure);              //初始化PC6
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM3); //GPIOC6复用为定时器3
 
TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=0; 
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//初始化定时器3

//初始化TIM3 Channel1 WM模式  
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性低
TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3OC1
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR1上的预装载寄存器
    TIM_ARRPreloadConfig(TIM3,ENABLE);//ARPE使能 
TIM_Cmd(TIM3, ENABLE);  //使能TIM3   

下面是main.c代码
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "pwm.h"


//ALIENTEK 探索者STM32F407开发板 实验9
//PWM输出实验-库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://openedv.taobao.com  
//广州市星翼电子科技有限公司  
//作者:正点原子 @ALIENTEK

int main(void)

//float duty;    
//u8 dir=1;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168);  //初始化延时函数
uart_init(115200);//初始化串口波特率为115200
  TIM14_PWM_Init(20000-1,84-1); //频率为50hz     
TIM3_PWM_Init(20000-1,84-1);
   while(1)
{
TIM_SetCompare1(TIM14,500);
delay_ms(1500);
TIM_SetCompare1(TIM14,1000);
delay_ms(1500);
TIM_SetCompare1(TIM14,1500);
delay_ms(1500);
TIM_SetCompare1(TIM14,2000);
delay_ms(1500);
TIM_SetCompare1(TIM14,2500);
delay_ms(1500);

}
while(1) //实现比较值从0-300递增,到300后从300-0递减,循环
{
TIM_SetCompare1(TIM3,500);
delay_ms(1500);
TIM_SetCompare1(TIM3,1000);
delay_ms(1500);
TIM_SetCompare1(TIM3,1500);
delay_ms(1500);
TIM_SetCompare1(TIM3,2000);
delay_ms(1500);
TIM_SetCompare1(TIM3,2500);
delay_ms(1500);

}
}

pwm.h的也整上来吧
#ifndef _TIMER_H
#define _TIMER_H
#include "sys.h"
//////////////////////////////////////////////////////////////////////////////////  
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F407开发板
//定时器 驱动代码    
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2014/6/16
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved   
////////////////////////////////////////////////////////////////////////////////// 

void TIM14_PWM_Init(u32 arr,u32 psc);
void TIM3_PWM_Init(u32 arr,u32 psc);

#endif
回复

使用道具 举报

8

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2016-7-1
在线时间
6 小时
发表于 2017-6-23 09:59:59 来自手机 | 显示全部楼层
清雅张 发表于 2015-4-14 10:50
回复【6楼】正点原子:
---------------------------------
原子大哥,本人想利用STM32F407ZG产生两路PWM波 ...

解决了吗
回复

使用道具 举报

8

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2016-7-1
在线时间
6 小时
发表于 2017-6-23 10:00:27 来自手机 | 显示全部楼层
清雅张 发表于 2015-4-14 10:50
回复【6楼】正点原子:
---------------------------------
原子大哥,本人想利用STM32F407ZG产生两路PWM波 ...

解决了吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-8-17 20:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表