舵机控制So easy
2017-08-06 16:22
106 查看
难者不会,会者不难。就只看你愿不愿意尝试,硬件的乐趣又何止于此。
硬件于我何加焉?
1.原理
真正了解一个东西和会用一个东西我一直认为那是两个境界。欲达登峰造极的地步,必须究其理那是必须的。
控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
一张动图理解下原理。
2.控制
舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度伺服为例,那么对应的控制关系是这样的:
0.5ms————–0度;
1.0ms————45度;
1.5ms————90度;
2.0ms———–135度;
2.5ms———–180度;
注意:
舵机的输入线共有三条,红色中间,是电源线,一边黑色的是地线,这两根线给舵机提供最基本的能源保证,主要是电机的转动消耗。电源有两种规格,一是4.8V,一是6.0V,分别对应不同的转矩标准,即输出力矩不同,6.0V对应的要大一些,具体看应用条件;另外一根线是控制信号线,Futaba的一般为白色,JR的一般为桔黄色。
本人所用舵机为红色VCC,橙色信号线,棕色GND
上程序:(定时器0模拟PWM输出)
下面演示利用PCA模块的PWM控制舵机
注意:由于舵机硬件的要求,要想转的精度准确,首先得确保频率务必准确,如何确定频率呢?利用系统时钟分频的方法肯定是不行了。可以这样搞,利用定时器0的溢出脉冲率,来产生自己想要的脉冲。
下面这个程序演示的是右转90度的程序
下面为一圈来回转的演示
硬件于我何加焉?
1.原理
真正了解一个东西和会用一个东西我一直认为那是两个境界。欲达登峰造极的地步,必须究其理那是必须的。
控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
一张动图理解下原理。
2.控制
舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度伺服为例,那么对应的控制关系是这样的:
0.5ms————–0度;
1.0ms————45度;
1.5ms————90度;
2.0ms———–135度;
2.5ms———–180度;
注意:
舵机的输入线共有三条,红色中间,是电源线,一边黑色的是地线,这两根线给舵机提供最基本的能源保证,主要是电机的转动消耗。电源有两种规格,一是4.8V,一是6.0V,分别对应不同的转矩标准,即输出力矩不同,6.0V对应的要大一些,具体看应用条件;另外一根线是控制信号线,Futaba的一般为白色,JR的一般为桔黄色。
本人所用舵机为红色VCC,橙色信号线,棕色GND
上程序:(定时器0模拟PWM输出)
#include <reg52.h> sbit PWMOUT = P1^0; unsigned char HighRH = 0; //高电平重载值的高字节 unsigned char HighRL = 0; //高电平重载值的低字节 unsigned char LowRH = 0; //低电平重载值的高字节 unsigned char LowRL = 0; //低电平重载值的低字节 void ConfigPWM(unsigned int fr, unsigned char dc); void ClosePW 4000 M(); void main() { unsigned int i; EA = 1; //开总中断 while (1) { ConfigPWM(50, 2); for (i=0; i<40000; i++); ClosePWM(); ConfigPWM(50, 5); for (i=0; i<40000; i++); ClosePWM(); ConfigPWM(50, 7); for (i=0; i<40000; i++); ClosePWM(); ConfigPWM(50, 10); for (i=0; i<40000; i++); ClosePWM(); ConfigPWM(50, 12); for (i=0; i<40000; i++); ClosePWM(); ConfigPWM(50, 10); for (i=0; i<40000; i++); ClosePWM(); ConfigPWM(50, 7); for (i=0; i<40000; i++); ClosePWM(); ConfigPWM(50, 5); for (i=0; i<40000; i++); ClosePWM(); } } /* 配置并启动PWM,fr-频率,dc-占空比 */ void ConfigPWM(unsigned int fr, unsigned char dc) { unsigned int high, low; unsigned long tmp; tmp = (11059200/12) / fr; //计算一个周期所需的计数值 high = (tmp*dc) / 100; //计算高电平所需的计数值 low = tmp - high; //计算低电平所需的计数值 high = 65536 - high + 12; //计算高电平的重载值并补偿中断延时 low = 65536 - low + 12; //计算低电平的重载值并补偿中断延时 HighRH = (unsigned char)(high>>8); //高电平重载值拆分为高低字节 HighRL = (unsigned char)high; LowRH = (unsigned char)(low>>8); //低电平重载值拆分为高低字节 LowRL = (unsigned char)low; TMOD &= 0xF0; //清零T0的控制位 TMOD |= 0x01; //配置T0为模式1 TH0 = HighRH; //加载T0重载值 TL0 = HighRL; ET0 = 1; //使能T0中断 TR0 = 1; //启动T0 PWMOUT = 1; //输出高电平 } /* 关闭PWM */ void ClosePWM() { TR0 = 0; //停止定时器 ET0 = 0; //禁止中断 PWMOUT = 1; //输出高电平 } /* T0中断服务函数,产生PWM输出 */ void InterruptTimer0() interrupt 1 { if (PWMOUT == 1) //当前输出为高电平时,装载低电平值并输出低电平 { TH0 = LowRH; TL0 = LowRL; PWMOUT = 0; } else //当前输出为低电平时,装载高电平值并输出高电平 { TH0 = HighRH; TL0 = HighRL; PWMOUT = 1; } }
下面演示利用PCA模块的PWM控制舵机
注意:由于舵机硬件的要求,要想转的精度准确,首先得确保频率务必准确,如何确定频率呢?利用系统时钟分频的方法肯定是不行了。可以这样搞,利用定时器0的溢出脉冲率,来产生自己想要的脉冲。
下面这个程序演示的是右转90度的程序
#include "STC12.H" // 包含 "STC15W4K.H"寄存器定义头文件 void initPCA() { // 初始化定时器T0为16位自动重装方式,其溢出脉冲作PCA计数器的时钟源 TMOD=0x01; // 设置T0为16位装载方式 TH0=0xff; // 定时时间78.125uS 决定了频率为50hz对应20ms TL0=0xb8; TR0=1; // 启动定时器0 ET0=1; // 初始化PCA模块1为PWM输出方式 CMOD=0x84; // #10000100B ,选择T0为PCA计数器时钟源 CCAPM1=0x42; // 设置PCA模块1为8位PWM输出方式。脉冲在P1.4引脚输出,PWM无需中断支持。 CCAP1H=0xf9; // 设置脉冲宽度 EA=1; // 开整个单片机所有中断共享的总中断控制位 CR=1; // 启动PCA计数器(CH,CL)计数 } void main (void) { initPCA(); while(1); // 这里可以编写其它程序 } void Timer0()interrupt 1 { TH0 = 0xFF; TL0 = 0xb8; }
下面为一圈来回转的演示
#include "STC12.H" // 包含 "STC15W4K.H"寄存器定义头文件 void initPCA() { // 初始化定时器T0为16位自动重装方式,其溢出脉冲作PCA计数器的时钟源 TMOD=0x01; // 设置T0为16位装载方式 TH0=0xFF; // 定时时间78.125uS 决定了频率为50hz对应20ms TL0=0xB8; TR0=1; // 启动定时器0 ET0=1; // 初始化PCA模块1为8位PWM输出方式 CMOD=0x84; // #10000100B 空闲模式下停止PCA计数器工作 // PCA时钟源选择T0溢出信号,禁止PCA计数器溢出时中断 CCON=0; // 清零PCA计数器溢出中断请求标志位CF // CR = 0, 不允许 PCA 计数器计数,清零PCA 各模块中断请求标志位CCFn CL=0; // 清零PCA 计数器 CH=0; CCAPM1=0x42; // 设置PCA模块1为8位PWM输出方式。脉冲在P1.4引脚输出,PWM无需中断支持。 PCA_PWM1=0; // 清0 PWM 模式下的第9位 CCAP1H=0xF9; // 设置脉冲宽度 EA=1; // 开整个单片机所有中断共享的总中断控制位 CR=1; // 启动PCA计数器(CH,CL)计数 } void main (void) { unsigned int i; initPCA(); while(1) // 等待中断 { CCAP1H=0xF9; // 设置脉冲宽度-90 for (i=0; i<40000; i++); CCAP1H=0xF3; // 设置脉冲宽度-45 for (i=0; i<40000; i++); CCAP1H=0xEC; // 设置脉冲宽度 0 for (i=0; i<40000; i++); CCAP1H=0xE6; // 设置脉冲宽度+45 for (i=0; i<40000; i++); CCAP1H=0xE0; // 设置脉冲宽度+90 for (i=0; i<40000; i++); CCAP1H=0xE6; // 设置脉冲宽度+45 for (i=0; i<40000; i++); CCAP1H=0xEC; // 设置脉冲宽度 0 for (i=0; i<40000; i++); CCAP1H=0xF3; // 设置脉冲宽度-45 for (i=0; i<40000; i++); } } void Timer0()interrupt 1 { TH0 = 0xFF; TL0 = 0xb8; }
相关文章推荐
- 舵机控制
- 舵机的工作原理和控制
- Arduino教程 模拟输入输出以及电机和舵机控制
- ROS机器人Diego 1#制作(十五)机械臂的控制---通过键盘控制机械臂舵机
- Arduino—舵机控制
- Arduino-舵机控制Servo
- 15自由度机器人课程日志(四)arduino控制舵机控制器
- 树莓派控制数字舵机转动
- 舵机控制
- arduino-控制舵机
- 360度舵机和180度舵机控制方法小结
- 利用arduino 控制舵机转动
- 【Arduino】控制舵机
- Arduino 舵机控制
- 第一次小小的尝试——舵机控制
- 最简单的pwm信号控制舵机
- STC15F104E (8脚单片机)实现蓝牙串口控制舵机转向
- 如何控制舵机的速度?
- iic协议扩展板和pmw引脚控制舵机转向与超声测距的实验,可实现简易超声雷达
- Dsp28335 - ePWM - 50Hz小舵机的控制 - 代码例程