STM32一个Timer输出4路不同频率、可调占空比的PWM

源码下载地址:http://download.csdn.net/detail/dazhou158/5253187


main.c

/*********************************************
    标题:操作USART的练习
    软件平台:MDK-ARM Standard Version4.70
    硬件平台:stm32f4-discovery	
    主频:168M
	Periph_Driver_version: V1.0.0
    
    描述:用一个定时器(TIM3),实现四路不同频率、占空比可调的PWM
		  代码参考自STM32F4-Discovery_FW_V1.1.0\Project\Peripheral_Examples\TIM_TimeBase

    author:大舟
    data:2013-04-13
**********************************************/

#include "stm32f4_discovery.h"



TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
__IO uint16_t CCR1_Val = 5000;//54618
__IO uint16_t CCR2_Val = 27309;
__IO uint16_t CCR3_Val = 13654;
__IO uint16_t CCR4_Val = 6826;
uint16_t PrescalerValue = 0;

void TIM_Config(void);


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_stm32f4xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f4xx.c file
     */

  /* TIM Configuration */
  TIM_Config();

  /** -----------------------------------------------------------------------
    TIM3 Configuration: Output Compare Timing Mode:
    
    In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1), 
    since APB1 prescaler is different from 1.   
      TIM3CLK = 2 * PCLK1  
      PCLK1 = HCLK / 4 
      => TIM3CLK = HCLK / 2 = SystemCoreClock /2
          
    To get TIM3 counter clock at 500 KHz, the prescaler is computed as follows:
       Prescaler = (TIM3CLK / TIM3 counter clock) - 1
       Prescaler = ((SystemCoreClock /2) /50 MHz) - 1
                                              
    CC1 update rate = TIM3 counter clock / CCR1_Val = 9.154 Hz	@note 上面已经将CCR1_Val改为了5000,具体频率,见中断的注释
    ==> Toggling frequency = 4.57 Hz
    
    C2 update rate = TIM3 counter clock / CCR2_Val = 18.31 Hz
    ==> Toggling frequency = 9.15 Hz
    
    CC3 update rate = TIM3 counter clock / CCR3_Val = 36.62 Hz
    ==> Toggling frequency = 18.31 Hz
    
    CC4 update rate = TIM3 counter clock / CCR4_Val = 73.25 Hz
    ==> Toggling frequency = 36.62 Hz

    Note: 
     SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file.
     Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()
     function to update SystemCoreClock variable value. Otherwise, any configuration
     based on this variable will be incorrect.    
  ----------------------------------------------------------------------- */  

  /* Compute the prescaler value */
  PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 500000) - 1;//=168

  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 65535;//65535
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  /* Prescaler configuration */
  TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate);//对84M进行168分频,即为500KHz

  /* Output Compare Timing Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OC1Init(TIM3, &TIM_OCInitStructure);
  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);

  /* Output Compare Timing Mode configuration: Channel2 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
  TIM_OC2Init(TIM3, &TIM_OCInitStructure);
  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);

  /* Output Compare Timing Mode configuration: Channel3 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
  TIM_OC3Init(TIM3, &TIM_OCInitStructure);
  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable);

  /* Output Compare Timing Mode configuration: Channel4 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
  TIM_OC4Init(TIM3, &TIM_OCInitStructure);
  TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable);
   
  /* TIM Interrupts enable */  
  TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);
	
  /* TIM3 enable counter */
  TIM_Cmd(TIM3, ENABLE);

  while (1);
}



/**
  * @brief  Configure the TIM IRQ Handler.
  * @param  None
  * @retval None
  */
void TIM_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* TIM3 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

  /* Enable the TIM3 gloabal Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* Initialize Leds mounted on STM32F4-Discovery board */
  STM_EVAL_LEDInit(LED4);
  STM_EVAL_LEDInit(LED3);
  STM_EVAL_LEDInit(LED5);
  STM_EVAL_LEDInit(LED6);

  /* Turn on LED4, LED3, LED5 and LED6 */
  STM_EVAL_LEDOn(LED4);
  STM_EVAL_LEDOn(LED3);
  STM_EVAL_LEDOn(LED5);
  STM_EVAL_LEDOn(LED6);
}






#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  while (1)
  {}
}
#endif

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/


stm32f4xx_it.c


#include "stm32f4xx_it.h"
#include "stm32f4_discovery.h"

uint16_t capture = 0;
extern __IO uint16_t CCR1_Val;
extern __IO uint16_t CCR2_Val;
extern __IO uint16_t CCR3_Val;
extern __IO uint16_t CCR4_Val;


/**
实际上当CCR1_Val每次都变化时,就可以用来改变占空比
*/
void TIM3_IRQHandler(void)
{
	/*7500为一个循环,周期为7500/500000=0.015,频率为66.67Hz*/
	if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
		
		if(CCR1_Val==5000)
		{
			STM_EVAL_LEDOn(LED4);	//PD12=0。ARR增加5000后,到达这条语句。
			CCR1_Val=2500;			//所以低电平的百分比为5000/7500=2/3。即占空比为1/3
		}
		else
		{
			STM_EVAL_LEDOff(LED4);	//PD12=1
			CCR1_Val=5000;
		}
		capture = TIM_GetCapture1(TIM3);
		TIM_SetCompare1(TIM3, capture + CCR1_Val);//在原来的CCR1(即capture)基础上加5000,则再过5000,又会触发中断
		//另外,有个问题,进入中断时,当ARR计数器快加到65535,而又不足5000时,不是会有数据多余,而产生波形的移动吗?
		//回答:不用担心。例如进入中断是,ARR=65000,65000+5000=70000>65535,那么高位会舍去,即为70000-65536=4464
		//等于是来了个循环,两次中断间ARR的增量还是5000。所以为了波形的稳定,初始化时,必须要有TIM_Period = 65535
	}
	else if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

		/* LED3 toggling with frequency = 9.15 Hz */
		STM_EVAL_LEDToggle(LED3);//PD13取反
		capture = TIM_GetCapture2(TIM3);
		TIM_SetCompare2(TIM3, capture + CCR2_Val);
	}
	else if (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);

		/* LED5 toggling with frequency = 18.31 Hz */
		STM_EVAL_LEDToggle(LED5);//PD14取反
		capture = TIM_GetCapture3(TIM3);
		TIM_SetCompare3(TIM3, capture + CCR3_Val);
	}
	else
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);

		/* LED6 toggling with frequency = 36.62 Hz */
		STM_EVAL_LEDToggle(LED6);//PD15取反
		capture = TIM_GetCapture4(TIM3);
		TIM_SetCompare4(TIM3, capture + CCR4_Val);
	}
}


