定时器TIM,pwm

一、定时器

1.     定义

设置等待时间,到达后则执行指定操作的硬件。

2.    STM32F407的定时器有以下特征

具有基本的定时功能,也有PWM输出(灯光控制、电机的转速)、脉冲捕获功能(红外捕捉)

2个高级控制定时器、10个通用定时器和2个基本定时器

高级控制定时器(TIM1和TIM8)

  具有16位定时器功能,也具有PWM输出高级控制功能

通用定时器(TIM2到TIM5)

  具有16位定时功能,也具有PWM输出控制功能

通用定时器(TIM9到TIM14)

  具有16位定时功能,也具有PWM输出控制功能

基本定时器(TIM6和TIM7)

  具有16位定时功能

二、定时器初始化

1.   选择时钟源,并初始化定时器分频值与定时时间

/* TIM3 clock enable ,定时器3时钟使能*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

/* Time base configuration ,定时器基本配置*/
TIM_TimeBaseStructure.TIM_Period = (10000/1000)-1;                           //定时时间的设置[非常重要],中断频率为1000Hz,也就是定时时间为1ms
TIM_TimeBaseStructure.TIM_Prescaler = 8400-1;                             //预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;              //时钟分频,也称之为二次分频,当前是1分频,说白了不分频,不降低频率
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;        //向上计数的方法
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);                               //初始化

涉及部分寄存器参考如下

1.         中断的配置

/* TIM Interrupts enable,使能定时器3更新中断事件,也代表说定时已经到达的事件 */
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

/* TIM3 enable counter,使能定时器3工作 */
TIM_Cmd(TIM3, ENABLE);

2.         中断服务函数的编写

void TIM3_IRQHandler(void)
{
         static uint32_t cnt=0;

         //是否已经有更新中断事件
         if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
         {
                   //添加用户代码
                   cnt++;

                   if(cnt>=500)
                   {
                            cnt =0;
                            PFout(9)^=1;

                   }
                   //清空标志位,告诉CPU我已经完成中断处理
                   TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
         }

}

TIM3

#include <stdio.h>
#include "stm32f4xx.h"
#include "sys.h"

GPIO_InitTypeDef            GPIO_InitStructure;

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
NVIC_InitTypeDef         NVIC_InitStructure;

void tim3_init(void)
{
    /* TIM3 clock enable ,定时器3时钟使能*/
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    /* Enable the TIM3 gloabal Interrupt ,使能定时器3全局中断*/
    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);

    /* Time base configuration ,定时器基本配置*/
    TIM_TimeBaseStructure.TIM_Period = (10000/1000)-1;            //定时时间的设置[非常重要],中断频率为1000Hz,也就是定时时间为1ms
    TIM_TimeBaseStructure.TIM_Prescaler = 8400-1;                //预分频值
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;        //时钟分频,也称之为二次分频,当前是1分频,说白了不分频,不降低频率
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    //向上计数的方法
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);                //初始化

    /* TIM Interrupts enable,使能定时器3更新中断事件,也代表说定时已经到达的事件 */
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

    /* TIM3 enable counter,使能定时器3工作 */
    TIM_Cmd(TIM3, ENABLE);

}

