STM32怎么实现精确控制PWM输出数量同时能改变频率?

2019-07-21 02:44发布

目前要实现电机加速启动和减速停止,并且要实现精确定位,就是控制PWM输出数量。频率范围 4000-40K
STM32怎么实现精确控制PWM输出数量,驱动的同时能改变频率?
这个问题可能大家问过,我在网上查了些资料,基本有一下几种方法:
1:采样PWM输出模式,外部再弄个IO口接到PWM脚上,用外部中断的办法,单独来计数。此办法可行,但个人感觉不科学,太频繁进入中断,严重影响资源。
2:使用2个定时器,使用一个和PWM频率一致的定时器,使用定时器中断来计数。但计数的过程中怎么实现频率的改变
3:使用1个定时器产生PWM,设定一个量,改变这个量值来改变频率同时波形计数。但实验过程中频率不能较好的线性改变。
------------------------------------------------------------
以上是我个人总结的一些观点,各位大神有没有好的办法!谢谢!!!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
电子陌离
1楼-- · 2019-07-22 06:42
本帖最后由 电子陌离 于 2018-12-12 10:23 编辑

//看看对你有用不,DutyCycle:占空比    Frequency:频率      jishu:脉冲输入计数//实测没问题的,我做圆织机的
#include "WMinput.h"

volatile u16 IC2Value = 0;
volatile u16 DutyCycle = 0;  //Õ¼¿Õ±è
volatile u32 Frequency = 0;  //ÆμÂê
u16  maijishu = 0;   //¼ÆËãÂö3å
u32 jishu = 0;       //Âö3å½óêÕ
u32 maicojishu = 0;  //Âö3å½óêÕ
float Duty_ycle = 0;               //Õ¼¿Õ±è
float Freq_ncy = 0;                //ÆμÂê


void PWM_INPUT_Config(void)//PWMêäèë2¶»ñ3õê¼»ˉ
{
                GPIO_InitTypeDef  GPIO_InitStructure;
                NVIC_InitTypeDef  NVIC_InitStructure;
                TIM_ICInitTypeDef TIM_ICInitStructure;
          TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;     //¸¡¿Õêäèë
                GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//                GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        //        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
                GPIO_Init(GPIOA,&GPIO_InitStructure);
          GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);
//                GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_2);
    //éèÖÃÆμÂê1MHZ,¼ÆË&#227WMÆμÂêê±òaê1óÃ
                TIM_TimeBaseStructure.TIM_Period = 0xffff;//ÖüÆú0~FFFF
                TIM_TimeBaseStructure.TIM_Prescaler = 72-1;//ê±Öó·ÖÆμ,·ÖÆμêyÎa5+1¼′6·ÖÆμ
                TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//ê±Öó·Ö¸î
                TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//Ä£ê½
                TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);//»ù±¾3õê¼»ˉ        

                NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;//′ò¿aTIM3μÄ諾ÖÖD¶Ï
                NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//ÇàÕ¼óÅÏ輶Îa0
                NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//Ïìó|óÅÏ輶Îa1
                NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //ê1Äü
                NVIC_Init(&NVIC_InitStructure);

/*ê1ÄüË«±ßÑؼì2a*/
//    TIM1->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC1E);
//                TIM1->CCMR1 |= 0x03;
//                TIM1->SMCR |= (1<<6);
//                TIM1->SMCR &= ~((1<<5)|(1<<4));
//                TIM1->CCER |= ((uint16_t)TIM_CCER_CC1E);
               
                TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;   //&#209;&#161;&#212;&#241;ê&#228;è&#235;&#182;&#203;,IC1ó3é&#228;μ&#189;TI1é&#207;
                TIM_ICInitStructure.TIM_ICFilter = 0x0;        //&#197;&#228;&#214;&#195;&#194;&#203;2¨,2&#187;&#194;&#203;2¨
                TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//é&#207;éy&#209;&#216;
                TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;  //&#197;&#228;&#214;&#195;·&#214;&#198;μ,2&#187;·&#214;&#198;μ
                TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//ó3é&#228;μ&#189;TI1é&#207;
               
