智能小车控制舵机,,c,,实现

2016-08-29 百科 阅读:

智能小车控制舵机,,c,,实现(一)
舵机工作原理详解及智能车单片机(飞思卡尔)控制的实现(程序)

舵机工作原理详解及单片机(飞思卡尔和51)控制的实现(程序)

1

、概述

舵机最早出现在航模运动中。在航空模型中,飞行机的飞行姿态是通过调节发动机和各个控制舵面来实现的。举个简单的四通飞机来说,飞机上有以下几个地方需要控制:

1.发动机进气量,来控制发动机的拉力(或推力);

2.副翼舵面(安装在飞机机翼后缘),用来控制飞机的横滚运动;

3.水平尾舵面,用来控制飞机的俯仰角;

4.垂直尾舵面,用来控制飞机的偏航角;

遥控器有四个通道,分别对应四个舵机,而舵机又通过连杆等传动元件带动舵面的转动,从而改变飞机的运动状态。舵机因此得名:控制舵面的伺服电机。

不仅在航模飞机中,在其他的模型运动中都可以看到它的应用:船模上用来控制尾舵,车模中用来转向等等。由此可见,凡是需要操作性动作时都可以用舵机来实现。

2、结构和控制

一般来讲,舵机主要由以下几个部分组成,舵盘、减速齿轮组、位置反馈电位计5k、直流电机、控制电路板等。

工作原理:控制电路板接受来自信号线的控制信号(具体信号待会再讲),控制电机转动,电机带动一系列齿轮组,减速后传动至输出舵盘。舵机的输出轴和位置反馈电位计是相连的,舵盘转动的同时,带动位置反馈电位计,电位计将输出一个电压信号到控制电路板,进行反馈,然后控制电路板根据所在位置决定电机的转动方向和速度,从而达到目标停止。 舵机的基本结构是这样,但实现起来有很多种。例如电机就有有刷和无刷之分,齿轮有塑料和金属之分,输出轴有滑动和滚动之分,壳体有塑料和铝合金之分,速度有快速和慢速之分,体积有大中小三种之分等等,组合不同,价格也千差万别。例如,其中小舵机一般称作微舵,同种材料的条件下是中型的一倍多,金属齿轮是塑料齿轮的一倍多。需要根据需要选用不同类型。

舵机的输入线共有三条,红色中间,是电源线,一边黑色的是地线,这辆根线给舵机提供最基本的能源保证,主要是电机的转动消耗。电源有两种规格,一是4.8V,一是6.0V,分别对应不同的转矩标准,即输出力矩不同,6.0V对应的要大一些,具体看应用条件;另外一根线是控制信号线,Futaba的一般为白色,JR的一般为桔黄色。另外要注意一点,SANWA的某些型号的舵机引线电源线在边上而不是中间,需要辨认。但记住红色为电源,黑色为地线,一般不会搞错。

舵机的控制信号为周期是20ms的脉宽调制(PWM)信号,其中脉冲宽度从0.5ms-2.5ms,相对应舵盘的位置为0-180度,呈线性变化。也就是说,给它提供一定的脉宽,它的输出轴就会保持在一个相对应的角度上,无论外界转矩怎样改变,直到给它提供一个另外宽度的脉冲信号,它才会改变输出角度到新的对应的位置上。舵机内部有一个基准电路,产生周期的20ms,宽度1.5ms的基准信号,有一个比较器,将外加信号与基准信号相比较,判断出方向和大小,从而产生电机的转动信号。由此可见,舵机是一种位置伺服的驱动器,转动范围不能超过180度,适用于那些需要角度不断变化并可以保持的驱动当中。比方说机器人的关节、飞机的舵面等。

常见的舵机厂家有:日本的Futaba、JR、SANWA等,国产的有北京的新幻想、吉林的振华等。现举Futaba S3003来介绍相关参数,以供大家设计时选用。之所以用3003是因为这个型号是市场上最常见的,也是价格相对较便宜的一种(以下数据摘自Futaba产品手册)。 尺寸(Dimensions): 40.4×19.8×36.0 mm

重量(Weight): 37.2 g

工作速度(Operating speed):0.23 sec/60°(4.8V)

0.19 sec/60°(6.0V)

输出力矩(Output torque):3.2 kg.cm (4.8V)

4.1 kg.cm (6.0V)

由此可见,舵机特点:

>体积紧凑,便于安装;

>输出力矩大,稳定性好;

>控制简单,便于和数字系统接口;

正是因为舵机有很多优点,所以,现在不仅仅应用在航模运动中,已经扩展到各种机电产品中来,在机器人控制中应用也越来越广泛。

