• 沒有找到結果。

单片机输入接口与机器人触觉导航

通过前面两章的学习,你已经掌握如何用单片机的输入/输出接口来控制机器人的各种 运动。当时,连接机器人伺服电机的单片机端口是作为输出使用,而且使用非常简单。

本章你将通过给你的机器人增加触觉传感器学习如何使用这些端口来获取外界信息。实 际上,对于任何一个自动化系统(不仅仅是机器人),无非都是通过传感器获取外界信息,

通过接口进入计算机(或者单片机),由计算机或单片机根据反馈信息进行计算和决策,生 成控制命令,然后通过输出接口去控制系统相应的执行机构,完成系统所要完成的任务。因 此,学习如何使用单片机的输入接口同学习使用输出接口同等重要。

许多自动化机械都依赖于各种触觉型开关,例如当机器人碰到障碍物时,接触开关就会 察觉,通过编程让机器人躲开障碍物;旅客登机桥在靠近飞机时为了保护昂贵的飞机,在登 机桥接口安装触须,当登机桥离飞机很近后触须就会碰到飞机,立即通知控制器提醒离飞机 已经很近了,需要降低靠近速度;工厂利用触觉开关来计量生产线上的工件数量;在工业加 工过程中,也被用来排列物体。在所有这些实例中,触觉开关提供的输入通过计算机或者单 片机处理后生成其它形式的程序化的输出。

本章中,你将在机器人前端安装并测试一个称为胡须的触觉开关。你将对机器人大脑编 程来监视触觉开关的状态,以及决定当它遇到障碍物时如何动作。最终的结果就是通过触觉 给机器人自动导航。如果你已经学习过《基础机器人制作与编程》,对本章的内容就不会太 陌生了。

触觉导航与单片机输入接口

在第二章一开始,你就已经知道了51系列单片机有4个8位的并行I/O口:P0、P1、P2和 P3。这4个接口,既可以作为输入,也可以作为输出,既可按8位处理,也可按位方式使用。

实际上,当单片机启动或复位时,所有的I/O插脚缺省为输入。也就是说,如果将胡须 连接到单片机某个I/O管脚时,该管脚会自动作为输入。作为输入,如果I/O脚上的电压为5V,

则其相对应的I/O口寄存器中的相应位存储1;如果电压为0V,则存储0。

布置恰当的电路,可以让胡须达到上述效果:当胡须没有被碰到时,使I/O脚上的电压 为5V;当胡须被碰到时,则使I/O脚上电压为0。然后,单片机就可以读入相应数据,进行分 析、处理,控制机器人的运动。

任务一 安装并测试机器人胡须

编程让机器人通过触觉胡须导航之前,首先必须安装并测试胡须。图4−1所示是安装机 器人触觉胡须所需的硬件元件清单,包括:

1. 金属丝2根

2. 平头M3×22盘头螺钉2个 3. 13mm圆形立柱2个 4. M3尼龙垫圈2个 5. 3-pin公-公接头2个 6. 220Ω电阻2个

7. 10kΩ电阻2个 图4-1 胡须硬件

安装胡须(如果你已经学习过《基础机器人制作》,可以跳过此步骤)

z 拆掉连接主板到前支架的两颗螺钉 z 参考图4-2,进行下面操作

z 螺钉依次穿过M3尼龙垫圈、13mm圆 形立柱

z 螺钉穿过主板上的圆孔之后,拧进 主板下面的支架中,但不要拧紧 z 把须状金属丝的其中一个钩在尼龙

垫圈之上,另一个钩在尼龙垫圈之 下,调整它们的位置使它们横向交 叉但又不接触

z 拧紧螺钉到支架上 图4-2 安装机器人胡须 z 参考接线图4-3,搭建胡须电路。

注意:右边胡须状态信息输入是通 过P1口的第4脚完成,而左边胡须 状态信息输入是通过P2口的第3脚 完成

z 确定两条胡须比较靠近,但又不接 触面包板上的3-pin头。推荐保持3 mm的距离。