int main(void)
{

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);

    /* 配置PF9引脚为输出模式 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                    //第9根引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                //设置输出模式
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                //推挽模式,增加驱动电流
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;            //设置IO的速度为100MHz,频率越高性能越好,频率越低,功耗越低
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;            //不需要上拉电阻
    GPIO_Init(GPIOF, &GPIO_InitStructure);

    PFout(9)=1;

    //定时器3初始化
    tim3_init();

    while(1)
    {

    }

}

void TIM3_IRQHandler(void)
{
    static uint32_t cnt=0;

    //是否已经有更新中断事件
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
    {
        //添加用户代码
        cnt++;

        if(cnt>=500)
        {
            cnt =0;

            PFout(9)^=1;

        }

        //清空标志位,告诉CPU我已经完成中断处理
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    }

}

tim1238_irq

#include "stm32f4xx.h"
#include "stdio.h"
#include "bitband.h"

GPIO_InitTypeDef GPIO_InitStructure;

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

NVIC_InitTypeDef NVIC_InitStructure;

void tim1_init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    //定时时间为100ms  168000000/16800=10000Hz
    TIM_TimeBaseStructure.TIM_Period = (10000/10)-1;
    TIM_TimeBaseStructure.TIM_Prescaler = 16800-1;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);

    TIM_Cmd(TIM1, ENABLE);

}

void tim2_init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    //定时时间为200ms 84000000/84000=10000Hz
    TIM_TimeBaseStructure.TIM_Period = (10000/5)-1;
    TIM_TimeBaseStructure.TIM_Prescaler = 8400-1;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    TIM_Cmd(TIM2, ENABLE);

}

void tim3_init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    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);

    //定时时间为500ms 84000000/84000=10000Hz
    TIM_TimeBaseStructure.TIM_Period = (10000/2)-1;
    TIM_TimeBaseStructure.TIM_Prescaler = 8400-1;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

    TIM_Cmd(TIM3, ENABLE);

}

void tim8_init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    //定时时间为2秒  168000000/168000=10000Hz
    TIM_TimeBaseStructure.TIM_Period = (10000*2)-1;
    TIM_TimeBaseStructure.TIM_Prescaler = 16800-1;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);

    TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE);

    TIM_Cmd(TIM8, ENABLE);

}

int main(void)
{

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOE, ENABLE);

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9|GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOF, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13|GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOE, &GPIO_InitStructure);

    PFout(9) = 1;
    PFout(10) = 1;
    PEout(13) = 1;
    PEout(14) = 1;

    tim1_init();
    tim2_init();
    tim3_init();
    tim8_init();

    while(1)
    {    

    }
}

void TIM1_UP_TIM10_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
    {

        PFout(9) ^= 1;

        TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
    }
}

void TIM2_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    {

        PFout(10) ^= 1;

        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    }
}

void TIM3_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
    {

        PEout(13) ^= 1;

        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    }
}

void TIM8_UP_TIM13_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM8, TIM_IT_Update) != RESET)
    {

        PEout(14) ^= 1;

        TIM_ClearITPendingBit(TIM8, TIM_IT_Update);
    }
}

原文地址:https://www.cnblogs.com/xiangtingshen/p/10961427.html

时间: 2024-10-10 18:57:16

定时器TIM,pwm的相关文章

STM32定时器输出PWM频率和步进电机控制速度计算

1.STM32F4系列定时器输出PWM频率计算 第一步,了解定时器的时钟多少: 我们知道AHP总线是168Mhz的频率,而APB1和APB2都是挂在AHP总线上的. (1)高级定时器timer1, timer8以及通用定时器timer9, timer10, timer11的时钟来源是APB2总线(2)通用定时器timer2~timer5,通用定时器timer12~timer14以及基本定时器timer6,timer7的时钟来源是APB1总线 从STM32F4的内部时钟树可知: 当APB1和APB

关于普通定时器与高级定时器的 PWM输出的初始化的区别

不管是普通定时器还是高级定时器,你用哪个通道,就在程序里用OC多少.比如CH3对应OC3 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;  TIM_OCInitStructure.TIM_Pulse=42;

stm32之通用定时器TIM

STM32系列的CPU,有多达8个定时器: 1.其中TMI1和TIM8是能够产生三对PWM互补输出的高级定时器,常用于三相电机的驱动:它们的时钟有APB2的输出产生: 2.其它6个为普通定时器,时钟由APB1的输出产生: 定时器的作用: 1.定时功能 2.计数功能 3.输入捕获 4.匹配输出 5.PWM脉冲波输出 概述: 通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成.它适用于多种场合,包括测量输入信号的脉冲长度(输入采集)或者产生输出波形(输出比较和PWM). 定时器是完全独

STM32普通定时器配置PWM的问题

oid TIM3_Init(void) { TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure; TIM_OCInitTypeDef  TIM_OCInitStructure; /* PWM信号电平跳变值 */ //    u16 CCR1= 36000; //    u16 CCR2= 36000; /*PCLK1经过2倍频后作为TIM3的时钟源等于72MHz*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,

stm32cube--通用定时器--产生pwm波

看了通用定时器的资料,发现内容挺多,挺难看懂,现在还是先掌握使用方法,以后再多看几遍吧. ① ② ③生成mdk工程后,在main.c的while(1)前面加上HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);就可以产生pwm波了. 通过一些实验可知,32cube配置好中断生成工程以后,程序中已经将中断相关的参数和准备工作都做好了,但我们要进入中断还必须手动添加中断的启动函数.

STM32 HAL库学习系列第7篇---定时器TIM 输入捕获功能

测量脉冲宽度或者测量频率 ? 基本方法 1.设置TIM2?CH1为输入捕获功能:? 2.设置上升沿捕获:? 3.使能TIM2?CH1捕获功能:? 4.捕获到上升沿后,存入capture_buf[0],改为捕获下降沿: ?5.捕获到下降沿后,存入capture_buf[1],改为捕获上升沿:? 6.捕获到上升沿后,存入capture_buf[2],关闭TIM2?CH1捕获功能:? 7.计算:capture_buf[2]?-?capture_buf[0]就是周期,capture_buf[1]?-?c

STM32学习笔记6(TIM通用模块生成PWM)

1.     TIMER输出PWM基本概念   脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术.简单一点,就是对脉冲宽度的控制.一般用来控制步进电机的速度等等. STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出. 1.1   PWM输出模式 S

(五)转载:通用定时器PWM输出

1.     TIMER输出PWM基本概念   脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术.简单一点,就是对脉冲宽度的控制.一般用来控制步进电机的速度等等. STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出. 1.1   PWM输出模式 S

TIM—基本定时器

本章参考资料:< STM32F4xx 参考手册>.< STM32F4xx 规格书>.库帮助文档< stm32f4xx_dsp_stdperiph_lib_um.chm>.学习本章时,配合< STM32F4xx 参考手册> 基本定时器章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分.特别说明,本书内容是以 STM32F42x 系列控制器资源讲解. TIM 简介定时器(Timer)最基本的功能就是定时了,比如定时发送 USART 数据.定时采集 AD数据等