3、用单片机来控制

正是舵机的控制信号是一个脉宽调制信号,所以很方便和数字系统进行接口。只要能产生标准的控制信号的数字设备都可以用来控制舵机,比方PLC、单片机等。这里介绍利用51系列单片机产生舵机的控制信号来进行控制的方法,编程语言为C51。之所以介绍这种方法只是因为笔者用2051实现过,本着负责的态度,所以敢在这里写出来。程序用的是我的四足步行机器人,有删改。单片机并不是控制舵机的最好的方法,希望在此能起到抛砖引玉的作用。

2051有两个16位的内部计数器,我们就用它来产生周期20 ms

的脉冲信号,根据需要,改变输出脉宽。基本思路如下(请对照下面的程序): 我用的晶振频率为12M,2051一个时钟周期为12个晶振周期,正好是1/1000 ms,计数器每隔1/1000 ms计一次数。以计数器1为例,先设定脉宽的初始值,程序中初始为1.5ms,在for循环中可以随时通过改变a值来改变,然后设定计数器计数初始值为a,并置输出p12为高位。当计数结束时,触发计数器溢出中断函数,就是void timer0(void) interrupt 1 using1 ,在子函数中,改变输出p12为反相(此时跳为低位),在用20000(代表20ms周期)减去高位用的时间a,就是本周期中低位的时间,c=20000-a,并设定此时的计数器初值为c,直到定时器再次产生溢出中断,重复上一过程。

# include <reg51.h>

#define uchar unsigned char

#define uint unsigned int

uinta,b,c,d;

/*a为舵机1的脉冲宽度,b为舵机2的脉冲宽度,单位1/1000 ms */

/*c、d为中间变量*/

/*以下定义输出管脚*/

sbit p12=P1^2;

sbit p13=p1^3;

sbit p37=P3^7;

/*以下两个函数为定时器中断函数*/

/*定时器1,控制舵机1,输出引脚为P12,可自定义*/

void timer0(void) interrupt 1 using 1

{p12=!p12; /*输出取反*/

c=20000-c; /*20000代表20 ms,为一个周期的时间*/

TH0=-(c/256); TL0=-(c%256); /*重新定义计数初值*/

if(c>=500&&c<=2500)c=a;

else c="20000-a"; /*判断脉宽是否在正常范围之内*/

}

/*定时器2,控制舵机2,输出引脚为P13,可自定义*/【智能小车控制舵机,,c,,实现】

void timer1(void) interrupt 3 using 1

{p13=!p13;

d=20000-d;

TH1=-(d/256); TL1=-(d%256);

if(d>=500&&d<=2500)d=b;

else d="20000-b";

}

/*主程序*/

void main(void)