z 图4-4所示是实际的参考接线图。

z 安装好触觉胡须的机器人如图4-5 所示。

4-3 胡须电路示意图

图4-4 教学底板上胡须接线图 图4-5 安装好触须的机器人 测试胡须

观察一下图4-3所示的胡须电路示意图,显然每条胡须都是一个机械式的、接地常开的 开关。胡须接地(GND)是因为教学板外围的镀金孔都连接到GND。金属支架和螺丝钉提供电 气连接给胡须。

通过编程让单片机探测什么时候胡须被触动。由图4-3可知,连接到每个胡须电路的I/O 引脚监视着10K上拉电阻上的电压变化。当胡须没有被触动,连接胡须的I/O管脚的电压是5V;

当胡须被触动时,I/O短接到地,所以I/O管脚的电压是0V。

int P1_4state(void)//获取 P1_4 的状态 {

return (P1&0x10)?1:0;

}

int P2_3state(void)//获取 P2_3 的状态 {

return (P2&0x08)?1:0;

}

int main(void) {

uart_Init();

printf("WHISKER STARTES\n");

while(1) {

printf("右边胡须的状态:%d ",P1_4state());

printf("左边胡须的状态:%d\n",P2_3state());

delay_nms(150);

} }  

上面的例程是用来测试胡须的功能是否正常。

首先,定义了两个无参数有返回值子函数int P1_4state(void)和int P2_3state(void) 来获取左右两个胡须的状态。要理解这两个函数,你又需要学习新的C语言知识。

|

异或

>> 右移

<< 左移

这里主要介绍与运算符“&”。

与运算符“&”的功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位 均为1时,结果位才为1,否则为0。如9和5的与运算:

0000 1001 (9的二进制)

&0000 0101 (5的二进制)

=0000 0001 (结果为1)

单片机AT89S52的四个端口P0、P1、P2和P3是可以按位来操作的,从低到高依次为第0 口、第1口……第7口,书写分别为PX.0、PX.1、……PX.7(X取0到3)。

下面来看看P4&0x10与P2&0x08分别是有什么含义。

P1 P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 0x20 0 0 0 1 0 0 0 0

P2 P2.7 P2.6 P2.5 P2.4 P2.3 P2.2 P2.1 P2.0 0x08 0 0 0 0 1 0 0 0

这样一来,P1&0x10和P2&0x08分别提取了P1.4和P2.3的值,屏蔽掉了其他位。

注意,上面提到的P0、P1、P2和P3四个端口,并不指的是物理上接口,而是这四个端口 对应的特殊功能寄存器P0、P1、P2和P3,在应用时直接使用这些符号就代表着这些特殊功能 寄存器。所谓特殊功能寄存器(SFR)也称专用寄存器,专门用来控制和管理单片机内的算 术逻辑部件,并行I/O接口等片内资源。你在使用时可以给其设定值,比如前面利用P1口控 制伺服电机,也可以直接利用这些寄存器进行运算。

该你了

取某一位的值,上面应用的是位运算,或运算也可以达到同样的效果,想想该怎么做呢?

另外,查找相关资料,思考其实几种运算符的用法。

if语句

第三章学习的switch语句是选择控制语句中的一种,还有一种语句是if语句,它根据给 定的条件进行判断,以决定执行某个分支程序段。if语句其中之一的形式为:

if(表达式) 语句1;

else 语句2;

其语义是:如果表达式的值为真,则执行语句1,否则执行语句2。

?操作符

C语言提供了一个可以代替某些“if-else”语句的简便易用的操作符“?”。该操作符 是三元的,其一般形式为:

表达式1 ?表达式2:表达式3

它的执行过程如下:先求解表达式1,如果为真(非0),则求解表达式2,并把表达式2 的结果作为整个条件表达式的值;如果表达式1的值为假(0),则求解表达式3,并把表达 式3的值作为整个条件表达式的值。

