任务2 机器人伺服电机控制信号
图2-4所示是高电平持续1.5ms,低电平持续20ms,然后不断重复地控制脉冲序列。该脉冲序列发给经过零点标定后的伺服电机,伺服电机不会旋转。如果此时电机旋转,表明电机需要标定。从图2-4、图2-5和图2-6可知,控制电机运转速度的是高电平持续的时间,当高电平持续时间为1.3ms时,电机顺时针全速旋转,当高电平持续时间1.7ms时,电机逆时针全速旋转。下面你将看到如何给单片机微控制器编程使P1端口的第一脚(P1_0)发出伺服电机的控制信号。
图2-4 电机转速为零的控制信号时序图
图2-5 1.3ms的控制脉冲序列使电机顺时针全速旋转
图2-6 1.7ms的连续脉冲序列使电机逆时针全速旋转
在进行下面的实验之前,必须首先确认一下机器人两个伺服电机的控制线是否已经正确地连接到C51单片机教学板的两个专用电机控制接口上。按照图2-7所示的电机连接原理图和实际接线图进行检查。如果没有正确连接,请参照该图重新连接。从图2-7可知,P1_0引脚的控制输出用来控制右边的伺服电机,而P1_1则用来控制左边的伺服电机。
图2-7 伺服电机与教学底板的连线原理图(左)和实际接线示意图(右)
微控制器编程发给伺服电机的高、低电平信号必须具备更精确的时间。因为单片机只有整数,没有小数,所以要生成伺服电机的控制信号,要求具有比delay_nms( )时间更精确的函数,这就需要用到另一个延时函数delay_nus(unsigned int n)。前面已经介绍过,这个函数可以实现更少的延时,它的延时单位是μs,即千分之一毫秒,参数n为延时微秒数。
看看下面的代码片段:
while(1) { P1_0=1; //P1_0输出高电平 delay_nus(1500); //延时1.5ms P1_0=0; //P1_0输出低电平 delay_nus(20000); //延时20ms }
如果用这个代码段代替例程HighLowLed.c中相应的程序片段,它是不是就会输出如图2-4所示的脉冲信号?肯定是!如果你手边有示波器,可以用示波器观察P1_0脚输出的波形是不是如图2-4所示。此时,连接到该脚的机器人轮子是不是静止不动的?如果它在慢慢转动,就说明你的机器人伺服电机可能没有经过调整。
同样,用下面的程序片段代替例程HighLowLed.c中相应的程序片段,编译、连接下载执行代码,观察连接到P1_0脚的机器人轮子是不是顺时针全速旋转。
while(1) { P1_0=1; //P1_0输出高电平 delay_nus(1300); //延时1.3ms P1_0=0; //P1_0输出低电平 delay_nus(20000); //延时20ms }
用下面的程序片段代替例程HighLowLed.c中相应的程序片段,编译、连接下载执行代码,观察连接到P1_0脚的机器人轮子是不是逆时针全速旋转。
while(1) { P1_0=1; //P1_0输出高电平 delay_nus(1700); //延时1.7ms P1_0=0; //P1_0输出低电平 delay_nus(20000); //延时20ms }
该你了——让机器人的两个轮子全速旋转
刚才是让连接到P1_0脚的伺服电机轮子全速旋转,下面你自己可以修改程序让连接到P1_1脚的机器人轮子全速旋转。
当然,最后需要修改程序,让机器人的两个轮子都能够旋转。让机器人两个轮子都顺时针全速旋转参考下面的程序。
例程:BothServoClockwise.c
● 接通板上的电源;
● 输入、保存、下载并运行程序BothServoClockwsie.c(整个过程请参考第1讲);
● 观察机器人的运动行为。
#include<BoeBot.h> #include<uart.h> int main(void) { uart_Init(); //初始化串口 printf("The LEDs connected to P1_0 and P1_1 are blinking!\n"); while(1) { P1_0=1; //P1_0输出高电平 P1_1=1; //P1_1输出高电平 delay_nus(1300); //延时500ms P1_0=0; //P1_0输出低电平 P1_1=0; //P1_1输出低电平 delay_nms(20); //延时20ms } }
注意:上述程序用到了两个不同的延时函数,效果与前面例子一样。运行上述程序时,你是不是对机器人的运动行为感到惊讶?