您的位置:首页 > 其它

【STM32】STM32之timer1产生PWM(互补通道)

2017-01-15 00:24 363 查看
本篇博文最后修改时间:2017年01月14日,23:50。




一、简介

本文介绍STM32系列如何使用timer1的第TIM1_CH2N通道(PB14)产生PWM。

二、实验平台

库版本:STM32F10x_StdPeriph_Lib_V3.5.0

编译软件:MDK4.53

硬件平台:STM32开发板(主芯片stm32f103c8t6)

仿真器:JLINK

、版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:http://blog.csdn.NET/feilusia

联系方式:897503845@qq.com

香瓜BLE之CC2541群:127442605

香瓜BLE之CC2640群:557278427

香瓜BLE之Android群:541462902

香瓜单片机之STM8/STM32群:164311667

甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

四、实验前提
1、在进行本文步骤前,请先阅读以下博文:
1)《STM32之timer3产生PWM》:http://blog.csdn.net/feilusia/article/details/53634882

2、在进行本文步骤前,请先实现以下博文:

暂无

五、基础知识
1、什么是互补通道?

答:TIM1_CH2N通道就是TIM1_CH2的互补通道,它们的波形完全反向。有些引脚上是互补通道,我们同样可用于PWM输出。

六、实验步骤

1、编写并添加PWM驱动
1)编写驱动GUA_Timer1_PWM.c(存放在“……\HARDWARE”)

//******************************************************************************
//name:             GUA_Timer1_PWM.c
//introduce:        定时器1的PWM驱动
//author:           甜甜的大香瓜
//email:            897503845@qq.com
//QQ group          香瓜单片机之STM8/STM32(164311667)
//changetime:       2017.01.14
//******************************************************************************
#include "stm32f10x.h"
#include "GUA_Timer1_PWM.h"

/*********************宏定义************************/
//引脚宏
#define GUA_TIMER1_PWM_PORT             GPIOB
#define GUA_TIMER1_PWM_PIN              GPIO_Pin_14
#define GUA_TIMER1_PWM_MODE             GPIO_Mode_AF_PP
#define GUA_TIMER1_PWM_GPIO_CLOCK				RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO
#define GUA_TIMER1_PWM_PERIPH_CLOCK			RCC_APB2Periph_TIM1

//计数值
#define GUA_TIMER1_PWM_PERIOD						(72 - 1)

/*********************内部函数声明************************/
static void GUA_Timer1_PWM_IO_Init(void);
static void GUA_Timer1_PWM_Config_Init(GUA_U16 nGUA_Timer3_PWM_Prescaler);

//******************************************************************************
//name:             GUA_Timer1_PWM_IO_Init
//introduce:        定时器1的PWM的IO初始化
//parameter:        none
//return:           none
//author:           甜甜的大香瓜
//email:            897503845@qq.com
//QQ group          香瓜单片机之STM8/STM32(164311667)
//changetime:       2017.01.14
//******************************************************************************
static void GUA_Timer1_PWM_IO_Init(void)
{
//IO结构体
GPIO_InitTypeDef GPIO_InitStructure;

//时钟配置
RCC_APB2PeriphClockCmd(GUA_TIMER1_PWM_GPIO_CLOCK, ENABLE);

//IO初始化
GPIO_InitStructure.GPIO_Pin = GUA_TIMER1_PWM_PIN;
GPIO_InitStructure.GPIO_Mode = GUA_TIMER1_PWM_MODE;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GUA_TIMER1_PWM_PORT, &GPIO_InitStructure);
}

//******************************************************************************
//name:             GUA_Timer1_PWM_Config_Init
//introduce:        定时器1的PWM的配置初始化
//parameter:        nGUA_Timer1_PWM_Prescaler:预分频数值,如100则表示1000000/100=10000Hz
//return:           none
//author:           甜甜的大香瓜
//email:            897503845@qq.com
//QQ group          香瓜单片机之STM8/STM32(164311667)
//changetime:       2017.01.14
//******************************************************************************
static void GUA_Timer1_PWM_Config_Init(GUA_U16 nGUA_Timer1_PWM_Prescaler)
{
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;

//时钟配置
RCC_APB2PeriphClockCmd(GUA_TIMER1_PWM_PERIPH_CLOCK, ENABLE);

//定时器配置
TIM_TimeBaseStructure.TIM_Period = GUA_TIMER1_PWM_PERIOD;								//设置计数值
TIM_TimeBaseStructure.TIM_Prescaler = nGUA_Timer1_PWM_Prescaler - 1;		//设置预分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0;														//设置时钟分频系数:不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;							//向上计数溢出模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

//PWM配置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;												//配置为PWM模式1(小于计数值时为有效电平)
//TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;					//比较输出使能
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;					//比较输出的互补输出使能
TIM_OCInitStructure.TIM_Pulse = 0;																			//设置待装入捕获比较寄存器的脉冲值
//TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;							//当定时器计数值小于CCR1时为低电平
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;							//当定时器计数值小于CCR1时互补输出为低电平
//TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;						//当MOE=0时,如果实现了OC*N,则死区后OC*=1
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;						//当MOE=0时,如果实现了OC*N,则死区后OC*=1
TIM_OC2Init(TIM1, &TIM_OCInitStructure);																//使能通道2

//默认关闭PWM
GUA_Timer1_PWM_Status(GUA_TIMER1_PWM_STATUS_OFF);

//使能
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);												//CH2预装载使能
TIM_ARRPreloadConfig(TIM1, ENABLE);																			//使能TIM1重载寄存器ARR
TIM_Cmd(TIM1, ENABLE);																									//使能定时器1
}

