目前要实现电机加速启动和减速停止,并且要实现精确定位,就是控制PWM输出数量。频率范围 4000-40K
STM32怎么实现精确控制PWM输出数量,驱动的同时能改变频率?
这个问题可能大家问过,我在网上查了些资料,基本有一下几种方法:
1:采样PWM输出模式,外部再弄个IO口接到PWM脚上,用外部中断的办法,单独来计数。此办法可行,但个人感觉不科学,太频繁进入中断,严重影响资源。
2:使用2个定时器,使用一个和PWM频率一致的定时器,使用定时器中断来计数。但计数的过程中怎么实现频率的改变?
3:使用1个定时器产生PWM,设定一个量,改变这个量值来改变频率同时波形计数。但实验过程中频率不能较好的线性改变。
------------------------------------------------------------
以上是我个人总结的一些观点,各位大神有没有好的办法!谢谢!!!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
//看看对你有用不,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,¼ÆËãWMÆμÂêê±ò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; //Ñ¡Ôñêäèë¶Ë,IC1ó3éäμ½TI1éÏ
TIM_ICInitStructure.TIM_ICFilter = 0x0; //ÅäÖÃÂË2¨,2»ÂË2¨
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//éÏéyÑØ
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //ÅäÖ÷ÖÆμ,2»·ÖÆμ
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//ó3éäμ½TI1éÏ
// TIM_ITRxExternalClockConfig(TIM3,TIM_TS_ETRF); //ÅäÖÃía2¿′¥·¢,·ñÔò2»»á¼Æêy
// TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);
// TIM_ClearITPendingBit(TIM1,TIM_IT_Update); //
TIM_PWMIConfig(TIM3,&TIM_ICInitStructure); //¸ù¾Y2ÎêyÅäÖÃTIMíaéèDÅÏ¢
TIM_SelectInputTrigger(TIM3,TIM_TS_TI2FP2); //Ñ¡ÔñIC2Îaê¼ÖÕ′¥·¢Ô′
TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//′¥·¢DÅoÅμÄéÏéyÑØÖØDÂ3õê¼»ˉ¼ÆêyÆ÷oí′¥·¢¼Ä′æÆ÷
TIM_SelectMasterSlaveMode(TIM3,TIM_MasterSlaveMode_Enable);//Æô¶ˉ¶¨ê±Æ÷μı»¶ˉ′¥·¢
TIM_Cmd(TIM3,ENABLE); //Æô¶ˉ¶¨ê±Æ÷3
TIM_ITConfig(TIM3,TIM_IT_CC3,ENABLE); //′ò¿aÖD¶Ï′|àíoˉêy
}
void TIM3_IRQHandler(void)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC3); //Çå3yTIMμÄÖD¶Ï′y′|àíλ
IC2Value = TIM_GetCapture2(TIM3); //¶áè¡IC22¶»ñ¼Ä′æÆ÷Öμ,¼′ÎaPWMÖüÆú¼ÆêyÖμ
maijishu = TIM3->SR;
if(IC2Value != 0)
{
DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value; //¶áè¡IC12¶»ñ¼Ä′æÆ÷Öμ,2¢¼ÆËãÕ¼¿Õ±è
Frequency = 1000000 / IC2Value; //¼ÆËãWMÆμÂê,1MHZè¡éÏÃæÅäÖÃ
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¶»ñê¼t
{
jishu++; //Âö3å¼Æêy2¶»ñéÏéyÑØÂö3åx22ÅêÇêäèëÕæÕyμÄÂö3åêy
maicojishu = jishu;
}
TIM3->SR = 0; //Çå3tÖD¶Ï±ê־λ
// printf("DutyCycle= %d ",DutyCycle);
// printf("Frequency= %d ",Frequency);
}
一周热门 更多>