STM32 PWM输出

PWM

脉冲宽度调制

由TIMx_ARR确定频率,由TIMx_CCRx确定占空比

两种PWM模式

  • 1 TIMx_CNT<TIMx_CCRx 时为有效电平
  • 2 TIMx_CNT>TIMx_CCRx 时为有效电平

PWM输出配置步骤

使能时钟(定时器时钟和相关IO口时钟)

    RCC_APB1PeriphClockCmd();
    RCC_APB2PeriphClockCmd();

IO口做为复用功能输出,初始化IO口

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//选择对应的引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出     
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PC端口

如果IO口要做重映射,还要使能AFIO时钟

    //未做重映射

定时器初始化

TIM_TimeBaseStructure.TIM_Period=arr;
TIM_TimeBaseStructure.TIM_Prescaler=psc;
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

初始化输出比较参数

TIM_OCInitTypeStructure.TIM_OCMode=TIM_OCMode_PWM2;
TIM_OCInitTypeStructure.TIM_OCPolarity=TIM_OCPolarity_High;
    TIM_OCInitTypeStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OC2Init(TIM3,&TIM_OCInitTypeStructure);

使能预装载寄存器

   TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);

使能定时器

    TIM_Cmd(TIM3,ENABLE);

在外部不断改变CCRx的值,调节占空比

    TIM_SetCompare2(TIM3,led0pwmval);

配置示例

void TIM3_PWM(u16 arr,u16 psc)
{       TIM_OCInitTypeDef TIM_OCInitTypeStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能定时器时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);//使能GPIOC和AFIO复用功能模块时钟
	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;	//选择对应的引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出     
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PC端口
        //GPIO_SetBits(GPIOC, GPIO_Pin_13 );	 // 关闭所有LED

	TIM_TimeBaseStructure.TIM_Period=arr;
	TIM_TimeBaseStructure.TIM_Prescaler=psc;
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
	
	
	TIM_OCInitTypeStructure.TIM_OCMode=TIM_OCMode_PWM2;
	TIM_OCInitTypeStructure.TIM_OCPolarity=TIM_OCPolarity_High;
        TIM_OCInitTypeStructure.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OC2Init(TIM3,&TIM_OCInitTypeStructure);
	
	TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
	TIM_Cmd(TIM3,ENABLE);
}

总示例 使用TIM3,PA7接LED


#include "stm32f10x.h"
//#include "led.h"

void TIM3_PWM(u16 arr,u16 psc)
{TIM_OCInitTypeDef TIM_OCInitTypeStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
		TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能定时器时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);//使能GPIOC和AFIO复用功能模块时钟
	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;	//选择对应的引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出     
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PC端口
      //GPIO_SetBits(GPIOC, GPIO_Pin_13 );	 // 关闭所有LED

	TIM_TimeBaseStructure.TIM_Period=arr;
	TIM_TimeBaseStructure.TIM_Prescaler=psc;
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
	
	
	TIM_OCInitTypeStructure.TIM_OCMode=TIM_OCMode_PWM2;
	TIM_OCInitTypeStructure.TIM_OCPolarity=TIM_OCPolarity_High;
  TIM_OCInitTypeStructure.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OC2Init(TIM3,&TIM_OCInitTypeStructure);
	
	TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
	TIM_Cmd(TIM3,ENABLE);
}
void Delay(__IO u32 nCount); 

int main(void)
{
u16 led0pwmval=0;
u8 dir=1;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	
 //SystemInit();	// 配置系统时钟为72M 	
 //LED_GPIO_Config(); //LED 端口初始化 
/*
  while (1)
  {
		LED1( ON );			  // 亮
		Delay(0x200000);
		LED1( OFF );		  // 灭
		Delay(0x200000);

		LED2( ON );
		Delay(0x200000);
		LED2( OFF ); 	
  }*/
	
	TIM3_PWM(899,0);
	while(1){
		Delay(1000);
		if (dir)led0pwmval+=1;
		else led0pwmval-=1;
		
		if(led0pwmval>300)dir=0;
		if(led0pwmval==0)dir=1;
		TIM_SetCompare2(TIM3,led0pwmval);
		
	}
	
}

void Delay(__IO u32 nCount)
{
  for(; nCount != 0; nCount--);
} 

遇到的问题

STM32F103C8T6数据手册里没有找到重映射表,故没有做重映射。
而且STM32F103C8T6的重映射有点问题,虽然还没遇见,mark一下

另一个问题是,对定时器配置的函数写在另一个c文件里,在头文件h里声明函数,然后c和main.c都包含h,这样搞下来总有一个main.c(34): warning: #223-D: function "TIM3_PWM_Init" declared implicitly
故上面的示例里把配置函数和主函数写在了一起

原文地址:https://www.cnblogs.com/uestcman/p/9048355.html