• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

舵机控制原理

武飞扬头像
牛牛ly
帮助1

舵机最早用于船舶上实现其转向功能,这就是舵机最早的由来。

1.舵机的组成:

直流电机减速齿轮组传感器(可变电阻)控制电路组成的一套自动控制系统

学新通

2.舵机与普通直流电机的区别:

直流电机是一圈圈转动的,舵机只能在一定角度内转动(有最大旋转角度比如:180度),不能一圈圈转。普通直流电机无法反馈转动的角度信息(如果带编码器就可以反馈角度),而舵机可以。用途也不同,普通直流电机一般是整圈转动做动力用,舵机是控制某物体转动一定角度用(比如机器人的关节)。

3.舵机的自动控制系统介绍

自控制电路板接收来自信号线的控制信号,控制电机转动,电机带动一系列齿轮组,减速后传动至输出舵盘。舵机的输出轴和位置反馈电位计是相连的,舵盘转动的同时,带动位置反馈电位计,电位计将输出一个电压信号到控制电路板,进行反馈,然后控制电路板根据所在位置决定电机转动的方向和速度,从而达到目标停止。 其工作流程为: 控制信号→控制电路板→电机转动→齿轮组减速→舵盘转动→位置反馈电位计→控制电路板反馈→电机转动 … … 。 类似PID闭环控制。

学新通

 4.舵机的接线

舵机的输入线共有三条,如图所示,红色中间,是电源正线一根棕色(有些是黑色)是电源地线,这两根线给舵机提供最基本的能源保证,主要是电机的转动消耗。电源有两种规格,一是4.8V,一是6.0V,分别对应不同的转矩标准,即输出力矩不同,6.0V对应的要大一些,具体看应用条件;另外一根线是控制信号线,一般为桔黄色(有些舵机为白色,主要是不同厂家可能采用不同颜色)。

5.舵机的控制原理:

舵机的信号线是做为输入线就是接收PWM信号(定时器产生)。一般PWM的周期是20ms,那么对应的频率是50hz那么改变不同的占空比就可以控制转动的角度。其中占空比从0.5-2.5ms,相对应的舵盘位置为0-180度,呈线性变化。如图所示:

学新通

 给它提供一定的脉宽,它的输出轴就会保持一定对应角度上,无论外界转矩怎么改变(只要目标不变就维持在这个角度类似PID自动控制算法),直到给它提供一个另外宽度的脉冲信号,它才会改变输出角度到新的对应位置上如所求。

舵机内部有一个基准电路,产生周期为20ms,宽度1.5ms的基准信号,有一个比较器,将外加信号与基准信号相比较,判断出方向和大小,从而生产电机的转动信号。由此可见,舵机是一种位置伺服驱动器,转动范围不能超过180度,适用于那些需要不断变化并可以保持的驱动器中,比如说机器人的关节、飞机的舵面等。

6.代码列子

用通用定时器来产生PWM(CH1)

定时器.h

  1.  
    #ifndef __GENERAL_TIM_H__
  2.  
    #define __GENERAL_TIM_H__
  3.  
    #include "stm32f4xx_hal.h"
  4.  
     
  5.  
    #define GENERAL_TIMx TIM2
  6.  
    #define GENERAL_TIM_RCC_CLK_ENABLE() __HAL_RCC_TIM2_CLK_ENABLE()
  7.  
    #define GENERAL_TIM_RCC_CLK_DISABLE() __HAL_RCC_TIM2_CLK_DISABLE()
  8.  
    #define GENERAL_TIM_GPIO_RCC_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
  9.  
    #define GENERAL_TIM_CH1_PORT GPIOA
  10.  
    #define GENERAL_TIM_CH1_PIN GPIO_PIN_15
  11.  
     
  12.  
    // 定义定时器预分频,定时器实际时钟频率为:84MHz
  13.  
    #define GENERAL_TIM_PRESCALER 840-1 // 实际时钟频率为:100KHz
  14.  
     
  15.  
    // 定义定时器周期,当定时器开始计数到GENERAL_TIMx_PERIOD值是更新定时器并生成对应事件和中断
  16.  
    #define GENERAL_TIM_PERIOD 1999 // 定时器产生中断频率为:100KHz/2000=50Hz
  17.  
     
  18.  
    /* 扩展变量 ------------------------------------------------------------------*/
  19.  
    extern TIM_HandleTypeDef htimx;
  20.  
     
  21.  
    /* 函数声明 ------------------------------------------------------------------*/
  22.  
    void GENERAL_TIMx_Init(void);
  23.  
     
  24.  
    #endif /* __GENERAL_TIM_H__ */
  25.  
     
