本帖最后由 水墓年华 于 2019-2-26 11:17 编辑
大家好:
我是一个嵌入式初学者,现在要做一个小项目,需要用到PWM驱动的舵机,但是调试了好久也摸不清原理,代码也是网上找的,有些地方还不太理解,现在电机就是不停的正转大概30度,再转回来30度,这样一直循环,请各位帮忙解答一下
1.在定时器初始化函数中,设置时钟分频系数应该是htim2.Init.Prescaler = 168-1;将时钟频率分为更小的频率,如我的板子STM32F427是设置168M的时钟频率,设置psc=168分频,168/168=1得到1M时钟频率,但是我这样配置的话电机就不转了,我试了试最起码要在差不多400才能正常转起来,而且这个时候转的角度很小,大概在1200的时候能达到最大,大概是45度左右,是我理解的不对吗?
2.htim2.Init.Period = 200-1;这个是设定自动重装载值吗,周期是怎么算的?
3.我要如何更改代码才能实现精准的控制,比如现在怎么让舵机只朝一个方向转动
下面贴一下我的代码:
主函数
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM2_Init();
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);
int n = 50;
int dir = 0;
while(1)
{
HAL_Delay(20);
if(dir)n++; //dir==1 n 递增
else n--; //dir==0 n 递减
if(n>300)dir=0; //n 到达 300 后,方向为递减
if(n==50)dir=1; //n 递减到 0 后,方向改为递增
USER_PWM_SetDutyRatio(&htim2,TIM_CHANNEL_3,n); //修改比较值,修改占空比
}
定时器初始化
static void MX_TIM2_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig;
TIM_OC_InitTypeDef sConfigOC;
htim2.Instance = TIM2;
htim2.Init.Prescaler = 1200-1; //该分频将时钟频率分为更小的频率,如STM32F429是设置168M的时钟频率,设置psc=168分频,得到1M时钟频率
htim2.Init.CounterMode = TIM_COUNTERMODE_UP; //设置计数方式为向上计数逐一增加从0到19999,此时得到的是20ms就重装初值的定时器
htim2.Init.Period = 200-1; //自动重装载值,在设置arr=20000重装初值,由公式1M/20000=50Hz,即周期T=20ms
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
HAL_TIM_MspPostInit(&htim2);
}
调整PWM占空比,value为占空比 value=50 即占空比为50%
void USER_PWM_SetDutyRatio(TIM_HandleTypeDef *htim,uint32_t Channel,uint8_t value)
{
TIM_OC_InitTypeDef sConfigOC;
uint32_t period=htim->Init.Period+1;
uint32_t pluse=(value * period)/100;
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = pluse;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_PWM_ConfigChannel(htim, &sConfigOC, Channel);
HAL_TIM_PWM_Start(htim, Channel);
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
这样还是不行,参数我也改了好多次了
谢谢,听你这么一说恍然大悟,一下子懂了点,麻烦再问下有你有没有相关的驱动电机的代码,有的话让我参考一下可以吗,还有就是我这个是舵机只有电源正负极,白 {MOD}的信号线这三根线,那就是说这个白 {MOD}信号线接PWM波输出,没有DIR口的概念对吗,这个要怎么控制呢,能详细说说吗
一周热门 更多>