//                TIM_ITRxExternalClockConfig(TIM3,TIM_TS_ETRF);          //&#197;&#228;&#214;&#195;ía2&#191;′¥·¢,·&#241;&#212;ò2&#187;&#187;á&#188;&#198;êy
//    TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);
//                TIM_ClearITPendingBit(TIM1,TIM_IT_Update); //
               
                TIM_PWMIConfig(TIM3,&TIM_ICInitStructure); //&#184;ù&#190;Y2&#206;êy&#197;&#228;&#214;&#195;TIMíaéèD&#197;&#207;¢
                TIM_SelectInputTrigger(TIM3,TIM_TS_TI2FP2);  //&#209;&#161;&#212;&#241;IC2&#206;aê&#188;&#214;&#213;′¥·¢&#212;′
                TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//′¥·¢D&#197;o&#197;μ&#196;é&#207;éy&#209;&#216;&#214;&#216;D&#194;3&#245;ê&#188;&#187;ˉ&#188;&#198;êy&#198;÷oí′¥·¢&#188;&#196;′&#230;&#198;÷
                TIM_SelectMasterSlaveMode(TIM3,TIM_MasterSlaveMode_Enable);//&#198;&#244;&#182;ˉ&#182;¨ê±&#198;÷μ&#196;±&#187;&#182;ˉ′¥·¢        
                TIM_Cmd(TIM3,ENABLE);                        //&#198;&#244;&#182;ˉ&#182;¨ê±&#198;÷3
                TIM_ITConfig(TIM3,TIM_IT_CC3,ENABLE);        //′ò&#191;a&#214;D&#182;&#207;′|àíoˉêy
}
void TIM3_IRQHandler(void)
{
          TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);  //&#199;&#229;3yTIMμ&#196;&#214;D&#182;&#207;′y′|àí&#206;&#187;
                IC2Value = TIM_GetCapture2(TIM3);        //&#182;áè&#161;IC22&#182;&#187;&#241;&#188;&#196;′&#230;&#198;÷&#214;μ,&#188;′&#206;aPWM&#214;ü&#198;ú&#188;&#198;êy&#214;μ
                maijishu = TIM3->SR;
          if(IC2Value != 0)
                 {
                        DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value;   //&#182;áè&#161;IC12&#182;&#187;&#241;&#188;&#196;′&#230;&#198;÷&#214;μ,2¢&#188;&#198;&#203;&#227;&#213;&#188;&#191;&#213;±è
                        Frequency = 1000000 / IC2Value;               //&#188;&#198;&#203;&#227WM&#198;μ&#194;ê,1MHZè&#161;é&#207;&#195;&#230;&#197;&#228;&#214;&#195;
                        Duty_ycle = (float)DutyCycle;
                        Freq_ncy = (float)Frequency;
//                        maijishu = TIM_GetCounter(TIM3);
//                        maijishu = TIM_GetCapture2(TIM3);         
                 }
                else
                 {
                         DutyCycle = 0;
                         Frequency = 0;
                         Freq_ncy = 0;
                         Duty_ycle = 0;
                 }
                 if(maijishu&0x02)     //·¢éú2&#182;&#187;&#241;ê&#194;&#188;t
                 {
                         jishu++;         //&#194;&#246;3&#229;&#188;&#198;êy2&#182;&#187;&#241;é&#207;éy&#209;&#216;&#194;&#246;3&#229;x22&#197;ê&#199;ê&#228;è&#235;&#213;&#230;&#213;yμ&#196;&#194;&#246;3&#229;êy
                         maicojishu = jishu;
                 }
                 TIM3->SR = 0;      //&#199;&#229;3t&#214;D&#182;&#207;±ê&#214;&#190;&#206;&#187;
        // printf("DutyCycle= %d ",DutyCycle);
        // printf("Frequency= %d ",Frequency);
}

xtldw
2楼-- · 2019-07-22 10:32
 精彩回答 2  元偷偷看……

一周热门 更多>