{TMOD=0x11; /*设初值*/

p12=1;

p13=1;

a=1500;

b=1500; /*数值1500即对应1.5ms,为舵机的中间90度的位置*/

c=a;d=b;

TH0=-(a/256); TL0=-(a%256);

TH1=-(b/256); TL1=-(b%256); /*设定定时器初始计数值*/

EA=1;

ET0=1; TR0=1;EX0=1;EX1=1;

ET1=1; TR1=1;

PX0=0;PX1=0;PT1=1;PT0=1;/*设定中断优先级*/

for(;;)

{

/*在这个for循环中,可以根据程序需要

在任何时间改变a、b值来改变脉宽的输

出时间,从而控制舵机*/

因为在脉冲信号的输出是靠定时器的溢出中断函数来处理,时间很短,因此在精度要求不高的场合可以忽略。因此如果忽略中断时间,从另一个角度来讲就是主程序和脉冲输出是并行的,因此,只需要在主程序中按你的要求改变a值,例如让a从500变化到2500,就可以让舵机从0度变化到180度。另外

a值的变化不能太要记住一点,舵机的转动需要时间的,因此,程序中

快,不然舵机跟不上程序。根据需要,选择合适的延时,用一个a递增

智能小车控制舵机,,c,,实现(二)
计算机控制技术智能小车课程设计

#include<AT89x51.H>

#include <intrins.h>

#define ECHO P2_4 //超声波接口定义

#define TRIG P3_0 //超声波接口定义

#define Sevro_moto_pwm P2_7 //接舵机信号端输入PWM信号调节速度

#define Left_1_led P3_4 //P3_4接四路寻迹模块接口第一路输出信号即中控板上面标记为OUT1 #define Left_2_led P3_5 //P3_5接四路寻迹模块接口第二路输出信号即中控板上面标记为OUT2 #define Right_1_led P3_6 //P3_6接四路寻迹模块接口第三路输出信号即中控板上面标记为OUT3 #define Right_2_led P3_7 //P3_7接四路寻迹模块接口第四路输出信号即中控板上面标记为OUT4

#define Left_moto_pwm P1_1 //PWM信号端

#define Left_moto_pwm1 P1_3

#define Right_moto_pwm P1_5

#define Right_moto_pwm1 P1_7

#define Left_moto_go {P1_4=1,P1_6=1;} //左边两个电机向前走

#define Left_moto_Stop {P1_4=0,P1_6=0;} //左边两个电机停转 #define Right_moto_go {P1_0=1,P1_2=1;} //右边两个电机向前走【智能小车控制舵机,,c,,实现】

#define Right_moto_Stop {P1_0=0,P1_2=0;} //右边两个电机停转

unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90/*-*/};

unsigned char const positon[4]={ 0xfe,0xfd,0xfb,0xf7};

unsigned char disbuffcj[5]={0}; //显示缓存

unsigned char posit=1; //定义扫描数码管字数

unsigned char disbuffcs[5]={0}; //显示缓存

unsigned char i =1; //定义扫描数码管字数

unsigned int count1=0; //计左电机码盘脉冲值

unsigned int V=0; //定义其速度

unsigned char disbuffwy[5]={0}; //显示缓存

unsigned char j =1; //定义扫描数码管字数

unsigned int countsum=0;

unsigned int X=0; //定义其位移

unsigned char pwm_val_left =0;//变量定义

unsigned char push_val_left =0;// 左电机占空比N/10

unsigned char pwm_val_right =0;

unsigned char push_val_right=0;// 右电机占空比N/10

unsigned char pwm_val=0;//变量定义

unsigned char push_val=14;//舵机归中,产生约,1.5MS 信号

unsigned int timecj=0;

unsigned int timecs=0;

unsigned long S=0;

unsigned long S1=0;

unsigned long S2=0;

unsigned long S3=0;

unsigned long S4=0;

unsigned int timer=0; //延时基准变量

unsigned char timer1=0; //扫描时间变量

unsigned char flag=0; //按键标志

unsigned char flag_wx=0; //开启无线标志

bit Right_moto_stop=1;

bit Left_moto_stop =1;

bit flag_tt=1; //循迹标志

/************************************************************************/ void delay(unsigned int k) //延时函数

{

unsigned int x,y;

for(x=0;x<k;x++)

for(y=0;y<2000;y++);

}

/************************************************************************/ void Display(void) //显示间距

{

if(posit==1)

{P0=(discode[disbuffcj[posit]])&0x7f;}//产生点

else

{P0=discode[disbuffcj[posit]];}

if(posit==0)

{ P2_0=0;P2_1=1;P2_2=1;P2_3=1;}

if(posit==1)

{P2_1=1;P2_1=0;P2_2=1;P2_3=1;}

【智能小车控制舵机,,c,,实现】

if(posit==2)

{P2_1=1;P2_1=1;P2_2=0;P2_3=1;}

if(posit==3)

{P2_1=1;P2_1=1;P2_2=1;P2_3=0;}

if(++posit>=4)

posit=1;

}

/*********************************************************************/ void Display_SMG(void) //显示速度

{

if(++i>=4)i=1;

P0=discode[disbuffcs[i]];

if(i==0)

{ P2_0=0;P2_1=1;P2_2=1;P2_3=1;}

if(i==1)

{P2_1=1;P2_1=0;P2_2=1;P2_3=1;}

if(i==2)

{P2_1=1;P2_1=1;P2_2=0;P2_3=1;}

if(i==3)

{P2_1=1;P2_1=1;P2_2=1;P2_3=0;}

}

/************************************************************************/ void Display_WY(void) //显示位移

{

if(j==2)

{P0=(discode[disbuffwy[j]])&0x7f;}//产生点

else

{P0=discode[disbuffwy[j]];}

if(j==0)

{ P2_0=0;P2_1=1;P2_2=1;P2_3=1;}

if(j==1)

{P2_1=1;P2_1=0;P2_2=1;P2_3=1;}

if(j==2)

{P2_1=1;P2_1=1;P2_2=0;P2_3=1;}

if(j==3)

{P2_1=1;P2_1=1;P2_2=1;P2_3=0;}

if(++j>=4)

j=1;

}

/*************************************************************************/ void StartModule() //启动测距信号

{

TRIG=1;

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

智能小车控制舵机,,c,,实现

http://m.zhuodaoren.com/shenghuo366389/

推荐访问:51智能小车舵机 舵机控制小车方向

百科推荐文章

推荐内容

上一篇:施工企业面临采购资金 下一篇:北方工业新装甲车