微型伺服马达在航模活动中使用已有很长一段历史,而且应用最为广泛,国内亦称之为“舵机”。舵机主要用作运动方向的控制部件。舵机的控制信号为周期是20ms的脉宽调制(PWM)信号,其中脉冲宽度从0.5ms-2.5ms,相对应舵盘的位置为0-180度,呈线性变化。也就是说,给它提供一定的脉宽,它的输出轴就会保持在一个相对应的角度上,直到给它提供一个另外宽度的脉冲信号,它才会改变输出角度到新的对应的位置上。舵机内部有一个基准电路,产生周期20ms,宽度1.5ms的基准信号,有一个比较器,将外加信号与基准信号相比较,判断出方向和大小,从而产生电机的转动信号。由此可见,舵机是一种位置伺服的驱动器,转动范围不能超过180度,适用于那些需要角度不断变化并可以保持的驱动当中。比方说机器人的关节、飞机的舵面等。
根据舵机的控制原理,用Mega8做了18路舵机控制实验,控制时间步长为50us。通过串口向控制向控制器发送数据,同时控制18路舵机。
BASCOM源程序:
'-------------------------------------------------------------------------------
'Name : servo.bas
'Copyright : http://www.avrbase.com
'Micro : AtMega8
'Author : slyt/箫天
'-------------------------------------------------------------------------------
$regfile = "M8def.dat"
$crystal = 8000000
$baud = 19200
$hwstack = 32
$swstack = 10
$framesize = 40
Ddrb = &HFF
Ddrc = &HFF
Ddrd = &HFF
Dim Controltime(18) As Byte
Dim Controlcounter(18) As Byte
Dim Count20ms As Word
Dim I As Byte , K As Byte
Dim Bitstring As String * 1
For I = 1 To 18
Controltime(i) = 30
Next
Set Portb.6
Enable Interrupts
On Urxc Rec_isr
Enable Urxc
'18路控制线对应引脚
' 1- 6==>D2-PD7
' 7-12==>B0-PB5
'13-18==>C0-PC5
Ch1 Alias Portd.2
Ch2 Alias Portd.3
Ch3 Alias Portd.4
Ch4 Alias Portd.5
Ch5 Alias Portd.6
Ch6 Alias Portd.7
Ch7 Alias Portb.0
Ch8 Alias Portb.1
Ch9 Alias Portb.2
Ch10 Alias Portb.3
Ch11 Alias Portb.4
Ch12 Alias Portb.5
Ch13 Alias Portc.0
Ch14 Alias Portc.1
Ch15 Alias Portc.2
Ch16 Alias Portc.3
Ch17 Alias Portc.4
Ch18 Alias Portc.5
'============!!!===========
Do
lds R30,{Controlcounter}
lds R31,{Controltime}
cp R30,R31
brlo s1
Ch1 = 0
rjmp ss1
S1:
Ch1 = 1
Ss1:
lds R30,{Controlcounter+1}
lds R31,{Controltime+1}
cp R30,R31
brlo s2
Ch2 = 0
rjmp ss2
S2:
Ch2 = 1
Ss2:
lds R30,{Controlcounter+2}
lds R31,{Controltime+2}
cp R30,R31
brlo s3
Ch3 = 0
rjmp ss3
S3:
Ch3 = 1
Ss3:
lds R30,{Controlcounter+3}
lds R31,{Controltime+3}
cp R30,R31
brlo s4
Ch4 = 0
rjmp ss4
S4:
Ch4 = 1
Ss4:
lds R30,{Controlcounter+4}
lds R31,{Controltime+4}
cp R30,R31
brlo s5
Ch5 = 0
rjmp ss5
S5:
Ch5 = 1
Ss5:
lds R30,{Controlcounter+5}
lds R31,{Controltime+5}
cp R30,R31
brlo s6
Ch6 = 0
rjmp ss6
S6:
Ch6 = 1
Ss6:
lds R30,{Controlcounter+6}
lds R31,{Controltime+6}
cp R30,R31
brlo s7
Ch7 = 0
rjmp ss7
S7:
Ch7 = 1
Ss7:
lds R30,{Controlcounter+7}
lds R31,{Controltime+7}
cp R30,R31
brlo s8
Ch8 = 0
rjmp ss8
S8:
Ch8 = 1
Ss8:
lds R30,{Controlcounter+8}
lds R31,{Controltime+8}
cp R30,R31
brlo s9
Ch9 = 0
rjmp ss9
S9:
Ch9 = 1
Ss9:
lds R30,{Controlcounter+9}
lds R31,{Controltime+9}
cp R30,R31
brlo s10
Ch10 = 0
rjmp ss10
S10:
Ch10 = 1
Ss10:
lds R30,{Controlcounter+10}
lds R31,{Controltime+10}
cp R30,R31
brlo s11
Ch11 = 0
rjmp ss11
S11:
Ch11 = 1
Ss11:
lds R30,{Controlcounter+11}
lds R31,{Controltime+11}
cp R30,R31
brlo s12
Ch12 = 0
rjmp ss12
S12:
Ch12 = 1
Ss12:
lds R30,{Controlcounter+12}
lds R31,{Controltime+12}
cp R30,R31
brlo s13
Ch13 = 0
rjmp ss13
S13:
Ch13 = 1
Ss13:
lds R30,{Controlcounter+13}
lds R31,{Controltime+13}
cp R30,R31
brlo s14
Ch14 = 0
rjmp ss14
S14:
Ch14 = 1
Ss14:
lds R30,{Controlcounter+14}
lds R31,{Controltime+14}
cp R30,R31
brlo s15
Ch15 = 0
rjmp ss15
S15:
Ch15 = 1
Ss15:
lds R30,{Controlcounter+15}
lds R31,{Controltime+15}
cp R30,R31
brlo s16
Ch16 = 0
rjmp ss16
S16:
Ch16 = 1
Ss16:
lds R30,{Controlcounter+16}
lds R31,{Controltime+16}
cp R30,R31
brlo s17
Ch17 = 0
rjmp ss17
S17:
Ch17 = 1
Ss17:
lds R30,{Controlcounter+17}
lds R31,{Controltime+17}
cp R30,R31
brlo s18
Ch18 = 0
rjmp ss18
S18:
Ch18 = 1
Ss18:
Incr Controlcounter(1)
Incr Controlcounter(2)
Incr Controlcounter(3)
Incr Controlcounter(4)
Incr Controlcounter(5)
Incr Controlcounter(6)
Incr Controlcounter(7)
Incr Controlcounter(8)
Incr Controlcounter(9)
Incr Controlcounter(10)
Incr Controlcounter(11)
Incr Controlcounter(12)
Incr Controlcounter(13)
Incr Controlcounter(14)
Incr Controlcounter(15)
Incr Controlcounter(16)
Incr Controlcounter(17)
Incr Controlcounter(18)
Incr Count20ms
If Count20ms > 400 Then
Controlcounter(1) = 0
Controlcounter(2) = 0
Controlcounter(3) = 0
Controlcounter(4) = 0
Controlcounter(5) = 0
Controlcounter(6) = 0
Controlcounter(7) = 0
Controlcounter(8) = 0
Controlcounter(9) = 0
Controlcounter(10) = 0
Controlcounter(11) = 0
Controlcounter(12) = 0
Controlcounter(13) = 0
Controlcounter(14) = 0
Controlcounter(15) = 0
Controlcounter(16) = 0
Controlcounter(17) = 0
Controlcounter(18) = 0
Toggle Portb.6
Count20ms = 0
End If
Waitus 9
Loop
'=========二进制方式接收=========
'数据格式,每组命令3个字节
'1-标识符"{",2-舵机序号(1-18),3-舵机位置(10-50,一般取20-40,对应±45度)
Rec_isr:
Bitstring = Inkey()
If Bitstring = "{" Then
I = Waitkey()
If I > 0 And I < 19 Then
K = Waitkey()
Controltime(i) = K
End If
End If
Return
|
PC端控制演示程序(需要VB运行库支持):
电路图:
|