本帖最后由 lulugl 于 2023-10-12 21:21 编辑
#申请原创#
【工程目的】用Joystick手柄控制机械臂的自由运转。
舵机也叫也叫 RC 伺服器,通常用于机器人项目,也可以在遥控汽车,飞机等航模中找到它们。
类似舵机这样的伺服系统通常由小型电动机,电位计,嵌入式控制系统和变速箱组成。
电机输出轴的位置由内部电位计不断采样测量,并与微控制器(CW32L031)设置的目标位置进行比较;
根据相应的偏差,控制设备会调整电机输出轴的实际位置,使其与目标位置匹配。这样就形成了闭环控制系统。
控制原理
通过向舵机的信号信号线发送PWM信号来控制舵机的输出量;
一般来说,PWM的周期以及占空比,我们是可控的,所以PWM脉冲的占空比直接决定了输出轴的位置。
下面举个例子;
当我们向舵机发送脉冲宽度为1.5毫秒(ms)的信号时,舵机的输出轴将移至中间位置(90度);
脉冲宽度为1ms时,舵机的输出轴将移至最小的位置(0度);
脉冲宽度为2ms时,舵机的输出轴将移至最小的位置(180度);
具体可以参考下图;
占空比 = t / T 相关参数如下:
t = 0.5ms——————-舵机会转到 0 °
t = 1.0ms——————-舵机会转到 45°
t = 1.5ms——————-舵机会转到 90°
t = 2.0ms——————-舵机会转到 135°
t = 2.5ms——————-舵机会转到 180°
我们要产生50Hz(20ms)的PWM波形,我们需要用了GTIM定时器。
因为:PWM周期为20ms = (40000*24)/48000000=0.02所以:TIM_Period = 23,TIM_Prescaler = 39999,就是我的程序入口参数
为此我们初始化PWM函数如下:
//初始化pwm
void PWM_OutputConfig(void)
{
GTIM_InitTypeDef GTIM_InitStruct = {0};
__RCC_GTIM1_CLK_ENABLE();//启用GTIM1时钟
GTIM_InitStruct.Mode = GTIM_MODE_TIME; //设置为定时器模式
GTIM_InitStruct.OneShotMode = GTIM_COUNT_CONTINUE; //为连续计时模式
GTIM_InitStruct.Prescaler = 23; // 计数时钟TCLKD = TCLK/(PSC+1)
GTIM_InitStruct.ReloadValue = 40000-1; //GTIM的重载值
GTIM_InitStruct.ToggleOutState = DISABLE; //GTIM的翻转输出使能选择
GTIM_TimeBaseInit(CW_GTIM1, >IM_InitStruct);
GTIM_OCInit(CW_GTIM1, GTIM_CHANNEL3, GTIM_OC_OUTPUT_PWM_LOW);//CHy 通道输出低电平
GTIM_SetCompare3(CW_GTIM1, 2000); //1ms为2000个计数值
GTIM_Cmd(CW_GTIM1, ENABLE);
}
初始化后,我们就可以输出指定时间的pwm占空比了。根据舵机的控制时间,我们以40000/20ms来获得1ms的计数值2000。
这次我们使用摇杠来实现对机械臂的控制,实现左右旋转,以及上下的移动。
程序流程图如下:
根据摇柄的ADC值来实现左、右、中间按下以及上、下两个方向的ADC值来判断摇柄的操用动作。基代码如下:
if(valueAdc0<2000)
{
X_state = LEFT;
}
else if(valueAdc0>3900)
{
X_state = MIDD;
}
else if(valueAdc0>3300 && valueAdc0<3500)
{
X_state = RIGHT;
}
else if(valueAdc0>=2710 && valueAdc0<2730)
{
X_state = XLIFT;
}
if(valueAdc1<1860)
{
Y_state = DOWN;
}
else if(valueAdc1>=1900 && valueAdc1<2730)
{
Y_state = YLIFT;
}
else if(valueAdc1>=3300)
{
Y_state = UP;
}
然后我们根据其的状态,来实现PWM占空比的修改,实现舵机的不同角度的修正,来实现机械臂的实理控制。
void joystic_contrl(void)
{
static uint32_t x_sempler = 1500;//0度
static uint32_t y_sempler = 1500;//0度
if(X_state == LEFT)
{
x_sempler = x_sempler - x_step;
if(x_sempler <= X_MIN)
{
x_sempler = X_MIN;
}
}
else if (X_state == RIGHT)
{
x_sempler = x_sempler + x_step;
if(x_sempler >= X_MAX)
{
x_sempler = X_MAX;
}
}
else if(X_state == MIDD)
{
x_sempler = 30000;
}
X_state = XLIFT;
GTIM_SetCompare3(CW_GTIM1, x_sempler);
if(Y_state == UP)
{
y_sempler = y_sempler - y_step;
if(x_sempler <= Y_MIN)
{
x_sempler = Y_MIN;
}
}
else if (Y_state == DOWN)
{
y_sempler = y_sempler + y_step;
if(y_sempler >= Y_MAX)
{
y_sempler = Y_MAX;
}
}
Y_state = YLIFT;
GTIM_SetCompare4(CW_GTIM1, y_sempler);
}【源代码】
cw32l031-机械臂实时控制.zip
(302.59 KB)
【实验效果】
编译下载到开发板后实现了游戏摇柄对机械臂的实时控制。
|
学习一下