项目名称:            基于手机安卓平台蓝牙通信的小车控制

 

 

 

 

 

龙文昌

 

 

蓝牙模块调试、手机程序编写和调试及报告撰写

魏洪超

 

 

手机程序编写和调试、单片机程序编写及调试

蒋文捷

 

 

蓝牙模块调试、手机程序编写和调试

 

 

 


 

摘要

 

本设计实现的是基于手机安卓平台通过蓝牙对小车进行控制。控制系统由车载控制设备和手机设备组成,车载控制设备以STC系列的STC11L02系列51单片机芯片和蓝牙芯片为核心,手机软件使用以Eclipse搭建的安卓应用程序。使用该软件通过蓝牙发送指令到单片机,再由单片机处理控制信号并对电机进行相应的控制,使小车完成指令动作。

 

关键词:

安卓手机,单片机,蓝牙,Eclipse


     

第一章 项目介绍........................................................................................................... 1

1.1开发背景................................................................................................................ 1

1.2项目任务................................................................................................................ 1

第二章 设计思路.......................................................................................................... 2

2.1遥控小车改装........................................................................................................ 2

2.2 控制思路............................................................................................................... 2

第三章 硬件电路实现................................................................................................... 4

3.1 小车的选择与改造............................................................................................... 4

3.2 小车遥控器的改造............................................................................................... 4

3.3控制信号的解调的单片机电路............................................................................ 4

3.4与单片机相连的蓝牙模块.................................................................................... 6

3.5我们在调试硬件电路时遇到的问题.................................................................... 7

第四章 软件部分........................................................................................................... 8

4.1 安卓手机软件部分............................................................................................... 8

4.1.1编译与调试环境............................................................................................ 8

4.1.2  安卓平台用户界面搭建............................................................................. 10

4.2 单片机平台部分................................................................................................. 14

4.2.1编译环境与功能实现.................................................................................. 14

4.2.2 程序烧录...................................................................................................... 14

4.3软件设计中我们遇到的问题及解决方法.......................................................... 15

第五章 结论与展望..................................................................................................... 16

第六章 项目总结与心得............................................................................................ 17

第七章 致谢.................................................................................................................. 18

第八章 参考资料......................................................................................................... 19

第九章 附录................................................................................................................ 20

 


第一章   项目介绍

1.1开发背景

随着时代的进步与科技的发展,控制理论、控制系统与控制设备都经历数次革命性的改变,从有线到无线,从机械控制到电控、从电控到光控,从一对一到一对多,从专业化配对到通用式配对,层出不穷,种类繁多。现在,手机作为一种基本的生活工具,成为人们生活中不可缺少的部分。手机平台也相应的成为了各生产厂家争相开发的目标,好的平台能够成全用户自主开发新功能,这里我们实现就是用手机平台来控制小车。

 

1.1   安卓机器人

在众多的手机平台中,安卓系统凭借其不断成熟的系统构架和强大的多元编译环境功能独树一帜。安卓是以Linux为核心的手机操作平台,作为一款开放式操作系统,随着安卓的快速发展,如今已允许开发者使用多种编程语言来开发安卓应用程序,而不再是以前只能使用Java开发安卓应用程序的单一局面,因而受到众多开发者的欢迎,成为真正意义上的开放式操作系统。 在安卓中,开发者可以使用Java作为编程语言来开发应用程序,也可以通过NDK使用C/C++作为编程语言来开发应用程序,也可使用SL4A来使用其他各种脚本语言进行编程(如:pythonluatclphp等等),还有其他诸如:QtMono等一些著名编程框架也开始支持安卓编程,甚至通过MonoDroid,开发者还可以使用C#作为编程语言来开发应用程序。另外,谷歌公司还在2009年特别发布了针对初学者的安卓 Simple语言,该语言类似Basic语言。而在网页编程语言方面,JavaScriptajaxHTML5jquerysenchadojomoblPhoneGap等等都已经支持安卓开发。因此,以手机安卓平台作为控制媒介的开发具有相当大的潜在价值与意义。

 

1.2项目任务

本次项目的任务为,改造一辆小车,用户能够对它进行控制,实现途径为通过手机、嵌入式开发板(9B96)、自制开发板、手机开发软件的模拟器等作为控制媒介,优先考虑无线模式。与此同时,可以附加其他功能,如:可以预先设定一条多边形封闭路径,让其自动循环行走;在用户界面上直接修改或输入运动路径,并使小车完成规定动作等。

第二章  设计思路

2.1遥控小车改装

出于我们老师的建议,我们是选择的改装市场上出售的遥控小车。老师给我们的小车的主要部件有一个完好无损的控制小车和改装的遥控器。如图2.1所示,是我们选择的小车在运动时的样子,比较遗憾的是,在我们制作的过程中,我们没有拍下相应的照片。从图中可以看出完整的小车和它的遥控器。途中是用绿线缆将遥控器绑在小车尾部的。

2. 1 遥控小车与遥控器

2.2 控制思路

遥控小车的控制思路是通过遥控器发射一定频率的控制信号,由小车上的接受器来接收信号,并处理信号,然后将信号里的控制信息转换为对马达的控制和对前轮方向的控制。而遥控器上的输入信号则是由人来控制的,一般为按钮输入,当按下某个键时,则会形成通路或断路,从而产生特定的信号发射出去,在这里我们不是人为按钮控制的,所以需要对遥控器进行改装,即将单片机输出分别对应接入遥控器的四个控制回路,通过单片机发出的信号来直接代替人的控制工能。如图2.2所示,为老师给我们的以改装过的遥控器。

2.2  改装的遥控器

根据以上提供的思路,我们是利用蓝牙模块来实现代替人为的控制功能的。那么要实现小车的动作,我们就需要对蓝牙实现控制。在此,我们选择以安卓手机平台为基础的蓝牙模块来实现和小车遥控器上的蓝牙模块来实现互相通信以传递控制信息,然后控制信息由与遥控器相连的单片机来分析从而得出输入给遥控器的控制信息,从而通过遥控器控制小车。控制信息由手机提供,这样,我们并能清楚的得到图2.3所示的控制信号流向图。

 

2.3 控制信号流向图

 

第三章硬件电路实现

3.1 小车的选择与改造

小车由老师直接配发,只要满足基本的要求即可,根据前面同学的经验,小车与遥控器绑定在一起,不仅能简化设备,还能促进控制的稳定与及时。随着小车的配置物品如下:

1:电池。包括小车的驱动电池和遥控器的供电电池两部分。考虑到小车耗电过快,我们选择的是四节串联的可充电电池,既减少预算,又能提供足够的工作电压;遥控器的电池选用9V的干电池即可。

2:电池充电器。与充电电池同步配套设备。如图3.1所示即为充电电池和其充电器。

3.1 充电电池和其充电器

3.2 小车遥控器的改造

