×
单片机 > 单片机程序设计 > 详情

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

发布时间:2020-06-06 发布时间:
|

一、简介



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




二、实验平台


库版本:STM32F10x_StdPeriph_Lib_V3.5.0


编译软件:MDK4.53


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


仿真器:JLINK



三、版权声明




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



四、实验前提

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)工程中添加GUA_Timer1_PWM.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




因此,实验成功。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
基于arm的指纹识别门禁系统是如何设计的