/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/



ReadMe.txt


/**
  @page TIM_TimeBase TIM_TimeBase
  
  @verbatim
  ******************************************************************************
  * @file    TIM_TimeBase/readme.txt
  * @author  MCD Application Team
  * @version V1.0.0
  * @date    19-September-2011
  * @brief   Description of the TIM Time Base example.
  ******************************************************************************
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  ******************************************************************************
   @endverbatim


@par Example Description 


This example shows how to configure the TIM peripheral in Output Compare Timing 
mode with the corresponding Interrupt requests for each channel in order to generate
4 different time bases.


The TIM3CLK frequency is set to SystemCoreClock / 2 (Hz), to get TIM3 counter 
clock at 500 KHz so the Prescaler is computed as following:
   - Prescaler = (TIM3CLK / TIM3 counter clock) - 1


SystemCoreClock is set to 168 MHz for STM32F4xx Devices Revision A.


The TIM3 CC1 register value is equal to 54618, 
CC1 update rate = TIM3 counter clock / CCR1_Val = 9.154 Hz,
so the TIM3 Channel 1 generates an interrupt each 109.2ms


The TIM3 CC2 register is equal to 27309, 
CC2 update rate = TIM3 counter clock / CCR2_Val = 18.31 Hz
so the TIM3 Channel 2 generates an interrupt each 54.6ms


The TIM3 CC3 register is equal to 13654, 
CC3 update rate = TIM3 counter clock / CCR3_Val = 36.62 Hz
so the TIM3 Channel 3 generates an interrupt each 27.3ms


The TIM3 CC4 register is equal to 6826, 
CC4 update rate = TIM3 counter clock / CCR4_Val =  73.25 Hz
so the TIM3 Channel 4 generates an interrupt each 13.65ms.


When the counter value reaches the Output compare registers values, the Output 
Compare interrupts are generated and, in the handler routine, 4 pins(PD.12, PD.13,
PD.14 and PD.15) are toggled with the following frequencies: 


//引脚输出的频率
- PD.12:  4.57 Hz (CC1)
- PD.13:  9.15 Hz (CC2)
- PD.14: 18.31 Hz (CC3) 
- PD.15: 36.62 Hz (CC4)


@par Directory contents 


  - TIM_TimeBase/stm32f4xx_conf.h     Library Configuration file
  - TIM_TimeBase/stm32f4xx_it.c       Interrupt handlers
  - TIM_TimeBase/stm32f4xx_it.h       Interrupt handlers header file
  - TIM_TimeBase/main.c               Main program 
  - TIM_TimeBase/system_stm32f4xx.c   STM32F4xx system clock configuration file
  
 


@par Hardware and Software environment 


  - This example runs on STM32F4xx Devices Revision A.
  
  - This example has been tested with STM32F4-Discovery (MB997) RevA and can be
    easily tailored to any other development board.
    


  - STM32F4-Discovery  
    - Use LED4, LED3, LED5 and LED6 connected respectively to PD.12, PD.13,D.14 
    and PD.15 pins and connect them on an oscilloscope to show the different 
    Time Base signals.  


@par How to use it ? 


In order to make the program work, you must do the following :


 + EWARM
    - Open the TIM_TimeBase.eww workspace 
    - Rebuild all files: Project->Rebuild all
    - Load project image: Project->Debug
    - Run program: Debug->Go(F5)


 + MDK-ARM
    - Open the TIM_TimeBase.uvproj project
    - Rebuild all files: Project->Rebuild all target files
    - Load project image: Debug->Start/Stop Debug Session
    - Run program: Debug->Run (F5)    


 + TASKING
    - Open TASKING toolchain.
    - Click on File->Import, select General->'Existing Projects into Workspace' 
      and then click "Next". 
    - Browse to  TASKING workspace directory and select the project "TIM_TimeBase"   
    - Rebuild all project files: Select the project in the "Project explorer" 
      window then click on Project->build project menu.
    - Run program: Select the project in the "Project explorer" window then click 
      Run->Debug (F11)


 + TrueSTUDIO
    - Open the TrueSTUDIO toolchain.
    - Click on File->Switch Workspace->Other and browse to TrueSTUDIO workspace 
      directory.
    - Click on File->Import, select General->'Existing Projects into Workspace' 
      and then click "Next". 
    - Browse to the TrueSTUDIO workspace directory and select the project "TIM_TimeBase" 
    - Rebuild all project files: Select the project in the "Project explorer" 
      window then click on Project->build project menu.
    - Run program: Select the project in the "Project explorer" window then click 
      Run->Debug (F11)
   
 *

© COPYRIGHT 2011 STMicroelectronics


 */




你可能感兴趣的:(STM32,定时器,Timer,PWM,可调频率,占空比,STM32F4)