(P1&0x10)?1:0的意思就是先将P1寄存器的内容同0x10按位进行“与”运算,如果结果 非0,则整个表达式的取值就为1;如果结果为0,则整个表达式的值为0。实际上,整个语句

return (P1&0x10)?1:0;

就相当于如下条件判断语句:

if (P1&0x10) return 1;

else

return 0;

在搞清楚整个程序的执行原理后,按照下面的步骤实际执行程序,对触觉胡须进行测试。

z 接通教学板和伺服电机的电源

z 输入、保存并运行程序TestWhiskers.c

z 这个例程要用到调试终端,所以当程序运行时要确保串口电缆已连接好 z 检查图4-3,弄清楚哪条胡须是左胡须,哪条是右胡须

z 注意调试终端的显示值;此时显示为:“右边胡须的状态:1 左边胡须的状态:1”,

如图4-6

图4-6 左右胡须均未碰到

z 把右胡须按到3-pin转接头上,注意显示为:“右边胡须的状态:0 左边胡须的状 态:1”,如图4-7

图4-7 右胡须碰到

z 把左胡须按到3-pin转接头上,注意显示为:“右边胡须的状态:1 左边胡须的状 态:0”,如图4-8

图4-8 左胡须碰到

z 同时把两个胡须按到各自的3-pin转接头上,显示为:“右边胡须的状态:0 左边胡 须的状态:0”,如图4-9

图4-9 左右胡须均碰到

z 如果两个胡须都通过测试,你可以继续下面的内容;否则检查程序或电路中存在的 错误

任务二 通过胡须导航

任务一中,你已经通过编程检测胡须是否被触动。在本任务中将利用这些信息对机器人 进行运动导航。

在机器人行走过程中,如果有胡须被触动,那就意味着碰到了什么。导航程序需要接受 这些输入信息,判断它的意义,调用一系列使机器人倒退、旋转朝不同方向行走的动作子函 数以避开障碍物。

编程使机器人基于胡须的触觉导航

下面的程序让机器人向前走直到碰到障碍物。在这种情况下,机器人用它的一根或者两 根胡须探测障碍物。一旦胡须探测到障碍物,调用第三章中的导航程序和子程序使小车倒退 或者旋转,然后再重新向前行走,直到遇到另一个障碍物。

为了实现这些功能,需要编程机器人来做出选择,此时要用到if语句的另一种形式,

if-else-if形式,它可以进行多分支选择。它的一般形式为:

if(表达式1) 语句1;

else if(表达式2) 语句2;

else if(表达式3) 语句3;

……

else if(表达式n-1) 语句n-1;

else

语句n;

else if(P2_3state()==0) //左边胡须检测到障碍物时,后退,再向右转 90 度 {

Back_Up();

Right_Turn ();

}

!

关系运算实际上是比较运算:将两个值进行比较,判断其比较的结果是否符合给定的条 件。例如,a>4是一个关系表达式,大于号( 〉)是一个关系运算符。如果a的值为6,则满 足给定的a>4的条件,因此关系表达式的值为“真”;如果a的值为2,则不满足“a>4”的条 件,则称关系表达式的值为“假”。

“P1_4state()==0;”首先调用右触须状态检测函数P1_4state(),将其返回值与0进行 比较:如果返回值为0,则关系表达式为“真”,否则为“假”。

同样“P2_3state()==0;”首先调用左触须状态检测函数P2_3state(),将其返回值与0 进行比较:如果返回值为0,则关系表达式为“真”,否则为“假”。

A&&B 若A、B为真,则A&&B为真。

注意区分位操作符“&”和逻辑运算符“&&”。

在if((P1_4state()==0)&&(P2_3state()==0))中将两个比较关系表达式用括号括起来,

表示先进行比较运算,将两个运算结果再进行逻辑与运算。因此,该语句的工作原理是:只

z 输入、保存并运行程序RoamingWithWhiskers.c

z 输入、保存并运行程序RoamingWithWhiskers.c