程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)

STM32F103 PWM配置

在《STM32F103定时器配置》中我们介绍了PWM的产生原理,本节介绍介绍如何编码实现PWM的输出。

一、PWM相关寄存器

TIMx如果要产生PWM,除了我们上一节提到的如下寄存器:

还需要使用到:

  • 捕获/比较模式寄存器(TIMx_CCM1/2);
  • 捕获/比较使能寄存器(TIMx_CCER);
  • 捕获/比较寄存器(TIMx_CCR1~4);
  • 刹车和死区寄存器(TIMx_BDTR)(只有高级定时器用到)。

注意:这里捕获指的是输入捕获,比较指的时输出比较。

1.1 捕获/比较模式寄存器(TIMx_CCMR1/2

捕获/比较模式寄存器一共有两个:

  • TIMx_CCMR1:控制通道1和2;
  • TIMx_CCMR2:控制通道3和4;

这里以 TIMx_CCM1寄存器为例进行介绍:

1.2 捕获/比较使能寄存器(TIMx_CCER

TIMx_CCER寄存器每4位描述一个通道;

其中:

  • CCxE:输入/捕获x输出使能位,我们需要重点关注;
  • CCxP:输入/捕获x输出极性。

1.3 捕获/比较寄存器(TIMx_CCR1~4

捕获/比较模式寄存器一共有4个,依次用于描述每一个通道,这里以TIMx_CCR1为例;

1.4 刹车和死区寄存器(TIMx_BDTR

TIMx_BDTR寄存器需要重点关注位15主输出使能位;

二、PWM生成源码

2.1 PWM初始化步骤

PWM生成配置流程如下:

(1) TIMx时钟使能:通过配置RCC_APB1ENR/RCC_APB2ENR寄存器使能TIMx时钟;

(2) GPIO功能复用:配置GPIO(比如TIM1通道1PA8)为复用功能推挽输出模式;

(3) 配置TIMx时基单元;

  • 配置TIMx_ARR寄存器自动重装载的值;
  • 配置TIMx_PSC寄存器预分频系数;

(4) 配置PWM相关寄存器;

  • 配置TIMx_CCMRx寄存器:

    • 输入捕获/比较输出选择(CCxS):配置为比较输出(用于实现PWM输出功能);
    • 输出比较模式(CCxM):配置为PWM模式1或者PWM模式2;
  • 配置TIMx_CCER寄存器:

    • 输入捕获/比较输出使能(CCxE):即开启比较输出功能,这样才能输出PWM
  • 针对高级定时器配置TIMx_BDTR寄存器位15:使能PWM输出;

(5) 允许TIMx工作:配置TIMx_CR10

(6) 修改TIMx_CCRx寄存器可以改变占空比。

2.2 源码实现

2.2.1 PWM初始化

PWM初始化函数TIM_PWM_Init定义如下:

/**************************************************************************************************************
 *
 *		 Description:   高级定时器1和8   APB2预分频系数=1 则计数器的时钟频率为 APB2  否则APB2*2
 *						 通用定时器2~7    APB1预分频系数=1 则计数器的时钟频率为 APB1  否则APB1*2
 *       Parameter  :    timx           TIMER1~TIMER5 8
                         DEFAULT_PSC    默认预分频系数 
                                        计数器的时钟频率 =  Fclk/(PSC[15:0]+1)   Fclk单位MHZ    
                         time           中断时间 = (ARR+1)/计数器的时钟频率       单位us
                                        中断频率 = Fclk*1000/((PSC+1)*(ARR+1))  单位kHZ
 *						 frequent       频率: 1~360  单位khz
						 Channel		通道		  PWM_CH1~4
 *
 **************************************************************************************************************/ 
void TIM_PWM_Init(TIMn timn,u8 frequent,PWM_CHANNEL Channel)         //PWM初始化                  
{
    u16 arr;							    //存放自动重装载的值
	u8 fclk;                                //存放定时器时钟频率  MHZ
	u16 DEFAULT_PSC = 1;					//默认预分频系数为1
	u8 REMAP=0x00;                          //映射情况 0x00默认 0x01  0x02:  0x03  自己设置   
	if(timn==0||timn==7) 	                //定时器1或8   
	{
		 fclk = 72;                        //默认APB2 1倍频
	}
	else 
	{
	     fclk =72;						   //默认APB1 2倍频
	}
	arr = fclk*1000/(DEFAULT_PSC+1)/frequent-1;
	//**************************************************************************************** 
	if(timn==0)                        //定时器1
	{
	  RCC->APB2ENR |=1<<11;                 //高级定时器1时钟使能
	  TIM1->BDTR|=1<<15;                    //主输出(pwm)使能(必须)
	  if(REMAP==0x00)          //默认情况下
	  {
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA8,GPO_MULPUSH_PULL_50,HIGH);     //复用推挽输出,最大速度50MHZ    主输出
			gpio_init(PB13,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ	 互补输出
			break;
		 case  PWM_CH2:
          	gpio_init(PA9,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			gpio_init(PB14,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PA10,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			gpio_init(PB15,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PA11,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else if(REMAP==0x01)	     //部分映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<6);                   //位7:6清零   
		 AFIO->MAPR   |= REMAP<<6;                   //TIM1部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA8,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
		    gpio_init(PA7,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PA9,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
		    gpio_init(PB0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PA10,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			gpio_init(PB1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PA11,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else if(REMAP==0x03)									   //完全映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<6);                   //位7:6清零   
		 AFIO->MAPR   |= REMAP<<6;                   //TIM1完全映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PE9,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
		    gpio_init(PE8,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PE11,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			gpio_init(PE10,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PE13,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			gpio_init(PE12,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PE14,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }	  
	  } 
	  else
	  {
	    ASSERT(0);
	  }
	}
	//********************************************************************************************   
	else if(timn==1)                   //定时器2
	{
	  RCC->APB1ENR |=1<<0;                  //定时器2时钟使能  
	  if(REMAP==0x00)          //默认情况下
	  {
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PA1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PA2,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PA3,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else if(REMAP==0x01)	     //部分映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<8);                   //位9:8清零   
		 AFIO->MAPR   |= REMAP<<8;                   //TIM2部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA15,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PB3,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PA2,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PA3,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else if(REMAP==0x02)									   //部分映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<8);                   //位9:8清零   
		 AFIO->MAPR   |= REMAP<<8;                   //TIM2部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PA1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PB10,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PB11,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }	  
	  } 
	  else if(REMAP==0x03)									   //完全映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<8);                   //位9:8清零   
		 AFIO->MAPR   |= REMAP<<8;                   //TIM2部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA15,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PB3,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PB10,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PB11,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }	  
	  } 
	  else
	  {
	    ASSERT(0);
	  } 
	}   
	//*****************************************************************************************************************       
    else if(timn==2)                   //定时器3
	{
	  REMAP=0x03; 
	  RCC->APB1ENR |=1<<1;                  //定时器3时钟使能 
	  if(REMAP==0x00)          //默认情况下
	  {
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA6,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PA7,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PB0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PB1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else if(REMAP==0x02)									   //部分映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<10);                   //位11:10清零   
		 AFIO->MAPR   |= REMAP<<10;                   //TIM3部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PB4,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PB5,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PB0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PB1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }	  
	  } 
	  else if(REMAP==0x03)									   //完全映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<10);                   //位11:10清零   
		 AFIO->MAPR   |= REMAP<<10;                   //TIM3部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PC6,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PC7,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PC8,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PC9,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }	  
	  } 
	  else
	  {
	    ASSERT(0);
	  }  

	}   
    //*********************************************************************************************************	    
	else if(timn==3)                   //定时器4
	{
	  RCC->APB1ENR |=1<<2;                  //定时器4时钟使能  
	  if(REMAP==0x00)          //默认情况下
	  {
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PB6,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PB7,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PB8,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PB9,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else if(REMAP==0x01)	     //完全映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟  
		 AFIO->MAPR   |= REMAP<<12;                  //TIM4部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PD12,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PD13,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PD14,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PD15,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else
	  {
	    ASSERT(0);
	  } 
	}  
	//*********************************************************************************************************** 	              
    else if(timn==4)                   //定时器5
	{
	  RCC->APB1ENR |=1<<3;                  //定时器5时钟使能
	  switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PA1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PA2,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PA3,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	}    
	//********************************************************************************************************
	else if(timn==7)      
	{
	   RCC->APB2ENR |=1<<13;                //定时器8时钟使能
	   TIM8->BDTR|=1<<15;                    //主输出(pwm)使能(必须) 
	   switch(Channel)
	   {  
	   case  PWM_CH1:
          	gpio_init(PC6,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
		  	gpio_init(PA7,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PC7,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
		    gpio_init(PB0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PC8,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			gpio_init(PB1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PC9,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 } 
	}	           
	else
	{
	   ASSERT(0);
	}                           
    TIMx[timn]->PSC  = DEFAULT_PSC;       //预分频值
    TIMx[timn]->ARR  = arr;		    	  //重新装载的值
	switch(Channel)
	{
	  case PWM_CH1:
	        TIMx[timn]->CCMR1 |=0x07<<4;    //PWM2输出模式设置
			//TIMx[timn]->CCMR1 |=0X01<<3;  //输出比较预装载使能 
			//TIMx[timn]->CR1 = 1<<7;       //自动重装在预装载允许位
			TIMx[timn]->CCER |=  0x0F;       //低电平有效 CH1使能  如是TIM1则互补输出使能
	        TIMx[timn]->CCR1  =0;           //初始化占空比为0
			break;
	 case PWM_CH2:
	        TIMx[timn]->CCMR1 |=0x07<<12;    //PWM2输出模式设置
			//TIMx[timn]->CCMR1 |=0X01<<3;   //输出比较预装载使能 
			//TIMx[timn]->CR1 = 1<<7;        //自动重装在预装载允许位
			TIMx[timn]->CCER |=  0x0F<<4;     //低电平有效 CH2使能  如是TIM1则互补输出使能
	        TIMx[timn]->CCR2  =0;            //初始化占空比为0
			break;
	 case PWM_CH3:
	        TIMx[timn]->CCMR2 |=0x07<<4;     //PWM3输出模式设置
			//TIMx[timn]->CCMR1 |=0X01<<3;   //输出比较预装载使能 
			//TIMx[timn]->CR1 = 1<<7;        //自动重装在预装载允许位
			TIMx[timn]->CCER |=  0x0F<<8;     //低电平有效 CH3使能	如是TIM1则互补输出使能
	        TIMx[timn]->CCR3  =0;            //初始化占空比为0
			break;
	 case PWM_CH4:
	        TIMx[timn]->CCMR2 |=0x07<<12;    //PWM4输出模式设置
			//TIMx[timn]->CCMR1 |=0X01<<3;   //输出比较预装载使能 1:更新事件时装载
			//TIMx[timn]->CR1 = 1<<7;        //自动重装在预装载允许位
			TIMx[timn]->CCER =  0x03<<12;     //低电平有效 CH2使能
	        TIMx[timn]->CCR4  =0;            //初始化占空比为0
			break;
	}
	
    //TIMx[timn]->DIER = 1<<0;				//允许更新(溢出)中断   UIE=1;
      TIMx[timn]->CR1  = 1<<0;              //使能计数器 开始计数
}

2.2.2 PWM占空比调节

PWM占空比调节函数:

/**************************************************************************************************************
 *
 *		 Description:  PWM设置
 *       Parameter  :    timx           TIMER1~TIMER5 8
                         DEFAULT_PSC    默认预分频系数 
						 Channel		通道		PWM_CH1~4
						 duty           占空比      0~100
 *
**************************************************************************************************************/
void TIM_PWM_Duty(TIMn timn,u8 duty,PWM_CHANNEL Channel)         //PWM占空比设置
{
  	u16 arr;
	u16 temp;                    //CCRx装载值
	arr = TIMx[timn]->ARR;
	temp = duty*arr/100;
	if(Channel==PWM_CH1)
	       TIMx[timn]->CCR1  =temp;            //设置占空比
	else if(Channel==PWM_CH2)
	       TIMx[timn]->CCR2  =temp;            //设置占空比
	else if(Channel==PWM_CH3)
	       TIMx[timn]->CCR3  =temp;            //设置占空比
	else if(Channel==PWM_CH4)
	       TIMx[timn]->CCR4  =temp;            //设置占空比
	else
	{
	  ASSERT(0);
	}
} 

2.3 实现功能

由于LED1连接的是PA8引脚,而这个引脚正好是TIM1CH1的输出引脚,因此我们可以通过调节占空比,来使得LED1越来越亮。

2.3.1 main函数实现
int main()
{
   u8 i=100;
   STM32_Clock_Init(9);                              //系统时钟初始化

   STM32_NVIC_Init(2,USART1_IRQn,0,1);		        //串口中断优先级初始化,其中包括中断使能
   usart_init(USART_1,115200);				        //串口1初始化,波特率115200 映射到PA9 PA10

   // LED1初始化
   gpio_init(PA8,GPO_SpeedMax_50,HIGH);              //PA8接入LED1

   TIM_PWM_Init(TIMER1, 100, PWM_CH1);              // PWM初始化,频率为100kHz
   TIM_PWM_Duty(TIMER1, 50, PWM_CH1);
   while(1)
   {
	   for(i=100;i>0;i--)						      //LED1越来越亮
	   {
	      TIM_PWM_Duty(TIMER1, i, PWM_CH1);
		  if(i%10==0)
		  {
				printf("duty: %d\n",i);
		  }
		  delay_ms(15);	                          
	   }
   }
}
2.3.3 测试

编译程序并下载测试:

可以通过串口查看当前输出的占空比。

此外,如果有示波器或者逻辑分析器,可以更直观的查看PA8引脚输出的波形。

这里我们将PA8引脚连接到逻辑分析仪的通道0

这里一个时钟周期为10us,换算成频率就是10kHz,与我们程序设置的一致。

三、源码下载

源码下载路径:stm32f103

posted @ 2024-12-05 00:02  大奥特曼打小怪兽  阅读(452)  评论(0)    收藏  举报
如果有任何技术小问题,欢迎大家交流沟通,共同进步