学新通

根据配置定时器预分频值与ARR值可以设置输出的PWM的周期是20ms,频率 = 50hz 

定时器.c

  1.  
    #include "GeneralTIM/bsp_GeneralTIM.h"
  2.  
    TIM_HandleTypeDef htimx;
  3.  
     
  4.  
    void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
  5.  
    {
  6.  
    GPIO_InitTypeDef GPIO_InitStruct;
  7.  
    if(htim->Instance==GENERAL_TIMx)
  8.  
    {
  9.  
    /* 定时器通道功能引脚端口时钟使能 */
  10.  
    GENERAL_TIM_GPIO_RCC_CLK_ENABLE();
  11.  
     
  12.  
    /* 定时器通道1功能引脚IO初始化 */
  13.  
    GPIO_InitStruct.Pin = GENERAL_TIM_CH1_PIN;
  14.  
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  15.  
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  16.  
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
  17.  
    HAL_GPIO_Init(GENERAL_TIM_CH1_PORT, &GPIO_InitStruct);
  18.  
    }
  19.  
    }
  20.  
     
  21.  
     
  22.  
    void GENERAL_TIMx_Init(void)
  23.  
    {
  24.  
    TIM_ClockConfigTypeDef sClockSourceConfig;
  25.  
    TIM_MasterConfigTypeDef sMasterConfig;
  26.  
    TIM_OC_InitTypeDef sConfigOC;
  27.  
     
  28.  
    htimx.Instance = GENERAL_TIMx;
  29.  
    htimx.Init.Prescaler = GENERAL_TIM_PRESCALER;
  30.  
    htimx.Init.CounterMode = TIM_COUNTERMODE_UP;
  31.  
    htimx.Init.Period = GENERAL_TIM_PERIOD;
  32.  
    htimx.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
  33.  
    HAL_TIM_Base_Init(&htimx);
  34.  
     
  35.  
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  36.  
    HAL_TIM_ConfigClockSource(&htimx, &sClockSourceConfig);
  37.  
     
  38.  
    HAL_TIM_PWM_Init(&htimx);
  39.  
     
  40.  
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  41.  
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  42.  
    HAL_TIMEx_MasterConfigSynchronization(&htimx, &sMasterConfig);
  43.  
     
  44.  
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
  45.  
    sConfigOC.Pulse = 50; // 捕获比较寄存器的值
  46.  
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  47.  
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  48.  
    HAL_TIM_PWM_ConfigChannel(&htimx, &sConfigOC, TIM_CHANNEL_1);
  49.  
     
  50.  
    HAL_TIM_MspPostInit(&htimx);
  51.  
    }
  52.  
     
  53.  
    /**
  54.  
    * 函数功能: 基本定时器硬件初始化配置
  55.  
    * 输入参数: htim_base:基本定时器句柄类型指针
  56.  
    * 返 回 值: 无
  57.  
    * 说 明: 该函数被HAL库内部调用
  58.  
    */
  59.  
    void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
  60.  
    {
  61.  
     
  62.  
    if(htim_base->Instance==GENERAL_TIMx)
  63.  
    {
  64.  
    /* 基本定时器外设时钟使能 */
  65.  
    GENERAL_TIM_RCC_CLK_ENABLE();
  66.  
    }
  67.  
    }
  68.  
     
  69.  
     
学新通

由于ARR设置为2000时对应是20ms。那么捕获比较寄存器的值设置为50.那么对应的占空比就是0.5ms。所有一启动就会在-90度的位置。

