深夜水一贴,库函数版定时器产生可变频率可变脉冲数目

2019-07-20 04:15发布

用库函数实现,用到了定时器3,可以产生可变的频率和可变的脉冲数目,用到PWM模式,通过中断后计数来实现,已测试过
贴上代码:
#ifndef _Timer_pwm_init_
#define _Timer_pwm_init_
#include<stm32f10x.h>
#include "include.h"
//定时器3初始化
/*stm32的定时器简介
TIM2,TIM3,TIM4,TIM5为通用定时器
TIME1,TIME8        为高级定时器
TIME6,TIME7        为基本定时器
*/
static u16 PulseCnt=0;         //记录定时器溢出的次数
/***********定时器3初始化****************
实现功能:产生一定的方波数
工作模式:PWM1模式                        72000000
7200:预分频系数
计数器工作频率:72000000/7200=10KHz
freq:计数器上限
换算关系:计数到freq时溢出时间为:freq*0.00001(1/10KHz)
***************************************/
//结构体申明定义
TIM_TimeBaseInitTypeDef                TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_OCInitTypeDef                                  TIM_OCInitStructure;
void Timer3_Init(u16 freq,u8 Chanl)
{
        /* Compute the prescaler value */
        /* Time base configuration */
        TIM_TimeBaseStructure.TIM_Period = freq;                       //计数上线        500,50ms产生一次中断
        TIM_TimeBaseStructure.TIM_Prescaler = 7199;             //pwm时钟分频,产生10KHz的频率
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;        
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;                //向上计数
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);    //初始化结构体
        
        /* PWM1 Mode configuration: Channel */
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
        
        TIM_OCInitStructure.TIM_Pulse = (freq+1)/2;        //占空比为一半
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;    //输出极性高
        if(Chanl==1)   //1轴单独运动
        {
           TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
           TIM_OC1Init(TIM3, &TIM_OCInitStructure);
        }
        else
        {
           TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
           TIM_OC1Init(TIM3, &TIM_OCInitStructure);
        }
        if(Chanl==2)   //2轴单独运动
        {
           TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
           TIM_OC2Init(TIM3, &TIM_OCInitStructure);
        }
        else
        {
           TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
           TIM_OC2Init(TIM3, &TIM_OCInitStructure);
        }
        if(Chanl==3)   //3轴单独运动
        {
           TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
           TIM_OC3Init(TIM3, &TIM_OCInitStructure);
        }
        else
        {
           TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
           TIM_OC3Init(TIM3, &TIM_OCInitStructure);
        }
        if(Chanl==4)   //4轴单独运动
        {
           TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
           TIM_OC4Init(TIM3, &TIM_OCInitStructure);
        }
        else
        {
           TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
           TIM_OC4Init(TIM3, &TIM_OCInitStructure);
        }
        if(Chanl==12)    //12进行联动
        {
           TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
           TIM_OC1Init(TIM3, &TIM_OCInitStructure);
                 TIM_OC2Init(TIM3, &TIM_OCInitStructure);
        }
        TIM_ARRPreloadConfig(TIM3, ENABLE);   //使能预装载寄存器
        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);                                                 //TIM2_DIER[2]=1  允许更新中断
        NVIC_InitStructure.NVIC_IRQChannel =         TIM3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
}
//定时器3中断函数
//PulseCnt:脉冲计数
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)     //确认是定时器3产生中断
    {        
        TIM3->SR = (uint16_t)~TIM_IT_Update;                  //清除中断标志位        
                          PulseCnt++;    //变量加加,产生了一次脉冲                        
                }
}
/*********************************
步进电机一圈需要48个Step,被驱动8细分之后,单片机所要产生的脉冲为48X8=384个脉冲,故定时器产生八个脉冲步进电机走一步
产生指定的脉冲数
输入参数:
freq:脉冲频率
Chanl:通道
Target:设定的目标脉冲数
输出参数:无
*********************************/
void MakePulse(u16 freq,u8 Chanl,u16 TargtCnt)
{
          TargtCnt=TargtCnt*8;
          Timer3_Init(freq,Chanl);
    TIM_Cmd(TIM3, ENABLE);//使能定时器3,开始计数
          while(1)
                {
                                if((TargtCnt+1)==PulseCnt)
                                {
                                         PulseCnt=0;                                 
                                         TIM_Cmd(TIM3, DISABLE);      //关闭定时器计数,不产生脉冲
                                         break;
                                }
                                                        
          }
}
最后直接调用函数MakePulse就可以了
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。