《单片机控制8路舵机15377.pdf》由会员分享,可在线阅读,更多相关《单片机控制8路舵机15377.pdf(10页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、 单片机控制舵机 附:单片机控制 8 路舵机程序,串口通讯上位机程序(C#)一、设计容综述 机械臂主要由手部和运动机构组成。手部是用来抓持工件的部件,运动机构使手部完成各种转动、移动或复合运动来实现规定的动作。为了抓取空间中任意位置和方位的物体,需有 6 个自由度,用六个舵机来控制。由单片机产生六路占空比可调的 PWM 信号来控制机械手的运动。利用上位机与单片机通信,改变占空比从而控制机械臂。为了使机械手运动时保持一定的连贯性,同时刻到达指定位置,机械手不同部位运动的速度应该不同,转一个小角度时舵机的速度应该慢一些,从而达到柔性控制。二、所使用的关键器件和基本参数 舵机 TR213:1.速度:
2、0.15 秒/60 度(4.8V);0.12 秒/60 度(6.0V)2.扭矩:13kgcm 3.围:180 4.控制精度:0.5 5.精度:精度高,步进角度很小 MAX232:1.符合所有的 RS-232C 技术标准 2.只需要单一+5V 电源供电,片载电荷泵具有升压、电压极性反转能力,能够产生+10V 和-10V 电压 V+、V-3.功耗低,典型供电电流 5mA 4.部集成两个 RS-232C 驱动器,两个 RS-232C 接收器 三、工作原理说明及计算 1、PC 机与单片机通信 在工业控制系统中,各种数据的采集和执行机构的控制都是由下位机来完成。由于单片机具有体积小、价格低廉、可应用于恶
3、劣工业环境的特点,在分布式控制系统多采用单片机作为下位机来进行数据采集和现场控制。在这些应用中,单片机只是直接面向被控对象底层。而对采集到的数据进行进一步分析和处理的工作是由功能强大的主控 PC 机来完成的。因此,PC 机和单片机之间就有着大量的数据交换。通常 PC 机和单片机之间的通信是通过串行总线 RS-232 实现的。因此采用一种以 MAX232 为核心的通信接口电路。该接口电路适用于由一台 PC 机与多个单片机串行通信的设计,其原理和方法同样适用于 PC 机与其它单片机之间的串行数据通信。该框图中,起着重要作用的是 RS-232C 通信接口电路。它是上位机和下位机之间信息传递的枢纽,一
4、切数据的传输必需由它完成,上位机利用它的 RS-232 串行口,为此,采用了 RS-232 串行通信来接收或上传数据和指令。但 RS-232 信号的电平和单片机串口信号的电平不一致,必须进行二者之间的电平转换。在此电路中,采用MAX232 实现 TTL 逻辑电平和 RS-232 电平之间的相互转换。MAX232 由单一的+5V 电源供电,只需配接 5 个高精度 10F/50V 的钽电容即可完成电平转换。转换后的串行信号 TXD、RXD 直接与 PC 机的串行口连接。如此设计,既可发挥出 PC 强大的计算和显示功能,又可以体现出单片机灵活的控制功能,有利于对现场信号的实时采集、处理和监控。串口通
5、讯软件 RS-232C 2、舵机的结构 舵机简单的说就是集成了直流电机、电机控制器和减速器等,并封装在一个便于安装的外壳里的伺服单元。能够利用简单的输入信号比较精确的转动给定角度的电机系统。舵机安装了一个电位器(或其它角度传感器)检测输出轴转动角度,控制板根据电位器的信息能比较精确的控制和保持输出轴的角度。这样的直流电机控制方式叫闭环控制,所以舵机更准确的说是伺服马达,英文servo。舵机的主体结构有五个部分:外壳、减速齿轮组、电机、电位器、控制电路。工作原理:控制电路接受来自信号线的控制信号,控制电机转动,电机带动一系列齿轮组,减速后传动至输出舵盘。舵机的输出轴和位置反馈电位计是相连的,舵盘
6、转动的同时,带动位置反馈电位计,电位计将输出一个电压信号到控制电路板,进行反馈,然后控制电路板,根据所在位置决定电机的转动方向和速度,从而达到目标停止。舵机的输入线共有三条,红色中间,是电源线,一边黑色的是地线,这辆根线给舵机提供最基本的能源保证,主要是电机的转动消耗。电源有两种规格,一是 4.8V,一是 6.0V,分别对应不同的转矩标准,即输出力矩不同,6.0V 对应的要大一些;另外一根线是控制信号线,一般为桔黄色。舵机的控制信号为周期是 20ms 的脉宽调制(PWM)信号,其中脉冲宽度从 0.5ms-2.5ms,相对应舵盘的位置为 0180 度,呈线性变化。也就是说,给它提供一定的脉宽,它
7、的输出轴就会保持在一个相对应的角度上,无论外界转矩怎样改变,直到给它提供一个另外宽度的脉冲信号,它才会改变输出角度到新的对应的位置上。舵机部有一个基准电路,产生周期20ms,宽度 1.5ms 的基准信号,有一个比较器,将外加信号与基准信号相比较,判断出方向和大小,从而产生电机的转动信号。由此可见,舵机是一种位置伺服的驱动器,转动围不能超过 180 度,适用于那些需要角度不断变化并可以保持的驱动当中。舵机的外壳一般是塑料的,特殊的舵机可能会有金属铝合金外壳。金属外壳能够提供更好的散热,可以让舵机的电机运行在更高功率下,以提供更高的扭矩输出。金属外壳也可以提供更牢固的固定位置。FUTABA-S30
8、03 型舵机的部电路 标准舵机示意图 舵机输出转角与输入信号脉冲宽度的关系 正是因为舵机有很多优点,所以应用已经扩展到各种机电产品中来,在机器人控制中应用也越来越广泛。3、用单片机来控制舵机 舵机的控制信号是一个脉宽调制信号,所以很方便和数字系统进行接口。只要能产生标准的控制信号的数字设备都可以用来控制舵机。我们使用单片机产生舵机的控制信号来进行控制的方法,编程语言为C51。单片机有两个(或两个以上)部计数器,我们就用它来产生周期20 ms 的脉冲信号,根据需要,改变输出脉宽。脉冲信号的输出是靠定时器的溢出中断函数来处理,时间很短,因此在精度要求不高的场合可以忽略。因此如果忽略中断时间,从另一
9、个角度来讲就是主程序和脉冲输出是并行的,因此,只需要在主程序中按要求改变A值,例如让A从500 变化到2500,就可以让舵机从0 度变化到180 度。另外舵机的转动需要时间的,因此,程序中A值的变化不能太快,不然舵机跟不上程序。根据需要,选择合适的延时,用一个递增循环,可以让舵机很流畅的转动,而不会产生像步进电机一样的脉动。这些还需要实践中具体体会。舵机的速度决定于你给它的信号脉宽的变化速度。一般来讲,舵机最大转动速度在4.8V 时为0.23s/60 度,也就是说,如果你要求的速度比这个快的话,舵机就反应不过来了;如果要求速度比这个慢,可以将脉宽变化值线性到你要求的时间,做一个循环,逐渐的增加
10、脉宽值,就可以控制舵机的速度了。当然,具体这个量到底是多少,就需要做试验了,不然的话,不合适的话,舵机就会向步进电机一样一跳一跳的转动了。还有一点很重要,就是舵机在每一次脉宽值改变的时候总会有一个转速由零增加再减速为零的过程,这就是舵机会产生像步进电机一样运动的原因。如果系统中需要控制几个舵机的准确转动,可以用单片机和计数器进行脉冲计数产生P W M 信号。脉冲计数可以利用51 单片机的部计数器来实现,由于时间及专业限制,我们暂时使用这种方法。当系统的主要工作任务就是控制多个舵机的工作,并且使用的舵机工作周期均为20ms 时。要求硬件产生的多路P W M 波的周期也相同。使用51 单片机的部定
11、时器产生脉冲计数。一般工作正脉冲宽度小于周期的1/8。这样可以在1个周期分时启动各路P W M 波的上升沿。再利用定时器中断T0 确定各路PWM 波的输出宽度。定时器中断T1 控制20ms 的基准时间。第1 次定时器中断T0 按20ms 的1/8(由于数比较好算,所以用1/8)设置初值,并设置输出I/O 口,第1 次T0 定时中断响应后,将当前输出I/O 口对应的引脚输出置高电平,设置该路输出正脉冲宽度,并启动第2 次定时器中断,输出I/O口指向下一个输出口。第2 次定时器定时时间结束后,将当前输出引脚置低电平,设置此中断周期为20ms 的1/8 减去正脉冲的时间,此路P W M 信号在该周期
12、中输出完毕,往复输出。在每次循环的第16次(2*8=16)中断实行关定时中断T0的操作,最后就可以实现8路(实际上六路就可以完成机械臂的控制)舵机控制信号的输出。但是从软件系统的稳定性和程序结构的合理性看,宜使用外部的计数器,还可以提高CPU 的工作效率。采用单片机和8253、8254 这样的计数器芯片的PWM 信号产生电路是可靠的。基于8253 产生PWM 信号的程序主要包括三方面容:一是定义8253寄存器的地址,二是控制字的写入,三是数据的写入软件。所以当系统需要产生多路P W M 信号时,使用上述方法可以减少电路降低成本,也可以达到较高的精度。调试时注意到由于程序中脉冲宽度的调整是靠调整
13、定时器的初值,中断程序也被分成了8个状态周期,并且需要严格的周期循环,而且运行其他中断程序代码的时间需要严格把握。在实际应用中,采用51单片机简单方便地实现了舵机控制需要的P W M 信号,对机器人舵机控制的测试表明舵机控制系统工作稳定,P W M 占空比(0.52.5ms 的正脉冲宽度)和舵机的转角(-90 90)线性度较好。4、上位机 上位机是指人可以直接发出控制命令的计算机,一般是PC。下位机是直接控制设备获取设备状况的计算机,一般是PLC/单片机之类的。上位机发出的命令首先给下位机,下位机再根据此命令解释成相应时序信号直接控制相应设备。下位机不时读取设备状态数据(一般为模拟量),转换成
14、数字信号反馈给上位机。为了在短时间完成上位机编程,我们使用C#来制作串口通讯上位机。C#(C Sharp)是微软为.NET Framework量身订做的程序语言,C#拥有C/C+的强大功能以及Visual Basic简易使用的特性,是第一个组件导向的程序语言,和C+与Java一样亦为对象导向程序语言。四、调试中遇到问题及解决方法 在进行串口调试过程中,我们发现电脑经常出现找不到串口的情况,无论重新安装驱动,还是重新启动,都只是维持很短暂的时间,然后又出现上述情况。经检查应该是硬件的问题,我们估计是单片机学习板的串口连接脱焊导致的。我们还发现学习板的 P0 及 P5 口被其他的原件占用,无法直接
15、从这两个口输出PWM 信号,所以控制机械臂的接口只能跳过这两个,选用其他的。在调试控制舵机时,因为最开始用的舵机已经坏了,所以无论怎么调试,舵机都无法转动。拿到新的舵机后,我们最先用信号发生器产生脉冲信号,测试舵机转动角度的围,发现并不是 0-180,而是 150 度。虽然角度小了些,但还是能正常转动的。作为初期的练习控制舵机,基本满足要求,所以就没再换新的。由于机械臂的配合及机械物件连接不连贯,经常出现卡壳的状况,我们经过拧紧螺丝后,有所改善,但还是不够理想,希望以后可以买到更好的硬件。在调试的过程中,发现舵机的扭矩不是很大,可能是因为舵机过多,电流太小,无法达到额定扭矩,所以电路最好是制作
16、一个驱动电路,以提高机械臂性能。在进行程序调试时经常会出现问题,这与我们对程序的学习不够,有着直接的关系。在经过我们组成员一个学期的努力下,终于把程序完成,并不断改进。五、个人体会及心得 本学期我们组在进行项目研究方面花费了很长时间,同时也遇到了很多困难,也学到了很多。由于专业的差异,我们研究的围注定只局限于项目之,即使这样我们的进度也是不尽如人意。主要原因还是在编程方面,虽然我们组成员都过了二级,但是还缺乏实际的动手编程经验,还需要加强这方面的能力。和以前做作业不同,本学期的项目需要每个队员的合作。有明确的分工,才会有效率,不能只等着别人。希望在下学期的努力学习下,能够将我们组的项目成功的完
17、成,学习到一些感兴趣的知识,不给自己留下遗憾。单片机控制8路舵机程序:;T1 serial port to high T2 pwm PWMOUT0 BIT P0.0 PWMOUT1 BIT P0.1 PWMOUT2 BIT P0.2 PWMOUT3 BIT P0.3 PWMOUT4 BIT P0.4 PWMOUT5 BIT P0.5 PWMOUT6 BIT P0.6 PWMOUT7 BIT P0.7 T2CON DATA 0C8H TF2 BIT T2CON.7 EXF2 BIT T2CON.6 RCLK BIT T2CON.5 TCLK BIT T2CON.4 EXEN2 BIT T2CON
18、.3 TR2 BIT T2CON.2 C_T2 BIT T2CON.1 CP_RL2 BIT T2CON.0 T2 BIT P1.0 T2EX BIT P1.1 RCAP2L DATA 0CAH RCAP2H DATA 0CBH TL2 DATA 0CCH TH2 DATA 0CDH ET2 BIT IE.5 PT2 BIT IP.5/PWMWID EQU 048H;16048H05FH ;First low 8bits then high 8bits channel EQU 032H;pha EQU 033H;/ORG 0000H LJMP MAIN ORG 000BH LJMP T0_IS
19、R ORG 002BH LJMP T2_ISR ORG 0100H MAIN:MOV SP,60H MOV 96H,#00H MOV 8EH,#00H;Init SETB EA ;enable interrupt SETB ET2 CLR TCLK CLR RCLK MOV SCON,#050H ;8bit serial MOV TL2,#000H MOV TH2,#000H MOV RCAP2L,#03CH ;2.5ms MOV RCAP2H,#0F6H CLR TF2 SETB TR2 CLR ES ;disable serial interrupt CLR TI ;clear seria
20、l FLAG MOV TMOD,#21H MOV TH0,#000H ;make time for T0_ISR to run CLR TF0 SETB ET0 CLR TR0 MOV TL1,#0F3H MOV TH1,#0F3H SETB TR1 CLR A MOV pha,A MOV A,#035H MOV PWMWID+00H,A MOV PWMWID+02H,A MOV PWMWID+04H,A MOV PWMWID+06H,A MOV PWMWID+08H,A MOV PWMWID+0AH,A MOV PWMWID+0CH,A MOV PWMWID+0EH,A MOV A,#0FA
21、H MOV PWMWID+01H,A MOV PWMWID+03H,A MOV PWMWID+05H,A MOV PWMWID+07H,A MOV PWMWID+09H,A MOV PWMWID+0BH,A MOV PWMWID+0DH,A MOV PWMWID+0FH,A;Communication COMMU:JNB RI,COMMU CLR RI MOV channel,SBUF MOV SBUF,channel MOV A,channel JNB ACC.7,COMMU JB ACC.6,COMMU JNB RI,$ANL channel,#07FH MOV A,#PWMWID ADD
22、 A,channel ADD A,channel MOV R0,A MOV R1,SBUF CLR C MOV A,#0FFH SUBB A,R1 ;ADDC A,#12H MOV SBUF,A MOV R0,A CLR RI JNB RI,$MOV R1,SBUF MOV A,#0FFH SUBB A,R1 INC R0 MOV SBUF,A MOV R0,A CLR RI SJMP COMMU T0_ISR:PUSH ACC CLR TR0 MOV A,pha RL A MOV DPTR,#TABLE JMP A+DPTR TABLE:SJMP S0 SJMP S1 SJMP S2 SJM
23、P S3 SJMP S4 SJMP S5 SJMP S6 SJMP S7 S0:CLR PWMOUT0 POP ACC RETI S1:CLR PWMOUT1 POP ACC RETI S2:CLR PWMOUT2 POP ACC RETI S3:CLR PWMOUT3 POP ACC RETI S4:CLR PWMOUT4 POP ACC RETI S5:CLR PWMOUT5 POP ACC RETI S6:CLR PWMOUT6 POP ACC RETI S7:CLR PWMOUT7 POP ACC RETI T2_ISR:CLR TF2 PUSH ACC INC pha ANL pha
24、,#07H MOV A,pha RL A MOV DPTR,#TABLE2 JMP A+DPTR TABLE2:SJMP SS0 SJMP SS1 SJMP SS2 SJMP SS3 SJMP SS4 SJMP SS5 SJMP SS6 SJMP SS7 SS0:MOV TH0,PWMWID+01H MOV TL0,PWMWID+00H SETB PWMOUT0 SETB TR0 POP ACC RETI SS1:MOV TH0,PWMWID+03H MOV TL0,PWMWID+02H SETB PWMOUT1 SETB TR0 POP ACC RETI SS2:MOV TH0,PWMWID
25、+05H MOV TL0,PWMWID+04H SETB PWMOUT2 SETB TR0 POP ACC RETI SS3:MOV TH0,PWMWID+07H MOV TL0,PWMWID+06H SETB PWMOUT3 SETB TR0 POP ACC RETI SS4:MOV TH0,PWMWID+09H MOV TL0,PWMWID+08H SETB PWMOUT4 SETB TR0 POP ACC RETI SS5:MOV TH0,PWMWID+0BH MOV TL0,PWMWID+0AH SETB PWMOUT5 SETB TR0 POP ACC RETI SS6:MOV TH
26、0,PWMWID+0DH MOV TL0,PWMWID+0CH SETB PWMOUT6 SETB TR0 POP ACC RETI SS7:MOV TH0,PWMWID+0FH MOV TL0,PWMWID+0EH SETB PWMOUT7 SETB TR0 POP ACC RETI END 上位机程序(C#):using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing;using System.Text;using System.Windows.Forms;na
27、mespace Cois public partial class Cois:Form private byte P=new byte4;private byte checker;public Cois()InitializeComponent();private void Form1_Load(object sender,EventArgs e)init();private void Message()throw new NotImplementedException();private void init()GetPortName();this.CBx_baud.Text=global:C
28、ois.Properties.Settings.Default.BaudRate;private void GetPortName()string portNames=System.IO.Ports.SerialPort.GetPortNames();CBx_port.Items.Clear();foreach(string name in portNames)CBx_port.Items.Add(name);if(!CBx_port.Items.Contains(CBx_port.Text)try this.CBx_port.Text=(string)CBx_port.Items0;catc
29、h this.CBx_port.Text=global:Cois.Properties.Settings.Default.PortName;private void CBx_port_SelectedIndexChanged(object sender,EventArgs e)serialPort.PortName=CBx_port.Text;private void CBx_baud_SelectedIndexChanged(object sender,EventArgs e)serialPort.BaudRate=Convert.ToInt32(CBx_baud.Text);private
30、 void write(int number)byte CMD=new byte3;CMD0=(byte)number;CMD0|=(byte)0 x80;switch(number)case 0:CMD1=(byte)(Servo0.Value+17)%256);CMD2=(byte)(Servo0.Value+17)/256);serialPort.Write(CMD,0,3);break;case 1:CMD1=(byte)(Servo1.Value+17)%256);CMD2=(byte)(Servo1.Value+17)/256);serialPort.Write(CMD,0,3);
31、break;case 2:CMD1=(byte)(Servo2.Value+17)%256);CMD2=(byte)(Servo2.Value+17)/256);serialPort.Write(CMD,0,3);break;case 3:CMD1=(byte)(Servo3.Value+17)%256);CMD2=(byte)(Servo3.Value+17)/256);serialPort.Write(CMD,0,3);break;case 4:CMD1=(byte)(Servo4.Value+17)%256);CMD2=(byte)(Servo4.Value+17)/256);seria
32、lPort.Write(CMD,0,3);break;case 5:CMD1=(byte)(Servo5.Value+17)%256);CMD2=(byte)(Servo5.Value+17)/256);serialPort.Write(CMD,0,3);break;case 6:CMD1=(byte)(Servo6.Value+17)%256);CMD2=(byte)(Servo6.Value+17)/256);serialPort.Write(CMD,0,3);break;case 7:CMD1=(byte)(Servo7.Value+17)%256);CMD2=(byte)(Servo7
33、.Value+17)/256);serialPort.Write(CMD,0,3);break;private void Btn_connect_Click(object sender,EventArgs e)if(serialPort.IsOpen)Btn_connect.Text=Unconnected;Btn_connect.CheckState=System.Windows.Forms.CheckState.Unchecked;serialPort.Close();else try serialPort.Open();catch Btn_connect.CheckState=Syste
34、m.Windows.Forms.CheckState.Unchecked;if(serialPort.IsOpen)Btn_connect.Text=Connected;Btn_connect.CheckState=System.Windows.Forms.CheckState.Checked;write(0);write(1);write(2);write(3);write(4);write(5);write(6);write(7);private void CBx_port_DropDown(object sender,EventArgs e)GetPortName();private v
35、oid Servo0_MouseUp(object sender,MouseEventArgs e)/if(serialPort.IsOpen)write(0);private void Servo1_MouseUp(object sender,MouseEventArgs e)/if(serialPort.IsOpen)write(1);private void Servo2_MouseUp(object sender,MouseEventArgs e)/if(serialPort.IsOpen)write(2);private void Servo3_MouseUp(object send
36、er,MouseEventArgs e)/if(serialPort.IsOpen)write(3);private void Servo4_MouseUp(object sender,MouseEventArgs e)/if(serialPort.IsOpen)write(4);private void Servo5_MouseUp(object sender,MouseEventArgs e)/if(serialPort.IsOpen)write(5);private void Servo6_MouseUp(object sender,MouseEventArgs e)/if(serial
37、Port.IsOpen)write(6);private void Servo7_MouseUp(object sender,MouseEventArgs e)/if(serialPort.IsOpen)write(7);private void Servo0_Scroll(object sender,EventArgs e)textBox1.Text=Servo0.Value.ToString();if(serialPort.IsOpen)write(0);private void Servo1_Scroll(object sender,EventArgs e)if(serialPort.I
38、sOpen)write(1);private void Servo2_Scroll(object sender,EventArgs e)if(serialPort.IsOpen)write(2);private void Servo3_Scroll(object sender,EventArgs e)if(serialPort.IsOpen)write(3);private void Servo4_Scroll(object sender,EventArgs e)if(serialPort.IsOpen)write(4);private void Servo5_Scroll(object sender,EventArgs e)if(serialPort.IsOpen)write(5);private void Servo6_Scroll(object sender,EventArgs e)if(serialPort.IsOpen)write(6);private void Servo7_Scroll(object sender,EventArgs e)if(serialPort.IsOpen)write(7);