STM32之定时器中断

STM32总共有8个定时器,TIM1和TIM8是16位的高级定时器,TIM2、TIM3、TIM4、TIM5是通用定时器。本实验中只是讲解通用定时器TIM3,利用TIM3产生4路不同占空比的方波。

通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括:

16位向上、向下、向上/向下自动装载计数器

 ● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536(2^16,十六位寄存器啊)之间的任意数值

● 4个独立通道: ─ 输入捕获 ─ 输出比较 ─ PWM生成(边缘或中间对齐模式) ─ 单脉冲模式输出

● 使用外部信号控制定时器和定时器互连的同步电路

● 如下事件发生时产生中断/DMA: ─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ─ 输入捕获 ─ 输出比较

● 支持针对定位的增量(正交)编码器和霍尔传感器电路

● 触发输入作为外部时钟或者按周期的电流管理时基单元


可编程通用定时器的主要部分是一个16位计数器和与其相关的自动装载寄存器。这个计数器可以向上计数、向下计数或者向上向下双向计数。此计数器时钟由预分频器分频得到。 计数器、自动装载寄存器和预分频器寄存器可以由软件读写,在计数器运行时仍可以读写。 时基单元包含:

● 计数器寄存器(TIMx_CNT)

● 预分频器寄存器 (TIMx_PSC)

● 自动装载寄存器 (TIMx_ARR)

自动装载寄存器是预先装载的,写或读自动重装载寄存器将访问预装载寄存器。根据在TIMx_CR1寄存器中的自动装载预装载使能位(ARPE)的设置,预装载寄存器的内容被立即或在每次的更新事件UEV时传送到影子寄存器。当计数器达到溢出条件(向下计数时的下溢条件)并当TIMx_CR1寄存器中的UDIS位等于’0’时,产生更新事件更新事件也可以由软件产生。随后会详细描述每一种配置下更新事件的产生。


时钟选择

计数器时钟可由下列时钟源提供:

● 内部时钟(CK_INT)

● 外部时钟模式1:外部输入脚(TIx)

● 外部时钟模式2:外部触发输入(ETR)

● 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器


/****************************************************************************

* 名    称:int main(void)

* 功    能:主函数

* 入口参数:无

* 出口参数:无

* 说    明:

* 调用方法:无

****************************************************************************/

int main(void)

{  

    unsigned char a=0;

    TIM_OCInitTypeDef  TIM3_OCInitStructure;

    RCC_Configuration(); 

    time_ini();          

    SysTick_Config(72000);    //配置SYSTICK时钟节拍为1ms一次

    while(1){

        Delay(1);         //延时1ms   

        TIM3_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;        //PWM模式2

        TIM3_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出禁止       

        TIM3_OCInitStructure.TIM_Pulse = CCR2_Val;                  //确定占空比

        TIM3_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;

        TIM_OC2Init(TIM3, &TIM3_OCInitStructure)

        /*调整CCR2_Val的值来改变占空比,逐步的控制LED1的亮度, 占空比大过一定值时,亮度的变化就不明显了,所以CCR2_VAL最大设定到17000*/

        if(a==0) CCR2_Val=CCR2_Val+10;                                   

        else CCR2_Val=CCR2_Val-10;

        if(CCR2_Val>17000){ CCR2_Val=17000; a=1;}                           

        else if(CCR2_Val<200){ CCR2_Val=200; a=0;}

    }

}

TIM_OCInitTypeDef  TIM3_OCInitStructure;

定义了一个TIM_OCInitTypeDef的结构体

 

void time_ini(void){

  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;        //PB5复用为TIM3的通道2

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /*TIM3局部复用功能开启   在TIM3的局部复用开启时,PB5会被复用为TIM3_CH2*/

  GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3 , ENABLE);          

               

   /*-------------------------------------------------------------------

  TIM3CLK=72MHz  预分频系数Prescaler=2 经过分频 定时器时钟为24MHz

  根据公式 通道输出占空比=TIM3_CCR2/(TIM_Period+1),可以得到TIM_Pulse的计数值

  捕获/比较寄存器2 TIM3_CCR2= CCR2_Val         

  -------------------------------------------------------------------*/

  TIM3_TimeBaseStructure.TIM_Prescaler = 2;               //预分频器TIM3_PSC=3

  TIM3_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    //计数器向上计数模式 TIM3_CR1[4]=0

  TIM3_TimeBaseStructure.TIM_Period =24000;                           //自动重装载寄存器TIM3_APR  确定频率为1KHz             

  TIM3_TimeBaseStructure.TIM_ClockDivision = 0x0; /时钟分频因子 TIM3_CR1[9:8]=00

  TIM3_TimeBaseStructure.TIM_RepetitionCounter = 0x0;

  TIM_TimeBaseInit(TIM3,&TIM3_TimeBaseStructure); //写TIM3各寄存器参数

  TIM3_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;              //PWM模式2 TIM3_CCMR1[14:12]=111 在向上计数时, //一旦TIMx_CNT

  TIM3_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;    //输入/捕获2输出允许  OC2信号输出到对应的输出引脚PB5

  TIM3_OCInitStructure.TIM_Pulse = CCR2_Val;//确定占空比,这个值决定了有效电平的时间。

  TIM3_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;       //输出极性  低电平有效 TIM3_CCER[5]=1;

  TIM_OC2Init(TIM3, &TIM3_OCInitStructure);

  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

  TIM_Cmd(TIM3,ENABLE);                                       //启动定时器3 TIM3_CR1[0]=1;

}

 


PWM 模式

脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。 在TIMx_CCMRx寄存器中的OCxM位写入’110’(PWM模式1)或’111’(PWM模式2),能够独立地设置每个OCx输出通道产生一路PWM。必须设置TIMx_CCMRx寄存器OCxPE位以使能相应的预装载寄存器,最后还要设置TIMx_CR1寄存器的ARPE位,(在向上计数或中心对称模式中)使能自动重装载的预装载寄存器。 仅当发生一个更新事件的时候,预装载寄存器才能被传送到影子寄存器,因此在计数器开始计数之前,必须通过设置TIMx_EGR寄存器中的UG位来初始化所有的寄存器。 OCx的极性可以通过软件在TIMx_CCER寄存器中的CCxP位设置,它可以设置为高电平有效或低电平有效。TIMx_CCER寄存器中的CCxE位控制OCx输出使能。详见TIMx_CCERx寄存器的描述。 在PWM模式(模式1或模式2)下,TIMx_CNT和TIMx_CCRx始终在进行比较,(依据计数器的计数方向)以确定是否符合TIMx_CCRx≤TIMx_CNT或者TIMx_CNT≤TIMx_CCRx。然而为了与OCREF_CLR的功能(在下一个PWM周期之前,ETR信号上的一个外部事件能够清除OCxREF)一致,OCxREF信号只能在下述条件下产生:

当比较的结果改变,或当输出比较模式(TIMx_CCMRx寄存器中的OCxM位)从“冻结”(无比较,OCxM=’000’)切换到某个PWM模式(OCxM=’110’或’111’)。 这样在运行中可以通过软件强置PWM输出。 根据TIMx_CR1寄存器中CMS位的状态,定时器能够产生边沿对齐的PWM信号或中央对齐的PWM信号。

 

 

 

你可能感兴趣的:(STM32,串口)