7路PWM产生程序阅读

原创 2017年01月02日 21:47:55
如下是7路PWM产生的程序解读,粘贴程序如下,并会在一些内容上做简单注释说明,以方便理解阅读,对于具体的产生原理需要阅读《STM32不完全手册》或是其它STM32的相关资料文档。使用库函数的方式完成功能实现,需要对库函数有一定的熟悉了解,相对于寄存器方式的方式更加快捷,但是对于初学者还是寄存器的方式更容易理解,加深学习效果。

程序的设计步骤为:
1、初始化系统时钟,使能相应的module的时钟;
2、GPIO的相应设置,使用GPIO的复用功能;
3、设置定时器的时基,采用的是内部时钟,主要设置频率、计数模式、分频倍频;
4、设置相应通道,包括比较寄存器的值、使能输出驱动、输出模式、输出极性、idle状态值
#include "stm32f10x.h"
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
uint16_t TimerPeriod = 0;
uint16_t Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0, Channel4Pulse = 0;

/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);      // 关于设备的时钟初始化在rcc.c的库文件中,startup文件启动时自动跳转至时钟设置处,在如下文档中只是做相应的module的时钟使能
void GPIO_Configuration(void);    // 设置 channel的GPIO,需要复用功能开启

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_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */     
       
  /* System Clocks Configuration */
  RCC_Configuration();

  /* GPIO Configuration */
  GPIO_Configuration();

  /* TIM1 Configuration ---------------------------------------------------
   Generate 7 PWM signals with 4 different duty cycles:
   TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock
   SystemCoreClock is set to 72 MHz for Low-density, Medium-density, High-density
   and Connectivity line devices and to 24 MHz for Low-Density Value line and
   Medium-Density Value line devices
   
   The objective is to generate 7 PWM signal at 17.57 KHz:(72MHz/4097=17570Hz 所以反向计算定时器周期为如下公式)
     - TIM1_Period = (SystemCoreClock / 17570) - 1
   The channel 1 and channel 1N duty cycle is set to 50%
   The channel 2 and channel 2N duty cycle is set to 37.5%
   The channel 3 and channel 3N duty cycle is set to 25%
   The channel 4 duty cycle is set to 12.5%
   The Timer pulse is calculated as follows:
     - ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100
  ----------------------------------------------------------------------- */
  /* Compute the value to be set in ARR regiter to generate signal frequency at 17.57 Khz */
  TimerPeriod = (SystemCoreClock / 17570 ) - 1;
  /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 and 1N */
  Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10);
  /* Compute CCR2 value to generate a duty cycle at 37.5%  for channel 2 and 2N */
  Channel2Pulse = (uint16_t) (((uint32_t) 375 * (TimerPeriod - 1)) / 1000);
  /* Compute CCR3 value to generate a duty cycle at 25%  for channel 3 and 3N */
  Channel3Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100);
  /* Compute CCR4 value to generate a duty cycle at 12.5%  for channel 4 */
  Channel4Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod- 1)) / 1000);

  /* Time Base configuration 时基的设置*/    
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

  /* Channel 1, 2,3 and 4 Configuration in PWM mode */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;

  TIM_OC1Init(TIM1, &TIM_OCInitStructure);

  TIM_OCInitStructure.TIM_Pulse = Channel2Pulse;
  TIM_OC2Init(TIM1, &TIM_OCInitStructure);

  TIM_OCInitStructure.TIM_Pulse = Channel3Pulse;
  TIM_OC3Init(TIM1, &TIM_OCInitStructure);

  TIM_OCInitStructure.TIM_Pulse = Channel4Pulse;
  TIM_OC4Init(TIM1, &TIM_OCInitStructure);

  /* TIM1 counter enable */
  TIM_Cmd(TIM1, ENABLE);

  /* TIM1 Main Output Enable */
  TIM_CtrlPWMOutputs(TIM1, ENABLE);

  while (1)
  {}
}
// 使能相应模块的时钟 
void RCC_Configuration(void)
{
  /* TIM1, GPIOA, GPIOB, GPIOE and AFIO clocks enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOE|
                         RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO, ENABLE);
}
//子函数为相应的GPIO的设置
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* GPIOA Configuration: Channel 1, 2 and 3 as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* GPIOB Configuration: Channel 1N, 2N and 3N as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
}
如下是示波器量测的波形,channel 2 GPIOA 的Pin 9
从图中可以看出信号是正确的,频率17.57KHz,占空比为37.5%

版权声明:本文为博主原创文章,未经博主允许不得转载。

STM32F4 TIM1 7路PWM信号输出

【实验目的】 输出7路占空比不同的PWM信号是各个版本ST库必备的例子。本实验的主要目的不是表现ST芯片PWM功能的强大,而是要完成输出的精确计算。 【实验内容】 输出7路PWM信号,并用示波器...

AVR16产生两路PWM波的小程序

  • 2012年11月21日 21:33
  • 2KB
  • 下载

linux下PWM程序设计

PWM(Pulse Width Modulation)——脉宽调制,它是利用微控制器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用于测量、通信、功率控制与变换等许多领域。 s3c2...

单片机产生pwm程序

  • 2014年09月16日 12:02
  • 653B
  • 下载

MINI2440开发板PWM驱动与测试程序简要分析

先看下电路原理图 #include #include #include #include #include #include #include #includ...

ht66f70a产生PWM波程序

  • 2016年05月29日 14:20
  • 35KB
  • 下载

STM32F103PWM+重映射 小程序

原文地址: 我的开发板是学习板,很多管脚没有引出。弄到定时器产生PWM这一块,想用下管脚重映射功能,毕竟库函数没有像操作寄存器那样容易理解。所以一开始着实糊涂了一会,最后还是给调出来了。结合很多别人...
  • bobbat
  • bobbat
  • 2014年08月30日 22:01
  • 2373
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:7路PWM产生程序阅读
举报原因:
原因补充:

(最多只允许输入30个字)