main.c

  1.  
    #include "stm32f4xx_hal.h"
  2.  
    #include "GeneralTIM/bsp_GeneralTIM.h"
  3.  
    #include "key/bsp_key.h"
  4.  
     
  5.  
    /**
  6.  
    * 函数功能: 系统时钟配置
  7.  
    * 输入参数: 无
  8.  
    * 返 回 值: 无
  9.  
    * 说 明: 无
  10.  
    */
  11.  
    void SystemClock_Config(void)
  12.  
    {
  13.  
     
  14.  
    RCC_OscInitTypeDef RCC_OscInitStruct;
  15.  
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
  16.  
     
  17.  
    __HAL_RCC_PWR_CLK_ENABLE(); // 使能PWR时钟
  18.  
     
  19.  
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); // 设置调压器输出电压级别1
  20.  
     
  21.  
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; // 外部晶振,8MHz
  22.  
    RCC_OscInitStruct.HSEState = RCC_HSE_ON; // 打开HSE
  23.  
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; // 打开PLL
  24.  
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; // PLL时钟源选择HSE
  25.  
    RCC_OscInitStruct.PLL.PLLM = 8; // 8分频MHz
  26.  
    RCC_OscInitStruct.PLL.PLLN = 336; // 336倍频
  27.  
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; // 2分频,得到168MHz主时钟
  28.  
    RCC_OscInitStruct.PLL.PLLQ = 7; // USB/SDIO/随机数产生器等的主PLL分频系数
  29.  
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
  30.  
     
  31.  
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  32.  
    |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  33.  
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 系统时钟:168MHz
  34.  
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // AHB时钟: 168MHz
  35.  
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; // APB1时钟:42MHz
  36.  
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; // APB2时钟:84MHz
  37.  
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
  38.  
     
  39.  
    HAL_RCC_EnableCSS(); // 使能CSS功能,优先使用外部晶振,内部时钟源为备用
  40.  
     
  41.  
    // HAL_RCC_GetHCLKFreq()/1000 1ms中断一次
  42.  
    // HAL_RCC_GetHCLKFreq()/100000 10us中断一次
  43.  
    // HAL_RCC_GetHCLKFreq()/1000000 1us中断一次
  44.  
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); // 配置并启动系统滴答定时器
  45.  
    /* 系统滴答定时器时钟源 */
  46.  
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  47.  
     
  48.  
    /* 系统滴答定时器中断优先级配置 */
  49.  
    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  50.  
    }
  51.  
     
  52.  
    /**
  53.  
    * 函数功能: 主函数.
  54.  
    * 输入参数: 无
  55.  
    * 返 回 值: 无
  56.  
    * 说 明: 无
  57.  
    */
  58.  
    int main(void)
  59.  
    {
  60.  
    /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
  61.  
    HAL_Init();
  62.  
    /* 配置系统时钟 */
  63.  
    SystemClock_Config();
  64.  
     
  65.  
    KEY_GPIO_Init();
  66.  
    /* 通用定时器初始化并配置PWM输出功能 */
  67.  
    GENERAL_TIMx_Init();
  68.  
     
  69.  
    /* 启动通道PWM输出,其实脉宽:0.5ms,对应舵机的0度 */
  70.  
    HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_1);
  71.  
     
  72.  
    /* 无限循环 */
  73.  
    while (1)
  74.  
    {
  75.  
    if( KEY1_StateRead() == KEY_DOWN)
  76.  
    {
  77.  
    __HAL_TIM_SET_COMPARE(&htimx,TIM_CHANNEL_1,100);// 脉宽:1ms, // -45
  78.  
    }
  79.  
    if( KEY2_StateRead() == KEY_DOWN)
  80.  
    {
  81.  
    __HAL_TIM_SET_COMPARE(&htimx,TIM_CHANNEL_1,150);// 脉宽:1.5ms, // 0
  82.  
    }
  83.  
    if( KEY3_StateRead() == KEY_DOWN)
  84.  
    {
  85.  
    __HAL_TIM_SET_COMPARE(&htimx,TIM_CHANNEL_1,200);// 脉宽:2.0ms, // 45
  86.  
    }
  87.  
    if( KEY4_StateRead() == KEY_DOWN)
  88.  
    {
  89.  
    __HAL_TIM_SET_COMPARE(&htimx,TIM_CHANNEL_1,250);// 脉宽:2.5ms, // 90
  90.  
    }
  91.  
    HAL_Delay(200); // 延时200ms 舵机会有一个反应转速
  92.  
    }
  93.  
    }
学新通

通过按键(按键代码没列出)改变占空比从而控制舵机的角度。如果占空比大于2.5ms也只会在最大角度。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgaciji
系列文章
更多 icon
同类精品
更多 icon
继续加载