其实对于小车的遥控器改造很简单,就是将原来的按钮取下来,换上对应的单片机的接口,四个接口均设定为低电平有效。即当接口处于高电平时,对应功能不动作;当处于低电平时,回路导通,小车动作。

3.3控制信号的解调的单片机电路

如图3.2所示,为单片机的硬件电路图。它也是我们所用到的电路板的原理图,因此对它的分析和理解对我们在设计过程中有很大的帮助。当需要对其进行调试时可以知道问题的所在。

                                                           3.2 单片机电路原理图 

所用单片机是ATMEL公司的STC系列的STC11L02系列51单片机芯片,主要性能参数如下:

兼容MCS-51指令系统;

内置通用8CPU8K Flash ROM

1000次可擦写周期;

0~24MHz全静态操作;

3级加密程序存储器;

256字节内部RAM

16个双向I/O口;

16位定时/计数器;

5个中断源;

全双工串行I/O口。

TTL通信线:采用计算机到小车单向串行通信,供烧录与下载程序用,如图3.3所示。

3.3 TTL数据线

3.4与单片机相连的蓝牙模块

单片机模块与蓝牙模块连接在同一PCB版上,使得单片机能够通过蓝牙获取外界指令(来自手机),连接电路图如图3.4所示:

 

3. 4  单片机与蓝牙模块电路板图(正面

 

3. 5单片机与蓝牙模块电路板图(反面)

3.5我们在调试硬件电路时遇到的问题

在用以上所说述的硬件设备和电路时,我们遇到了不少问题,经过队员们的努力和老师的帮助,最终克服了这些问题。当然,如果不会碰到,自是好事,但是碰到了,小事也会导致整个设计的的延迟甚至失败。下面我就我们遇到的问题和解决方法做个总计:

1:通信线的选择:开始我们根据以往资料的叙述,直接选择的RS232通信线,以期实现单片机的程序的烧录。然而,这与单片机的配置不符合,导致我们很长一段时间都不能烧入程序,经过老师知道,我们选择了TTL通信线,最终实现了程序的烧录。

2:单片机电路的问题。本来,我们是不应该出现对电路板的怀疑,但是由于电源电压的接入错误,很可能烧坏单片机,因此我们就有必要对单片机进行检测。在接入9V的电源电压后,我们将ON/OFF跳线帽取下,根据原理图,LED2是不会亮的。但是事实上LED2是亮的,用万用表测的LED2两端的电压差为2.11V,小于3.3V。后来对电路做了一些调试,如取下单片机及其他元件,均不能得到合理的解释,但是就是这样,程序依然烧录成功。当然这样的话就得改变操作步骤,提示上电后,再装上9V电池,当然ON/OFF跳线帽一直连着。

3:蓝牙模块的选择。老师给的物品中包含链接在单片机上的蓝牙模块,每个蓝牙模块的MAC地址不同。在开始我们不能将该蓝牙模块与手机蓝牙连接起来。后来,经过摸索,确定连通蓝牙的操作步骤如下:首先通过计算机的蓝牙搜索蓝牙模块,这是会发现搜索到我们的蓝牙模块,查看属性可以得到该蓝牙模块的MAC地址;然后将该MAC地址copy到软件程序中要连接的蓝牙MAC(具体位置请见软件部分的程序);最后开启手机蓝牙,搜索目标蓝牙,连接并输入配置密码,该密码为一般默认的,1234或者0000等,实验成功即可。

第四章软件部分

4.1 安卓手机软件部分

4.1.1编译与调试环境

由于安卓平台软件开发多以JAVA语言编程为主,我们采用的是Eclipse软件来编写程序,如图4.1所示。同时,为了能够直观地在电脑上检视界面效果,我们还采用了Oracle VM Virtual Box虚拟机下搭载的X86Android2.2系统作为试运行环境,如图4.2所示,通过调整虚拟机网络配置器以及IP地址和Eclipse本身的运行调试参数,可以将两个软件联系起来,在Eclipse上完成程序编写并在虚拟机的安卓平台上进行运行。但是要注意的是,在虚拟平台下的安卓界面不能开启蓝牙功能,因此在程序完成编译通过后最好是烧入手机并运行之,通过实际中操作来确定是否实现了预期功能。

对于软件开发环境的配置,只需按照步骤一步一步的做好即可,在此不作过多赘述,具体方法将在参考资料与附录中作出说明。

QQ截图20111002165256.jpg

4. 1  编译环境Eclipse

4.2 虚拟机操作界面

4.3 虚拟机运行成功界面

 

4.1.2  安卓平台用户界面搭建

1、  窗体架构程序

在基本的功能的基础上的窗体架构:控制小车动作一共需要五个按钮,前进、后退、左转、右转和停止。于是我们在Android工程下的main.xml窗体文件中按十字形安放了5个按钮,等高等宽,位置放置合适即可。图4.4为其实现效果图。

程序如下:

<?xml version="1.0" encoding="utf-8"?>

<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/widget0"

    android:layout_width="wrap_content"

    android:layout_height="match_parent" >

 

 

 

<Button

android:id="@+id/btnF"

android:layout_width="100px"

android:layout_height="60px"

android:text="前进"

android:layout_x="130px"

android:layout_y="62px"

> 

</Button>

<Button

android:id="@+id/btnL"

android:layout_width="100px"

android:layout_height="60px"

android:text="左转"

android:layout_x="20px"

android:layout_y="152px"

> 

</Button>

<Button

android:id="@+id/btnB"

android:layout_width="100px"

android:layout_height="60px"

android:text="后退"

android:layout_x="130px"

android:layout_y="242px"

> 

</Button>

<Button

android:id="@+id/btnS"

android:layout_width="100px"

android:layout_height="60px"

android:text="停止"

android:layout_x="130px"

android:layout_y="152px"

> 

</Button>

 

 

<Button

    android:id="@+id/btnR"

    android:layout_width="100px"

    android:layout_height="60px"

    android:layout_x="165dp"

    android:layout_y="104dp"

    android:text="右转" />

 

</AbsoluteLayout>

4.4窗体实现效果图

2、  功能实现程序

安卓平台的手机信息传输依靠的是蓝牙通信方式,因此,我们调用了蓝牙配置器类,并且设定将用于通信的变量存放于缓存区message中。五个按钮按下后发送到缓存区的字符分别为:‘1-前进,‘2-左转,‘3-后退,‘4-右转,‘0-停止,并且在屏幕上显示出来短暂的时间。

对于按钮动作,我们将简单的按动动作分为两个部分,其一为按下,其二为松开,具体配置为:当按下某一特定按钮时,向缓存区写入字符‘X’(X为上文事先规定的字符),当松开时,自动向缓存区写入‘0’(表示停止),然后通过蓝牙通信,将写入缓存区的指令信息传送到小车车载单片机上,实现了按下按钮小车动作,松开按钮小车停止的效果,避免了单次触发无停止的不良效果。

按照我们最初的设想,我们所添加的功能是自动检测命令错误。即设想同时按下两个按键,如左转和右转,此时,系统返回COMMOND ERROR,并且自动处于停止状态。由此,我们的思路是先设定一个flag值为0,当检测按键按下时先检测flag是否为0,是则置1,否则返回错误并停止。对于该停止函数,在执行了停止动作后,自动将flag0以实现下一次的可能的正确动作。

但是遗憾的是,当程序编写完成后才发现,安卓系统下并不能同时按下两个键,即是系统默认不会出现命令错误,这是我作为组长的失职,导致了方向的错误,致使工作失败。以下是以前进为例的源程序和命令错误时的停止功能函数:

// 后退

              mButtonB = (Button) findViewById(R.id.btnB);

              mButtonB.setOnTouchListener(new Button.OnTouchListener() {

 

                     public boolean onTouch(View v, MotionEvent event) {

                           // TODO Auto-generated method stub

                           String message;

                           byte[] msgBuffer;

                           int action = event.getAction();

                            switch (action) {

                           case MotionEvent.ACTION_DOWN:

                                  if(flag==1)

                                  {

                                  Toast.makeText(getApplicationContext(), "COMMOND ERROR!WILL STOP!",

                                         Toast.LENGTH_SHORT).show();

                                  stop();

                                  return false;

                                  }

                           else

                                  flag=1;

                                  try {

                                         outStream = btSocket.getOutputStream();

 

                                  } catch (IOException e) {

                                         Log.e(TAG, "ON RESUME: Output stream creation failed.",

                                                       e);

                                  }

 

                                  message = "3";

 

                                  msgBuffer = message.getBytes();

 

                                  try {

                                         outStream.write(msgBuffer);

 

                                  } catch (IOException e) {

                                         Log.e(TAG, "ON RESUME: Exception during write.", e);

                                  }

                                  break;

 

                           case MotionEvent.ACTION_UP:

                       flag=0;

                                 

                                  Toast.makeText(getApplicationContext(), "flag wei o le",

                                                Toast.LENGTH_SHORT).show();

                                  try {

                                         outStream = btSocket.getOutputStream();

 

                                  } catch (IOException e) {

                                         Log.e(TAG, "ON RESUME: Output stream creation failed.",

                                                       e);

                                  }

 

                                  message = "0";

 

                                  msgBuffer = message.getBytes();

 

                                  try {

                                         outStream.write(msgBuffer);

 

                                  } catch (IOException e) {

                                         Log.e(TAG, "ON RESUME: Exception during write.", e);

                                  }

                                  break;

                           }

 

                           return false;

                     }

 

              });

Stop功能函数:

public void stop() {

              try {

                     outStream = btSocket.getOutputStream();

 

              } catch (IOException e) {

                     Log.e(TAG, "ON RESUME: Output stream creation failed.", e);

              }

 

              String message = "0";

 

              byte[] msgBuffer = message.getBytes();

 

              try {

                     outStream.write(msgBuffer);

 

              } catch (IOException e) {

                     Log.e(TAG, "ON RESUME: Exception during write.", e);

              }

              flag=0;

       }

 

 

4.2 单片机平台部分

4.2.1编译环境与功能实现

我们选择的单片机编译环境为Keil uVision2,通过单片机对引脚进行规定,并且设定接收缓存区用以存放蓝牙通信获取的信息,同时规定信号传输方式为串行输入,设定合适运行参数。在编译完成后,make生成hex文件,这是转换为单片机的可执行文件,是要直接烧入单片机的。

本次共用到四个单片机引脚P3^2P3^3P3^4P3^5,分别对应前进、后退、左转、右转(由焊接时的实际连接决定),由于在安卓平台部分已对指令信号作出了规定,对不同的获得信息作出不同的反应,即对要求的宽口赋“0”即置低电平,对不需要的动作的端口赋“1”即置高电平。

4.2.2 程序烧录

烧录具体步骤请参见相关网页。单片机的程序烧录是基于TTL通信线以及专用烧录软件进行的,USB端接电脑, TxDRxd接收发送线连接对应的数据端,Vcc与发送模块Vcc相连, GND与发送模块GND连接。电脑端需使用USBRS232驱动。烧录软件我们选用了宏晶科技的STC-ISP进行单片机握手与程序下载烧录,如图4.5所示。

4.5  STC-ISP烧录软件操作界面

由于程序烧录的成功与否与单片机本身的晶振设置、烧录波特率以及所使用电脑的参数相关,因此我们的烧录是在经过多次修改各项参数的尝试后完成的,具体的参数设置与所用器材罗列如下仅供参考:

1、相关参数:

电脑型号:宏基电脑4930GVISTA操作系统

烧录可用端口:COM6COM7(这个具体视电脑管理界面显示的单片机接口而定)

单片机程序编写环境:Keil μVision2

烧录程序:STC-isp

2、烧录参数设定:

i. MCU TypeSTC11L02

ii. COMCOM6(换接口时为COM7

iii. 最高波特率:2400

iv. 最低波特率:2400(如此有利于烧录成功)

v. 下次冷启动后时钟源:内部RC振荡器(首次烧录)/外部晶体或时钟(后续复写烧录)

vi. 振荡器放大增益:Low

vii:打开程序文件位置的hex文件

3 烧录步骤及注意事项

i. 连接单片机版ON/OFF跳线帽,取下电池

ii. 完成上述参数设定

iii. 点击”下载“

iv. 提示上电(默认开启提示音)后,接入电池,提示正在下载后完全按下接入

v. 在烧录未完成或者未烧录成功情况下,不可直接移除USB接口,否则易导致STC软件无响应、自动退出或者电脑蓝屏死机的情况,如果参数设定错误或者操作步骤出现错误,也会导致蓝屏的情况。

4.3软件设计中我们遇到的问题及解决方法

其实本次设计用到的软件的主体部分为前面的同学设计完成的,再次表示感谢。我们在使用该程序的过程中遇到了些许问题,并经过讨论得到解决。

1:软件使用蓝牙模块的授权命令。开始我们发现并不能使用蓝牙模块,程序会报错。加入授权许可后编译方能通过;

2:运行程序总是显示SOCKET CLOSED,是因为手机蓝牙并没有与目标蓝牙连接成功。如果蓝牙未开,会提示你先打开蓝牙;

3:修改蓝牙mac地址;

4:在编译程序的时候可能由于某些原因,导致程序缺失,这是会出现编译错误,系统会自动提示修改方案,一般请况下,选择默认方案即可;

5:用Eclipse编译产生的众多文件中,bin文件下的apk文件为安卓手机的安装文件。

第五章 结论与展望

总的来说我们只完成了基础部分的功能,附加功能是失败的尝试。基础部分实现了用手机来控制小车前进、后退、左转、右转和停止的功能。但是基于不同小车的本身的性能和蓝牙的不同特性效果也是有差距的,对此我们总结出以下几点不足之处:

1、无急停效果,需要深度改造;

2、转弯角度受限,需要深度改造;

3、缓存区没有及时清除,导致在每次开始控制之初总会有不受控制的动作,为上次控制留下的控制数据,可以进一步改善;

4、运行速度不受控制,仅与电池的电压大小相关,可深度改造。

拓展部分未能实现预期的功能。但是个人认为仍可以进一步开发,因为命令错误在任何电子设备中都是可能存在的问题,既可以在用户操作界面上下功夫,也可以通过更改程序来避免命令错误的行为。对于我们工作方向的失误,对一起努力的队员们表示道歉。

第六章 项目总结与心得

   通过这次的科技创新的实践,使我对安卓手机的开发有了更深刻的了解。首先选择科创题目时,就是由于自己的兴趣,事实证明兴趣是最好的老师。

开始时面对如此的创新要求,内心还是有些许的畏惧,但与组员的相互讨论和实际操作,使大家更有信心,从开始的总体设计,人事安排,项目规划,到随后的安装开发环境与执行,出现问题,解决矛盾,学习讨论等,增进了大家的团队协作与克服困难的能力。

本次的科创我们所遇到的主要问题是串口的调试和蓝牙连接问题,但是通过与老师及时的沟通,大家不断的讨论实验,最终圆满的完成了此次的科创实验。

从中,我做学到的不止是软件使用等技术。更关键的是集体协作共同面对困难,解决困难的经历,使我对此次的科创经历有了更深的印象。

最后感谢老师和同组同学的帮助与指导。

——魏洪超

作为组长,我开始觉得压力比较大,因为初次接触到手机安卓平台这个东西。小组内的首次接触让我发现大家都是首次接触安卓平台,体会到了本次设计的艰难性。但是幸运的是,通过第一次与张老师的沟通,经过与老师沟通,老师非常简单的向我们说明了情况,并授权组内合理安排工作时间。对此我们都非常高兴。

还记得当时课程任务刚下来时,安装虚拟机时由于选的软件包过多,在电脑旁等了一个晚上才安装完成;还记得我们去领小车,发现老师给我们的设备已经很全,几乎不用我们自己再制造相关东西,特别是单片机和蓝牙模块;在钻研前人留下来的报告时,发现里面有些许错误,在经过数次的折腾和翻阅安卓手机开发的相关书籍后才解决;还记得在解决蓝牙连接问题的时候,经过试验我们自己各自的设想,最终蒋同学的办法非常好的解决了这个问题。还记得多少晚上,坐在电脑前编译程序,查阅相关函数,虽然最后自创的东西不多,但还是很好的理解了安卓中的许多语言,学到了很多的东西,正如张老师所说的,如果你认真的做,还是可以学到很多的东西的。在五月初的时候,程序已经可以在手机上实现了相应功能,但是单片机里的程序却不能烧录进去,去向张老师反应问题后,老师马上帮我解决了这个问题。在整个过程中,张老师一直都关注着我们,当我们遇到自己难以解决的问题的时候,随时可以找到老师。对与工作繁忙的老师来说,能做到这中地步时难能可贵的,所以非常的感谢张老师!

在最后的附加功能的设计与开发的时候,由于定的方向错误,导致功亏一篑,这是我的失职。但是队友们依然团结在一起,一起刻苦的钻研,为最后的任务奉献自己的力量,非常谢谢你们的工作,在这次科创中收获的不止是知识,还有这一份友情。

——龙文昌

一晃一个学期又过去了。这次的科技实践与创新也步入尾声。身为参与其中的一分子,我感慨万千。这次科创让我学会了很多,也有很多感触。

在基础实践阶段。我们巩固了以前练习的基本功:焊接电路板。而新的程序设计部分则给我们了一些小的挑战。科创3C很吸引我的地方就是它对安卓系统的应用。虽然身为一个电院男生我本该对嵌入式系统更熟悉一点,不过挑战未知更吸引人啊。可是,对于安卓系统的全新开发语言,我真的是丈二和尚摸不着头脑。幸好助教有给程序,而我又从图书馆里借了一辆本安卓的入门书,总算是稍微了解了一点程序大概运行的方式,稍加改动终于能让小车听指挥了。

然而,这只是个开始,在拓展阶段,我终于明白了这个项目困难的地方之所在。老师给的任务是很简单:想加什么功能就加什么功能。可是,自己心里想的和自己能够做到的总是存在着不小的差距,或者说:眼高手低吧。好几次,我想实现一个简单的功能时,却死活搞不定。为什么程序就不听指挥呢?我很烦恼。于是我只好去咀嚼原来的程序,豁然发现自己之前知道的仅仅是皮毛中的皮毛,离真正可以编写程序还差得远呢!

没办法,不积跬步,无以致千里。我只好一点一点坑教程,一部一部看视频,加上自己的实践。安卓的语言主要基于JAVA,和我所熟悉的C++有那么些联系,可是又完全不同。就像会英语的人说德语,既熟悉又陌生。而安卓的架构和C++也很不一样。有的方面确实很方便,比如布局什么的。可是XML我也不会,没办法。一步一步来吧。从最基础的程序结构,布局到主程序的编写,虽然进步很慢,不过每一个小步都离自己希望实现的功能更进一步不是吗?加上组员之间的交流磨合,我们的小车也能稍微动得灵活一点了。不过,时间终究还是有些短暂。加上自己的努力还有些不够,最终还是没能做到自己想做到的样子,不得不说有一些遗憾。不过,只要想做的话,以后有的是机会吧。希望以后有机会能把程序的完整版写出来。

--蒋文捷

第七章致谢

对于此次科创的工作过程中,张士文老师均亲自指导,对此我表示非常感激。由于选课人数不多,张老师便决定由小组内部掌握进度,又由于我们是大四学生,所以对如此的计划我们是非常高兴的。这给了我们充足的时间来完成这们课程,不至于操之过急而导致质量过低。在宽松的学习氛围中,张老师经常询问我们的进度,并询问我们遇到的问题与困难,及时与他沟通讨论,因此在此次课程中,张老师是给我们帮助和动力最大的人,再次表示衷心的感谢和祝福!再次,作为一个小组,我们组员内部之间互相帮助,互相体谅,互相学习,当出现问题时,一起讨论,一起寻找解决方法,一起去实验室验证设想,那段时间是非常充实和快乐的日子,有你们这样的搭档,我感到非常的荣幸。在此也对你们表示感谢与祝福,希望我们之间的这种合作精神能够成为一份美好的回忆。最后,感谢我的家人和周围同学的帮助,谢谢你们!

第八章参考资料

[1] 科创III-C PPT

[2] 科技创新III-C指导书

[3] JAVA编程思想》第三版  Bruce Eckel

第九章附录

程序清单:

安卓部分:

Main.xml   //窗体文件

 

<?xml version="1.0" encoding="utf-8"?>

<AbsoluteLayout

android:id="@+id/widget0"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

xmlns:android="http://schemas.android.com/apk/res/android"

> 

 

</Button>

<Button

android:id="@+id/btnF"

android:layout_width="100px"

android:layout_height="60px"

android:text="前进"

android:layout_x="130px"

android:layout_y="62px"

> 

</Button>

<Button

android:id="@+id/btnL"

android:layout_width="100px"

android:layout_height="60px"

android:text="左转"

android:layout_x="20px"

android:layout_y="152px"

> 

</Button>

<Button

android:id="@+id/btnR"

android:layout_width="100px"

android:layout_height="60px"

android:text="右转"

android:layout_x="240px"

android:layout_y="152px"

> 

</Button>

<Button

android:id="@+id/btnB"

android:layout_width="100px"

android:layout_height="60px"

android:text="后退"

android:layout_x="130px"

android:layout_y="242px"

> 

</Button>

<Button

android:id="@+id/btnS"

android:layout_width="100px"

android:layout_height="60px"

android:text="停止"

android:layout_x="130px"

android:layout_y="152px"

> 

</Button>

<SurfaceView

android:id="@+id/viewDraw"

android:layout_width="400px"

android:layout_height="400px"

android:layout_x="20px"

android:layout_y="310px"

> 

</SurfaceView>

</AbsoluteLayout>

 

 

package firsttest.android;

 

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.PowerManager;

 

import java.io.IOException;

 

import java.io.OutputStream;

import java.util.UUID;

import java.util.concurrent.Semaphore;

 

import android.app.Activity;

 

import android.bluetooth.BluetoothAdapter;

 

import android.bluetooth.BluetoothDevice;

 

import android.bluetooth.BluetoothSocket;

import android.content.DialogInterface;

import android.content.DialogInterface.OnClickListener;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Point;

 

import android.os.Bundle;

import android.provider.ContactsContract.CommonDataKinds.Event;

 

import android.util.Log;

import android.view.MotionEvent;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

import android.view.View;

 

import android.widget.Button;

import android.widget.Toast;

 

public class MysecondprojiectActivity extends Activity {

      private int a = 0;

 

      private static final String TAG = "THINBTCLIENT";

 

      private static final boolean D = true;

 

      private BluetoothAdapter mBluetoothAdapter = null;

 

      private BluetoothSocket btSocket = null;

 

      private OutputStream outStream = null;

      Button mButtonF;

 

      Button mButtonB;

      Button mButtonL;

      Button mButtonR;

      Button mButtonS;

      Button mButtonBL;

      Button mButtonBR;

      int flag=0;

 

      SurfaceView mSV;

      SurfaceHolder mSH;

      Semaphore surface_ready = new Semaphore(0);

 

      PathManager pm = new PathManager();

 

      private static final UUID MY_UUID = UUID

                  .fromString("00001101-0000-1000-8000-00805F9B34FB");

 

      private static String address = "00:10:04:08:00:30"; // <==要连接的蓝牙设备MAC地址

 

      /** Called when the activity is first created. */

 

      @Override

      public void onCreate(Bundle savedInstanceState) {

 

            super.onCreate(savedInstanceState);

            setContentView(R.layout.main);

 

           

            // 前进

            mButtonF = (Button) findViewById(R.id.btnF);

            mButtonF.setOnTouchListener(new Button.OnTouchListener() {

 

                  public boolean onTouch(View v, MotionEvent event) {

                        // TODO Auto-generated method stub

                        String message;

                        byte[] msgBuffer;

                        int action = event.getAction();

                        switch (action) {

                        case MotionEvent.ACTION_DOWN:

                              if(flag==1)

                              {

                              Toast.makeText(getApplicationContext(), "COMMOND ERROR!WILL STOP!",

                                    Toast.LENGTH_SHORT).show();

                              stop();

                              return false;

                              }

                        else

                              flag=1;

                              try {

                                    outStream = btSocket.getOutputStream();

                                    // Toast.makeText(SchoolFlower2Activity.this,

                                    // String.format("%d",a), Toast.LENGTH_LONG).show();

 

                              } catch (IOException e) {

                                    Toast.makeText(MysecondprojiectActivity.this,

                                                e.getMessage(), Toast.LENGTH_LONG).show();

                                    Log.e(TAG, "ON RESUME: Output stream creation failed.",

                                                e);

                              }

 

                              message = "1";

 

                              msgBuffer = message.getBytes();

 

                              try {

                                    outStream.write(msgBuffer);

                                    Toast.makeText(MysecondprojiectActivity.this, message,

                                                Toast.LENGTH_LONG).show();

 

                              } catch (IOException e) {

                                    Toast.makeText(MysecondprojiectActivity.this,

                                                e.getMessage(), Toast.LENGTH_LONG).show();

                                    Log.e(TAG, "ON RESUME: Exception during write.", e);

                              }

                              break;

 

                        case MotionEvent.ACTION_UP:

                        flag=0;

                             

                              Toast.makeText(getApplicationContext(), "flag wei o le",

                                          Toast.LENGTH_SHORT).show();

                              try {

                                    outStream = btSocket.getOutputStream();

 

                              } catch (IOException e) {

                                    Toast.makeText(MysecondprojiectActivity.this,

                                                e.getMessage(), Toast.LENGTH_LONG).show();

                                    Log.e(TAG, "ON RESUME: Output stream creation failed.",

                                                e);

                              }

 

                              message = "0";

 

                              msgBuffer = message.getBytes();

 

                              try {

                                    outStream.write(msgBuffer);

                                    Toast.makeText(MysecondprojiectActivity.this, message,

                                                Toast.LENGTH_LONG).show();

                              } catch (IOException e) {

                                    Toast.makeText(MysecondprojiectActivity.this,

                                                e.getMessage(), Toast.LENGTH_LONG).show();

                                    Log.e(TAG, "ON RESUME: Exception during write.", e);

                              }

                              break;

                        }

                        return false;

                  }

 

            });

 

            // 后退

            mButtonB = (Button) findViewById(R.id.btnB);

            mButtonB.setOnTouchListener(new Button.OnTouchListener() {

 

                  public boolean onTouch(View v, MotionEvent event) {

                        // TODO Auto-generated method stub

                        String message;

                        byte[] msgBuffer;

                        int action = event.getAction();

                        switch (action) {

                        case MotionEvent.ACTION_DOWN:

                              if(flag==1)

                              {

                              Toast.makeText(getApplicationContext(), "COMMOND ERROR!WILL STOP!",

                                    Toast.LENGTH_SHORT).show();

                              stop();

                              return false;

                              }

                        else

                              flag=1;

                              try {

                                    outStream = btSocket.getOutputStream();

 

                              } catch (IOException e) {

                                    Log.e(TAG, "ON RESUME: Output stream creation failed.",

                                                e);

                              }

 

                              message = "3";

 

                              msgBuffer = message.getBytes();

 

                              try {

                                    outStream.write(msgBuffer);

 

                              } catch (IOException e) {

                                    Log.e(TAG, "ON RESUME: Exception during write.", e);

                              }

                              break;

 

                        case MotionEvent.ACTION_UP:

                       flag=0;

                             

                              Toast.makeText(getApplicationContext(), "flag wei o le",

                                          Toast.LENGTH_SHORT).show();

                              try {

                                    outStream = btSocket.getOutputStream();

 

                              } catch (IOException e) {

                                    Log.e(TAG, "ON RESUME: Output stream creation failed.",

                                                e);

                              }

 

                              message = "0";

 

                              msgBuffer = message.getBytes();

 

                              try {

                                    outStream.write(msgBuffer);

 

                              } catch (IOException e) {

                                    Log.e(TAG, "ON RESUME: Exception during write.", e);

                              }

                              break;

                        }

 

                        return false;

                  }

 

            });

            // 左转

            mButtonL = (Button) findViewById(R.id.btnL);

            mButtonL.setOnTouchListener(new Button.OnTouchListener() {

 

                  public boolean onTouch(View v, MotionEvent event) {

                        // TODO Auto-generated method stub

                        String message;

                        byte[] msgBuffer;

                        int action = event.getAction();

                        switch (action) {

                        case MotionEvent.ACTION_DOWN:

                              if(flag==1)

                              {

                              Toast.makeText(getApplicationContext(), "COMMOND ERROR!WILL STOP!",

                                    Toast.LENGTH_SHORT).show();

                              stop();

                              return false;

                              }

                        else

                              flag=1;

                              try {

                                    outStream = btSocket.getOutputStream();

 

                              } catch (IOException e) {

                                    Log.e(TAG, "ON RESUME: Output stream creation failed.",

                                                e);

                              }

 

                              message = "2";

 

                              msgBuffer = message.getBytes();

 

                              try {

                                    outStream.write(msgBuffer);

 

                              } catch (IOException e) {

                                    Log.e(TAG, "ON RESUME: Exception during write.", e);

                              }

                              break;

 

                        case MotionEvent.ACTION_UP:

                         flag=0;

                             

                              Toast.makeText(getApplicationContext(), "flag wei o le",

                                          Toast.LENGTH_SHORT).show();

                              try {

                                    outStream = btSocket.getOutputStream();

 

                              } catch (IOException e) {

                                    Log.e(TAG, "ON RESUME: Output stream creation failed.",

                                                e);

                              }

 

                              message = "0";

 

                              msgBuffer = message.getBytes();

 

                              try {

                                    outStream.write(msgBuffer);

 

                              } catch (IOException e) {

                                    Log.e(TAG, "ON RESUME: Exception during write.", e);

                              }

                              break;

                        }

 

                        return false;

 

                  }

            });

            // 右转

            mButtonR = (Button) findViewById(R.id.btnR);

            mButtonR.setOnTouchListener(new Button.OnTouchListener() {

 

                  public boolean onTouch(View v, MotionEvent event) {

                        // TODO Auto-generated method stub

                        String message;

                        byte[] msgBuffer;

                        int action = event.getAction();

                        switch (action) {

                        case MotionEvent.ACTION_DOWN:

                              if(flag==1)

                              {

                              Toast.makeText(getApplicationContext(), "COMMOND ERROR!WILL STOP!",

                                    Toast.LENGTH_SHORT).show();

                              stop();

                              return false;

                              }

                        else

                              flag=1;

                              try {

                                    outStream = btSocket.getOutputStream();

 

                              } catch (IOException e) {

                                    Log.e(TAG, "ON RESUME: Output stream creation failed.",

                                                e);

                              }

 

                              message = "4";

 

                              msgBuffer = message.getBytes();

 

                              try {

                                    outStream.write(msgBuffer);

 

                              } catch (IOException e) {

                                    Log.e(TAG, "ON RESUME: Exception during write.", e);

                              }

                              break;

 

                        case MotionEvent.ACTION_UP:

                     flag=0;

                             

                              Toast.makeText(getApplicationContext(), "flag wei o le",

                                          Toast.LENGTH_SHORT).show();

                              try {

                                    outStream = btSocket.getOutputStream();

 

                              } catch (IOException e) {

                                    Log.e(TAG, "ON RESUME: Output stream creation failed.",

                                                e);

                              }

 

                              message = "0";

 

                              msgBuffer = message.getBytes();

 

                              try {

                                    outStream.write(msgBuffer);

 

                              } catch (IOException e) {

                                    Log.e(TAG, "ON RESUME: Exception during write.", e);

                              }

                              break;

                        }

 

                        return false;

 

                  }

 

            });

            // 停止

            mButtonS = (Button) findViewById(R.id.btnS);

 

            mButtonS.setOnTouchListener(new Button.OnTouchListener() {

 

                  public boolean onTouch(View v, MotionEvent event) {

                        // TODO Auto-generated method stub

                        if (event.getAction() == MotionEvent.ACTION_DOWN) {

                              if(flag==1)

                                    {

                                    Toast.makeText(getApplicationContext(), "COMMOND ERROR!WILL STOP!",

                                          Toast.LENGTH_SHORT).show();

                                    stop();

                                    return false;

                                    }

                              else

                                   

                              stop();

                              flag=1;

                        }

                        if (event.getAction() == MotionEvent.ACTION_UP) {

                              flag=0;

                             

                              Toast.makeText(getApplicationContext(), "flag wei o le",

                                          Toast.LENGTH_SHORT).show();

                        }

                        return false;

 

                  }

 

            });

 

            mSV = (SurfaceView) findViewById(R.id.viewDraw);

            mSH = (SurfaceHolder) mSV.getHolder();

            mSH.addCallback(new SurfaceHolder.Callback() {

 

                  public void surfaceDestroyed(SurfaceHolder holder) {

                        // TODO Auto-generated method stub

 

                  }

 

                  public void surfaceCreated(SurfaceHolder holder) {

                        // TODO Auto-generated method stub

                        // surface_ready.release();

                  }

 

                  public void surfaceChanged(SurfaceHolder holder, int format,

                              int width, int height) {

                        // TODO Auto-generated method stub

                        surface_ready.release();

                  }

            });

 

            mSV.setOnTouchListener(new View.OnTouchListener() {

 

                  public boolean onTouch(View v, MotionEvent event) {

                        // TODO Auto-generated method stub

                        pm.addPoint(new Point((int) event.getX(), (int) event.getY()));

                        return false;

                  }

            });

 

            // Redrawing thread

            final Handler handler = new Handler();

            new Thread(new Runnable() {

 

                  public void run() {

                        // TODO Auto-generated method stub

                        synchronized (mSH) {

                              while (true) {

 

                                    try {

                                          surface_ready.acquire();

                                    } catch (InterruptedException e1) {

                                          // TODO Auto-generated catch block

                                          e1.printStackTrace();

                                    }

                                    handler.post(new Runnable() {

 

                                          public void run() {

                                                // TODO Auto-generated method stub

                                                try {

                                                      MysecondprojiectActivity.this.onDraw();

                                                      surface_ready.release();

 

                                                } catch (Exception e) {

                                                      Toast.makeText(

                                                                  MysecondprojiectActivity.this,

                                                                  e.toString() + e.getMessage(),

                                                                  Toast.LENGTH_SHORT).show();

                                                }

                                          }

                                    });

                                    try {

                                          mSH.wait(30);

                                    } catch (InterruptedException e) {

                                          // TODO Auto-generated catch block

                                          e.printStackTrace();

                                    }

                              }

                        }

                  }

            }).start();

 

            if (D)

                  Log.e(TAG, "+++ ON CREATE +++");

            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

 

            if (mBluetoothAdapter == null) {

                  Toast.makeText(this, "Bluetooth is not available.",

                              Toast.LENGTH_LONG).show();

                  finish();

                  return;

            }

 

            if (!mBluetoothAdapter.isEnabled()) {

                  Toast.makeText(this,

                              "Please enable your Bluetooth and re-run this program.",

                              Toast.LENGTH_LONG).show();

                  // finish();

                  // return;

 

            }

 

            if (D)

                  Log.e(TAG, "+++ DONE IN ON CREATE, GOT LOCAL BT ADAPTER +++");

 

      }

 

      public void stop() {

            try {

                  outStream = btSocket.getOutputStream();

 

            } catch (IOException e) {

                  Log.e(TAG, "ON RESUME: Output stream creation failed.", e);

            }

 

            String message = "0";

 

            byte[] msgBuffer = message.getBytes();

 

            try {

                  outStream.write(msgBuffer);

 

            } catch (IOException e) {

                  Log.e(TAG, "ON RESUME: Exception during write.", e);

            }

            flag=0;

      }

 

      @Override

      public void onStart() {

 

            super.onStart();

 

            if (D)

                  Log.e(TAG, "++ ON START ++");

      }

 

      @Override

      public void onResume() {

 

            super.onResume();

            a++;

            if (D) {

                  Log.e(TAG, "+ ON RESUME +");

                  Log.e(TAG, "+ ABOUT TO ATTEMPT CLIENT CONNECT +");

 

            }

 

            Toast.makeText(MysecondprojiectActivity.this, "Resume:Connecting",

                        Toast.LENGTH_LONG);

            BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);

 

            try {

 

                  btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);

                  pm.btSocket = this.btSocket;

 

            } catch (IOException e) {

 

                  Log.e(TAG, "ON RESUME: Socket creation failed.", e);

 

            }

            mBluetoothAdapter.cancelDiscovery();

            try {

 

                  btSocket.connect();

 

                  Log.e(TAG,

                              "ON RESUME: BT connection established, data transfer link open.");

 

            } catch (IOException e) {

 

                  try {

                        btSocket.close();

 

                  } catch (IOException e2) {

 

                        Log.e(TAG,

                                    "ON RESUME: Unable to close socket during connection failure",

                                    e2);

                  }

 

            }

 

            // Create a data stream so we can talk to server.

 

            if (D)

                  Log.e(TAG, "+ ABOUT TO SAY SOMETHING TO SERVER +");

            try {

                  outStream = btSocket.getOutputStream();

 

            } catch (IOException e) {

                  Log.e(TAG, "ON RESUME: Output stream creation failed.", e);

            }

 

            String message = "1";

 

            byte[] msgBuffer = message.getBytes();

 

            try {

                  outStream.write(msgBuffer);

 

            } catch (IOException e) {

                  Log.e(TAG, "ON RESUME: Exception during write.", e);

            }

 

      }

 

      @Override

      public void onPause() {

 

            super.onPause();

 

            if (D)

                  Log.e(TAG, "- ON PAUSE -");

            if (outStream != null) {

                  try {

                        outStream.flush();

                  } catch (IOException e) {

                        Log.e(TAG, "ON PAUSE: Couldn't flush output stream.", e);

                  }

 

            }

 

            try {

                  btSocket.close();

            } catch (IOException e2) {

                  Log.e(TAG, "ON PAUSE: Unable to close socket.", e2);

            }

 

      }

 

      @Override

      public void onStop() {

 

            super.onStop();

 

            if (D)

                  Log.e(TAG, "-- ON STOP --");

 

      }

 

      @Override

      public void onDestroy() {

 

            super.onDestroy();

 

            if (D)

                  Log.e(TAG, "--- ON DESTROY ---");

 

      }

 

      public void onDraw() throws Exception {

            Canvas canvas = mSH.lockCanvas();

            if (canvas == null)

                  throw new Exception("Canvas is null");

            Paint paint = new Paint();

            paint.setARGB(255, 230, 230, 230);

            canvas.drawColor(paint.getColor());

 

            paint.setColor(Color.BLUE);

            Point[] path = new Point[0];

            synchronized (pm.path) {

                  path = pm.path.toArray(path);

            }

            PathManager.unit_vector dir = pm.curDir;

            for (int i = 1; i < path.length; i++) {

                  canvas.drawLine(path[i - 1].x, path[i - 1].y, path[i].x, path[i].y,

                              paint);

            }

            canvas.drawCircle(path[0].x, path[0].y, 10, paint);

 

            paint.setColor(Color.RED);

            canvas.drawLine(path[0].x, path[0].y, path[0].x + dir.x * 15.0f,

                        path[0].y + dir.y * 15.0f, paint);

            mSH.unlockCanvasAndPost(canvas);

      }

 

}

 