//******************************************************************************
//name:             GUA_Timer1_PWM_Status
//introduce:        定时器1的PWM开关
//parameter:        nGUA_Timer1_PWM_Status: GUA_TIMER1_PWM_STATUS_ON or GUA_TIMER1_PWM_STATUS_OFF
//return:           none
//author:           甜甜的大香瓜
//email:            897503845@qq.com
//QQ group          香瓜单片机之STM8/STM32(164311667)
//changetime:       2017.01.14
//******************************************************************************
void GUA_Timer1_PWM_Status(GUA_U8 nGUA_Timer1_PWM_Status)
{
//打开PWM
if(nGUA_Timer1_PWM_Status == GUA_TIMER1_PWM_STATUS_ON)
{
TIM_SetCounter(TIM1, 0);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
//关闭PWM
else
{
TIM_CtrlPWMOutputs(TIM1, DISABLE);
}
}

//******************************************************************************
//name:             GUA_Timer1_PWM_SetDutyCycle
//introduce:        定时器1的PWM设置占空比
//parameter:        nGUA_Timer1_PWM_DutyCycle: 0~100为0%~100%
//return:           none
//author:           甜甜的大香瓜
//email:            897503845@qq.com
//QQ group          香瓜单片机之STM8/STM32(164311667)
//changetime:       2017.01.14
//******************************************************************************
void GUA_Timer1_PWM_SetDutyCycle(GUA_U8 nGUA_Timer1_PWM_DutyCycle)
{
TIM_SetCompare2(TIM1, GUA_TIMER1_PWM_PERIOD*nGUA_Timer1_PWM_DutyCycle/100);
}

//******************************************************************************
//name:             GUA_Timer1_PWM_Init
//introduce:        定时器1的PWM初始化
//parameter:        nGUA_Timer1_PWM_Prescaler:预分频数值,如100则表示1000000/100=10000Hz
//return:           none
//author:           甜甜的大香瓜
//email:            897503845@qq.com
//QQ group          香瓜单片机之STM8/STM32(164311667)
//changetime:       2017.01.14
//******************************************************************************
void GUA_Timer1_PWM_Init(GUA_U16 nGUA_Timer1_PWM_Prescaler)
{
//初始化IO
GUA_Timer1_PWM_IO_Init();

//初始化定时器配置
GUA_Timer1_PWM_Config_Init(nGUA_Timer1_PWM_Prescaler);
}

2)编写驱动头文件GUA_Timer1_PWM.h(存放在“……\HARDWARE”)

//******************************************************************************
//name:             GUA_Timer1_PWM.h
//introduce:        定时器1的PWM驱动的头文件
//author:           甜甜的大香瓜
//email:            897503845@qq.com
//QQ group          香瓜单片机之STM8/STM32(164311667)
//changetime:       2017.01.14
//******************************************************************************
#ifndef _GUA_TIMER1_PWM_H_
#define _GUA_TIMER1_PWM_H_

/*********************宏定义************************/
//类型宏
#ifndef GUA_U8
typedef unsigned char GUA_U8;
#endif

#ifndef GUA_8
typedef signed char GUA_8;
#endif

#ifndef GUA_U16
typedef unsigned short GUA_U16;
#endif

#ifndef GUA_16
typedef signed short GUA_16;
#endif

#ifndef GUA_U32
typedef unsigned long GUA_U32;
#endif

#ifndef GUA_32
typedef signed long GUA_32;
#endif

#ifndef GUA_U64
typedef unsigned long long GUA_U64;
#endif

#ifndef GUA_64
typedef signed long long GUA_64;
#endif

//PWM的开关宏
#define GUA_TIMER1_PWM_STATUS_ON                0       //PWM打开
#define GUA_TIMER1_PWM_STATUS_OFF               1       //PWM关闭

/*********************外部函数声明************************/
void GUA_Timer1_PWM_Status(GUA_U8 nGUA_Timer1_PWM_Status);
void GUA_Timer1_PWM_SetDutyCycle(GUA_U8 nGUA_Timer1_PWM_DutyCycle);
void GUA_Timer1_PWM_Init(GUA_U16 nGUA_Timer1_PWM_Prescaler);

#endif

3)工程中添加[b]GUA_Timer1_PWM[/b].c



4)在MDK设置中添加驱动源文件路径



2、添加库的驱动

1)添加库的驱动文件



2)添加库的驱动头文件(stm32f10x_conf.h 中)

#include "stm32f10x_tim.h"
3、在应用层中调用

1)添加驱动头文件(main.c中)
#include "GUA_Timer1_PWM.h"

2)添加初始化代码(main.c的main函数中)
GUA_Timer1_PWM_Init(26); //设置PWM频率为1000000/26=38000Hz=38KHz
GUA_Timer1_PWM_SetDutyCycle(50); //设置PWM占空比为50%
GUA_Timer1_PWM_Status(GUA_TIMER3_PWM_STATUS_ON); //使能PWM

七、注意事项

1、在初始化PWM的配置之后,需要调用使能PWM的函数才会有PWM的波形。

2、PWM会有死区。

3、如果仅使用PWM的互补通道,记得不要把另一个普通的PWM通道也初始化了。

八、实验结果

设置仿真断点在测试代码,仿真并全速运行至断点,单步执行测试代码后的PB14波形如下图:

1、使能PWM



因此,实验成功。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: