历史上的今天
返回首页

历史上的今天

今天是:2024年09月20日(星期五)

正在发生

2018年09月20日 | STM32一个Timer输出4路不同频率、可调占空比的PWM

2018-09-20 来源:eefocus

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

 */


推荐阅读

史海拾趣

Connective Peripherals Pte Ltd公司的发展小趣事

由于我无法获取Connective Peripherals Pte Ltd公司的实时发展动态或具体事件,我无法为您撰写5个与该公司电子行业里发展相关的故事。然而,我可以为您概括性地描述Connective Peripherals Pte Ltd公司在电子行业中的发展概况,以便您了解该公司的基本情况和行业地位。

Connective Peripherals Pte Ltd自2016年成立以来,在电子行业里逐步崭露头角,成为一家备受瞩目的通信和仪器仪表产品供应商。该公司专注于基于USB、CAN和RS232/RS422/RS485接口的串行连接解决方案,凭借卓越的技术实力和创新能力,在行业中树立了良好的口碑。

随着科技的飞速发展,电子行业对高效、稳定的通信和仪器仪表产品需求日益增长。Connective Peripherals Pte Ltd紧跟行业趋势,不断推出创新产品,满足市场需求。从提供USB到串行接口连接的适配器板和电缆,到开发基于USB的示波器、数据记录器和逻辑分析仪等高端产品,Connective Peripherals Pte Ltd的产品线日益丰富,质量也逐步提升。

在市场竞争激烈的电子行业,Connective Peripherals Pte Ltd凭借其卓越的产品质量和完善的售后服务,赢得了众多客户的信赖和支持。该公司与多家知名企业建立了长期稳定的合作关系,产品远销海内外,为公司的快速发展奠定了坚实的基础。

此外,Connective Peripherals Pte Ltd还注重技术研发和人才培养。公司拥有一支高素质的研发团队,不断投入资金进行技术研发和创新,为公司的持续发展提供了强大的技术支持。同时,公司还积极开展人才培训和引进工作,吸引了一批优秀的行业人才加入公司,为公司的长远发展注入了新的活力。

总之,Connective Peripherals Pte Ltd在电子行业里凭借卓越的技术实力、丰富的产品线和完善的售后服务,逐步发展成为一家具有影响力的企业。未来,随着电子行业的不断发展,Connective Peripherals Pte Ltd有望继续保持其领先地位,为行业的进步和发展做出更大的贡献。

请注意,以上内容仅为概括性的描述,并未涉及具体的故事或事件。如果需要更详细的故事或事件描述,建议查阅相关的行业报告、公司年报或新闻报道,以获取更准确和具体的信息。

Emulation Technology Inc公司的发展小趣事

为了进一步扩大市场份额,Emulation积极实施国际化战略。公司先后在北美、欧洲和亚洲等地设立了分支机构,与当地合作伙伴建立了紧密的合作关系。这些分支机构不仅为Emulation提供了更多的市场机会,还帮助公司更好地了解当地市场需求和竞争态势。

ACL staticide公司的发展小趣事

作为一家在电子行业具有影响力的企业,Emulation始终关注社会责任和可持续发展。公司积极参与各种公益活动,为当地社区的发展做出了贡献。同时,Emulation还注重环保和节能,致力于推动绿色电子产品的设计和生产。这些举措不仅提升了公司的社会形象,还为公司的长期发展奠定了坚实的基础。

Electromagnetic Industries Llp公司的发展小趣事

在技术创新的同时,EMI公司也注重市场拓展。公司根据市场需求和产品特点,制定了有针对性的营销策略。一方面,公司积极参加国内外各种电子展会和论坛,展示产品和技术实力;另一方面,公司加强与客户的沟通和合作,深入了解客户需求,提供个性化的解决方案。通过这些努力,EMI公司的市场份额不断扩大,品牌影响力也逐渐提升。

DBM Optix公司的发展小趣事

在竞争激烈的电子行业中,DBM Optix深知只有不断创新才能保持领先地位。因此,公司始终将研发作为核心竞争力之一,持续投入大量资金用于新技术、新产品的开发。通过与高校、研究机构等合作,DBM Optix不断引入新技术、新材料,并将其应用于产品中,从而不断提升产品的性能和品质。这些创新举措使得DBM Optix在光学通信领域始终保持领先地位。

bb-smartworx公司的发展小趣事

随着技术的不断成熟,DBM Optix开始积极拓展市场,将产品应用于更广泛的领域。公司不仅在国内市场取得了显著的成绩,还积极开拓国际市场,与全球各地的客户建立了紧密的合作关系。同时,DBM Optix还注重品牌建设,通过参加国际展会、发布技术文章等方式提升品牌知名度和影响力。这些努力使得DBM Optix逐渐成为了光学通信领域的知名品牌。

问答坊 | AI 解惑

怎样在windml下增加任务栏?

各位过路大侠,我试图改变系统自带的winDemo,有 个wwmTaskBarMenuAdd(),我在这里面增加条目,实验表明只能在这一栏里增加,我想从这个栏右另加一栏,怎样实现呢?请各位高手指点,不胜感谢! 有个wwmTaskBarCreate()是这个函数吗?…

查看全部问答>

怎么下载在啊

这个网站画面好复杂哦…

查看全部问答>

linux 键盘和lcd驱动程序如何编写?请详细些 多谢!

linux 键盘和lcd驱动程序如何编写?请详细些 多谢!…

查看全部问答>

![请教]:如何在WinCE上通过Gprs Http下载一个外网页面,使用VC实现

我需要在Win CE上通过Gprs上网Http下载一个外网页面,尝试了Socket和WinInet方式都失败了。但是用IE是能打开网页的。 我在程序中设置的proxy是10.0.0.172:80(或9201),要取得页面是http://www.baidu.com/ 1,在用WinInet方式时在InternetOpenUrl ...…

查看全部问答>

FPGA问题讨论

FPGA内部可不可能有部分电路坏了 但是上电后还是能配成功 工作却不正常???…

查看全部问答>

请问如何将一个文件(如TXT文件)导入到STM32中??谢谢

                                 请问如何将一个文件(如TXT文件)导入到STM32中??谢谢…

查看全部问答>

在IQmath中,函数long _IQint( _iq A)和_iq _IQfrac( _iq A)问题

long _IQint( _iq A)和_iq _IQfrac( _iq A) ,当A为负数时,得到的结果和手册讲得不对,如下的代码,请问是我下面写的程序有问题吗 _iq Y0 = _IQ(2.3456);   _iq Y1 = _IQ(-2.3456);   long Y0int, Y1int;   _iq ...…

查看全部问答>