PathManager.java  //主程序2

 

package com.Android.SchoolFlower2;

 

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.Semaphore;

 

import android.bluetooth.BluetoothSocket;

import android.graphics.Point;

 

 

public class PathManager {

      public class unit_vector {

            float x,y;

            public unit_vector(Point st, Point ed) {

                  x = ed.x - st.x;

                  y = ed.y - st.y;

                  float mod = (float) Math.sqrt(x*x+y*y);

                  x /= mod;

                  y /= mod;

            }

            public float angleTo(unit_vector vec) {

                  //    in radian, positive value means clockwise

                  float angle = (float) Math.acos(x*vec.x + y*vec.y);

                  if ( x*vec.y > y*vec.x ) {

                        return angle;

                  } else {

                        return -angle;

                  }

            }

      }

      float distance(Point a, Point b) {

            float x = a.x - b.x;

            float y = a.y - b.y;

            return (float) Math.sqrt(x*x+y*y);

      }

 

      public List<Point> path = new ArrayList<Point>();

      public unit_vector curDir = new unit_vector(new Point(0,0), new Point(0,-1));

      public BluetoothSocket btSocket = null;

     

      private Semaphore points = new Semaphore(0);

     

      public PathManager() {

            path.add(new Point(200,200));

           

            new Thread(new Runnable() {

                  public final float rot_speed = 45.54f;

                  public final float mov_speed = 10.0f;

                  @Override

                  public void run() {

                        // TODO Auto-generated method stub

                        try {

                              while(true) {

                                    points.acquire();

                                    Point st, ed;

                                    synchronized(path) {

                                          st = path.get(0);

                                          ed = path.get(1);

                                    }

                                    unit_vector dir = new unit_vector(st,ed);

                                    float rot = curDir.angleTo(dir);

                                    if ( rot > 0.1f || rot < -0.1f ) {

                                          try {

                                                if ( rot > 0.1f )

                                                      btSocket.getOutputStream().write('4');      //    Turn right

                                                else

                                                      btSocket.getOutputStream().write('2');      //    Turn left

                                          } catch(Exception e) {

                                          }

                                          Thread.sleep( Math.round(Math.abs(rot) * rot_speed) );

                                    }

                                    curDir = dir;

                                    float dist = distance(st, ed);

                                    try {

                                          btSocket.getOutputStream().write('1');

                                    } catch (IOException e) {

                                          // TODO Auto-generated catch block

                                          e.printStackTrace();

                                    }

                                    Thread.sleep( Math.round(dist * mov_speed) );

                                    try {

                                          btSocket.getOutputStream().write('0');

                                    } catch (IOException e) {

                                          // TODO Auto-generated catch block

                                          e.printStackTrace();

                                    }

                                    synchronized(path) {

                                          path.remove(0);

                                    }

                              }

                        } catch (InterruptedException e) {

                              // TODO Auto-generated catch block

                        }

                  }

            }).start();

      }

     

      public void addPoint(Point p) {

            synchronized(path) {

                  path.add(p);

            }

            points.release();

      }

}

 

 

 

单片机部分:

#include <reg51.h>

#include <absacc.h>

 

unsigned char data cmd = 0x00;

 

unsigned char cnt = 0;

 

 

 

// Enable bit, set to 0 to run the motor

sbit up = P3^2;

sbit down = P3^3;

sbit right = P3^4;

sbit left = P3^5;

 

sfr AUXR1 = 0xA2;

 

// 1 = forward, 0 = back

 

void global_init();

void serial_init();

void send_back(unsigned char c);

void motor_move(unsigned char command);

 

void main()

{

      global_init();

 

      while(1);

}

 

void global_init()

{

      //left_speed = speed;

      //right_speed = speed;

 

      TMOD |= 0x02;

      TH0 = 0xec;

      TL0 = 0xec;

      ET0 = 1;

      TR0 = 1;

 

      AUXR1 |= 0x80;

 

      serial_init();

      EA = 1;

 

      send_back(0xaa);

}

 

void serial_init()

{

//请用实际行动支持宏晶STC大陆本土MCU统一全球市场

 

      PCON &= 0x7f;           //波特率不倍速

      SCON = 0x50;            //8位数据,可变波特率

      //AUXR &= 0xbf;         //定时器1时钟为Fosc/12,12T

      //AUXR &= 0xfe;         //串口1选择定时器1为波特率发生器

      TMOD &= 0x0f;           //清除定时器1模式位

      TMOD |= 0x20;           //设定定时器18位自动重装方式

      TL1 = 0xFD;       //设定定时初值

      TH1 = 0xFD;       //设定定时器重装值

      ET1 = 0;          //禁止定时器1中断

      TR1 = 1;          //启动定时器1

 

 

 

      IE |= 0x90;

 

      PS = 1;

      up = 1;

 

      down = 1;

 

      right = 1;

 

      left = 1;

}

 

void send_back(unsigned char c)

{

      ES = 0;

      TI = 0;

      SBUF = c;

      while (TI == 0);

      TI = 0;

      ES = 1;

}

 

 

// Move forward: 0x18

// Move backward: 0x00

// Turn left: 0x10

// Turn Right: 0x08

// Stop: 0x78

/*

void motor_move(unsigned char command)

{

      EA = 0;

 

      if ( command & 0x80 )

      {

            speed = command & 0x3F;

 

            // 1 as its most significant bit

            // indicates setting speed

            // Its second most significant bit

            // indicates whether setting left motor speed

            // or right motor speed

            // Its remaining bit is the actual speed value

            if ( command & 0x40 )

                  right_speed = speed;

            else

                  left_speed = speed;

      }

      else

      {

            left_enb = command & 0x40;

            right_enb = command & 0x20;

            left_dir = command & 0x10;

            right_dir = command & 0x8;

 

            if ( left_enb && right_enb )

                  left_speed = right_speed = 0;

            else

                  left_speed = right_speed = 0x3F;

      }

 

      EA = 1;

}

*/

 

// Timer based interrupt to set speed

void timer0( void ) interrupt 1 using 1

{

      ET0 = 0;

 

 

      if ( ++cnt == 0x3F )

            cnt = 0;

 

 

      ET0 = 1;

}

/*

void receive_cmd() interrupt 4 using 3

{

      if (RI == 1)

      {

            RI = 0;

            cmd = SBUF;

            send_back(cmd);

 

            u = 0;

 

            motor_move(cmd);

      }

}

*/

 

void receive_cmd() interrupt 4 using 3

{

      if (RI == 1)

      {

            RI = 0;

            cmd = SBUF;

            send_back(cmd);

            if(cmd == '1'){

                  up = 0;

            }else if (cmd == '3'){

                  down = 0;

            }else if(cmd == '4'){

                  left = 0;

 

                  up = 0;

            }else if (cmd == '2'){

                  right = 0;

 

                  up = 0;

            }else if (cmd == '5'){

                  down = 0;

                  left = 0;

           

            }else if (cmd == '6'){

                  down = 0;

                  right = 0;

            }else{

               up = 1;

               down = 1;

               left = 1;

               right = 1;

            }

          //u = 0;

            //stay();

      }

}

 

 

 

 

 

 

/*#include <reg51.h>

 

sbit up = P3^2;

sbit down = P3^3;

sbit left = P3^4;

sbit right = P3^5;

 

void main(void)

{

    unsigned char x;

      //x = SBUF;

   

    EA = 1;

      SCON = 0x52;

      TMOD = 0x20;

      TH1 = 0xFA;

      TR1 = 1;

      ES = 1;

 

    up = 1;

    down =1;

    left = 1;

    right = 1;

    for(;;);

      {

            x = SBUF;

     switch(x)

       {

         case '1': up = 0;break;

         case '3': down = 0;break;

         case '2': left = 0;break;

         case '4': right = 0;break;

         case '0': {up = 1;down = 1;left = 1;right = 1;break;};

 

         }

     

       //down = 0;

       //up = 0;

       //left = 0;

       //right = 0;};

 

}

}

 

serial() interrupt 4

{

      static int a = 0;

      if (TI) {

            RI = 0;

            left = 0;

            right=1;

      }

      //TI=0;

      else {

      right = 0;

      RI = 0;

      left=1;

 

      }

    //down = 0;

      //left = 0;

    //right = 0;

 

}

*/