[本系列文章还将陆续介绍其他的传感器模块,欢迎订阅我的博客]
本次所介绍的是伺服电机模块,主要参考《基于ARM Cortex-M3的STM32系列嵌入式微控制器应用实践》内的对机器人的伺服电机模块的控制。本书作者依照对机器人的伺服电机控制讲的从简入深,简明易懂。
作者先介绍了机器人可以前后左右的移动,这里所说的机器人其实就是一个小车。对于它的巡航动作中,必须先知道两个车轮如何转圈,例如小车向前走,那么从左边看,小车的轮子是逆时针旋转,也就是伺服电机就是逆时针旋转,从右边看,小车的轮子是顺时针旋转,伺服电机就是顺时针旋转喽。
再一个需要知道,单片机给引脚发送的高电平时间决定了伺服电机的速度与方向,当中可以加入for循环,而for循环的参数控制了发送给电机的脉冲数量,而每一个脉冲的时间是相同的,所以for循环也控制伺服电机的运行的时间,
下面给出的是小车向前走3s的程序,是的!没错,就是3s,时间很短,现在这一点就不用讲,先把程序看懂。
#include"stm32f0x_heads.h"
#include"HelloRobot.h"
int main()
{
intcounter;
BSP_Init();//开发板初始化
USART_Configuration();
for(counter=0;counter<130;counter++)//运行3s
{
GPIO_SetBits(GPIOD,GPIO_Pin_10);//左侧电机逆时针旋转
delay_nus(1700);
GPIO_ResetBits(GPIOD,GPIO_Pin_10);
GPIO_SetBits(GPIOD,GPIO_Pin_9);//右侧电机顺时针旋转
delay_nus(1300);
GPIO_ResetBits(GPIOD,GPIO_Pin_9);
delay_nus(20);
}
while(1);
}
通过程序就可以知道小车可以向前运行,整个for循环执行130次,大约需要3s,就可以知道小车向前运行3s。先不管运行多短,看懂程序才是王道。时间只是修改一个数字而已,但面临的问题是由于小车的运动惯性的问题,小车会在程序停止后,还会向前运动,会使小车不稳定。
还会有这样的疑问,为什么会设为1700与1300,首先要告诉的就是1700是电机逆时针运行的最大速度,而1300是顺时针运行的最大速度。所以可以知道要使电机停止,应该为多少呢?对,就是1500,这个数值能尽量使小车停止,即毫无疑问就可以使小车减速。
下面我们我们编写一下使小车向前,向后,左转,右转的程序:
#include"stm32f0x_heads.h"
#include"HelloRobot.h"
int main()
{
intcounter;
BSP_Init();//开发板初始化
USART_Configuration();
for(counter=0;counter<=65;counter++)//向前跑
{
GPIO_SetBits(GPIOD,GPIO_Pin_10);//左侧电机逆时针旋转
delay_nus(1700);
GPIO_ResetBits(GPIOD,GPIO_Pin_10);
GPIO_SetBits(GPIOD,GPIO_Pin_9);//右侧电机顺时针旋转
delay_nus(1300);
GPIO_ResetBits (GPIOD,GPIO_Pin_9);
delay_nus(20);
}
for(counter=0;counter<=26;counter++) //向左转跑
{
GPIO_SetBits(GPIOD,GPIO_Pin_10);//左侧电机顺时针旋转
delay_nus(1300);
GPIO_ResetBits (GPIOD,GPIO_Pin_10);
GPIO_SetBits(GPIOD,GPIO_Pin_9);//右侧电机顺时针旋转
delay_nus(1300);
GPIO_ResetBits (GPIOD,GPIO_Pin_9);
delay_nus(20);
}
for(counter=0;counter<=26;counter++) //向右转跑
{
GPIO_SetBits(GPIOD,GPIO_Pin_10);//左侧电机逆时针旋转
delay_nus(1700);
GPIO_ResetBits (GPIOD,GPIO_Pin_10);
GPIO_SetBits(GPIOD,GPIO_Pin_9);//右侧电机逆时针旋转
delay_nus(1700);
GPIO_ResetBits (GPIOD,GPIO_Pin_9);
delay_nus(20);
}
for(counter=0;counter<=65;counter++) //向后跑
{
GPIO_SetBits(GPIOD,GPIO_Pin_10);//左侧电机顺时针旋转
delay_nus(1300);
GPIO_ResetBits (GPIOD,GPIO_Pin_10);
GPIO_SetBits(GPIOD,GPIO_Pin_9);//右侧电机逆时针旋转
delay_nus(1700);
GPIO_ResetBits (GPIOD,GPIO_Pin_9);
delay_nus(20);
}
}
while(1);
}
下面我们使小车原地旋转,程序:
向右顺时针原地旋转:
GPIO_SetBits(GPIOD,GPIO_Pin_10);//左侧电机停止旋转
delay_nus(1500);
GPIO_ResetBits (GPIOD,GPIO_Pin_10);
GPIO_SetBits(GPIOD,GPIO_Pin_9);//右侧电机顺时针旋转
delay_nus(1300);
GPIO_ResetBits (GPIOD,GPIO_Pin_9);
delay_nus(20);
同理,我们就知道向左原地旋转:
GPIO_SetBits(GPIOD,GPIO_Pin_10);//左侧电机逆时针旋转
delay_nus(1700);
GPIO_ResetBits (GPIOD,GPIO_Pin_10);
GPIO_SetBits(GPIOD,GPIO_Pin_9);//右侧电机停止旋转
delay_nus(1500);
GPIO_ResetBits (GPIOD,GPIO_Pin_9);
delay_nus(20);
刚才就说了,如果小车一下子运行时间长的话,程序停止,会使小车倾倒,这就是涉及到加速,匀加速,匀减速的问题,我们可以设计一个变量,能够使小车慢慢加速。
匀加速程序如下:
for(pulseCount=10; pulseCount <=200; pulseCount= pulseCount +10)
{
GPIO_SetBits(GPIOD,GPIO_Pin_10);
delay_nus(1500+pulseCount);
GPIO_ResetBits(GPIOD,GPIO_Pin_10);
GPIO_SetBits(GPIOD,GPIO_Pin_9);//右侧电机顺时针旋转
delay_nus(1500-pulseCount);
GPIO_ResetBits(GPIOD,GPIO_Pin_9);
delay_nus(20);
}
没错,就是这么简单,循环一次变量pulseCount就会增加10,第一次循环时,pulseCount为10,发送给PD10,PD9的脉冲宽度分别为1.51ms,1.49ms,第二次循环时,pulseCount值为20,宽度为1.52,1.48,······循环20次,pulseCount为200,此时的宽度为1.7ms和1.3ms,此时的电机全速运转。注意是全速,分别以1700,1300旋转。
匀减速的程序,需要修改的地方主要是for循环:
for(pulseCount=200; pulseCount >=0; pulseCount= pulseCount -10)
具体程序,你应该能写出来了。
程序可以进行简化,具体可以参考上面我所说的书籍,如果找不到书的话,可以给我留言,我给你发过去。
[文章未经作者的允许,不得转载]