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

发布者:Huanle最新更新时间:2018-09-20 来源: eefocus关键字:STM32  Timer  不同频率  可调占空比  PWM 手机看文章 扫描二维码
随时随地手机看文章

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




[cpp] view plaincopy

#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 引用地址:STM32一个Timer输出4路不同频率、可调占空比的PWM

上一篇:stm32f407之数字滤波(操作寄存器)
下一篇:STM32作为主机I2C,读写24C02 EEPROM

推荐阅读最新更新时间:2024-03-16 16:14

STM32】HAL库 STM32CubeMX教程六----定时器中断
前言: 今天我们来学习定时器,32的定时器有着非常丰富的功能, 输入捕获/输出比较,PWM,中断等等。是我们学习STM32最频繁使用到的外设之一,所以一定要掌握好,这节我们讲解定时器中断,本系列教程将对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 所用工具: 1、芯片: STM32F407ZET6/STM32F103ZET6 2、STM32CubeMx软件 3、IDE: MDK-Keil软件 4、STM32F1xx/STM32F4xxHAL库 5 知识概括: 通过本篇博客您将学到: SMT32定时器原理 STM32CubeMX创建定时器例程 HAL库TIM定时器函数库 定时器
[单片机]
【<font color='red'>STM32</font>】HAL库 STM32CubeMX教程六----定时器中断
stm32 定时器中断时间计算
分频值是是指你将系统时钟的频率减小,假设时钟频率是72Mhz,然后分频值是7199,现在你的定时器值就是10kHz,表示每计一个数,然后过了1/(10^4)秒,然后你的重装值就是你的时间了,如果值是9999,就表示定时时间为1s。 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); TIM_ClearITPendingBit(TIM3, TIM_IT_Update); TIM_T
[单片机]
STM32】CubeMX+HAL 输出PWM
1. 配置STM32CubeMX 前面的一些基础步骤可参见:【STM32】CubeMX+HAL 点亮LED 的【1.1】~【1.6】步骤。 核心配置: 这里我使用的是 TIM2 定时器,当然使用其他的也可以,但要注意相关配置。 1.1 TIM2 的 Mode 配置 1.2 TIM2 的 Configuration 配置 1.3 其余 GPIO 配置 PA2 的 PWM 输出作为 PA6 的输入,PA6 连接的是一个 LED ,观察是否出现呼吸灯现象。 余下步骤可参见:【STM32】CubeMX+HAL 点亮LED 的【1.10】~【1.13】步骤。 2. 添加代码 下面贴出主要代码: 2.1
[单片机]
【<font color='red'>STM32</font>】CubeMX+HAL 输出<font color='red'>PWM</font>
STM32的bootloader IAP编程
首先谈谈stm32的ISP和IAP区别和联系。 ISP(In-System Programming)在系统可编程,指电路板上的空白器件可以编程写入最终用户代码, 而不需要从电路板上取下器件,已经编程的器件也可以用ISP方式擦除或再编程。IAP(In-Application Programming) 指MCU可以在系统中获取新代码并对自己重新编程,即可用程序来改变程序。ISP和IAP技术是未来仪器仪表的发展方向。 1 ISP和IAP的工作原理 ISP的实现相对要简单一些,一般通用做法是内部的存储器可以由上位机的软件通过串口来进行改写。对于单片机来讲可以通过SPI或其它的串行接口接收上位机传来的数据并写入存储器中。所以即使我们将
[单片机]
STM32 中 BIT_BAND(位段/位带)和别名区使用入门
一、 什么是位段和别名区 是这样的,记得MCS51吗? MCS51就是有位操作,以一位(BIT)为数据对象的操作,MCS51可以简单的将P1口的第2位独立操作: P1.2=0;P1.2=1 ;这样就把P1口的第三个脚(BIT2)置0置1。而现在STM32的位段、位带别名区就为了实现这样的功能。 它的对象可以是SRAM、I/O和外设空间。要实现对这些地方的某一位的操作。它是这样做的:在寻址空间(32位对应的地址空间为 4GB )的另一地方,取个别名区空间,从这个地址开始处,每一个字(32BIT)对应SRAM或I/O的一位。 这样,1MB SRAM 就可以有 32MB 的对应别名区空间,就是1位膨胀到32位(1 BI
[单片机]
STM32 IIC OLED中英文显示
简介 ; II2C OLED 中英文显示 ADC数据采集实时显示 八路ADC 一 先上代码 #include oled.h #include sys.h #include delay.h #include oledfont.h #include delay.h #include bmp.h #include gbk.h #define uint unsigned int #define uchar unsigned char //OLED显存 u8 OLED_GRAM ; // 开始信号:SCLK为高电平 SDA由高电平跳变为低电平 开始传输数据 // 结束信号:SCLK为高电平 SDA由低电平跳变为高
[单片机]
<font color='red'>STM32</font> IIC OLED中英文显示
基于STM32的血氧仪开源设计方案
一、简介 设计一款基于STM32的血氧仪,用于测量人体血氧饱和度和心率,并将测量结果显示在LCD屏幕上。 本 产品 由STM32F103C8T6 单片机 最小系统+MAX30102 传感器 +LCD显示模块+蜂鸣器模块组成。 1.选择合适的传感器模块,如MAX30102,用于采集红光和 红外 线 信号 ,并通过单片机I IC 总线读取。 2.使用STM32 微控制器 作为主控 芯片 ,配置相应的 时钟 源和分频系数,开启需要使用的外设时钟,包括GPIO口、 ADC 、LCD等。 3.根据传感器模块和LCD屏幕的 接口 要求,进行相应的GPIO口配置和LCD初始化操作。 二、功能需求 采集功能:能够采集被测者的
[单片机]
基于<font color='red'>STM32</font>的血氧仪开源设计方案
Maxim推出新型4串、HB LED驱动器MAX16814
  日前,Maxim推出高度集成的4串HB (高亮度) LED驱动器MAX16814,每通道可输出高达150mA电流。器件集成了构建LCD TV、监视器和汽车显示器中高性能背光驱动器所需的所有功能。通过这种集成架构,MAX16814能够为设计者提供高性价比方案,在保持高性能的同时大大简化了照明设计。   MAX16814集成了开关DC-DC控制器,用于产生驱动多串LED所需的电压。器件还具有4个带有片内功率MOSFET的线性电流吸收电路,为每串LED提供最高150mA的可编程电流。自适应输出电压控制架构优化了效率,极大地降低了LED电流吸收通路的功耗。这种架构省去了多个外部元件,简化了空间受限
[电源管理]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved