基于STM32的无线遥控小车的设计与实现_第1页
基于STM32的无线遥控小车的设计与实现_第2页
基于STM32的无线遥控小车的设计与实现_第3页
基于STM32的无线遥控小车的设计与实现_第4页
基于STM32的无线遥控小车的设计与实现_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

引言在这高速发展的21世纪,路上随处可见造型漂亮玩法新颖的玩具小车和飞机,自动公交车、无人出租车也是科学家们研究的热门。我对这一嵌入式、也是自动化技术十分的感兴趣。首先它非常有趣,可以成为孩子和家人的娱乐活动,其次它的技术性也很高,和我的专业还算对口,最重要的一点就是,它的科技时尚性非常强,是走在科技前沿的研究项目。回顾智能车辆研究的历史:在上世纪50年代初,国外就有关于智能车辆的研究了。从90年代开始,智能车辆研究就进入了系统化大规模的研究阶段。尤其突出的成果是美国卡内基梅陇大学机器人研究所完成的Navlab系列自主车辆的研究,这一研究成果成为国外智能车辆的主要里程碑。而国内对于智能车辆的研究较晚,研究始于上世纪80年代,现在大部分还是使用入门级别的51单片机进行设计与研究。为了弥补与国外研究的差距,教育部和工业和信息化部共同发起了全国大学生电子设计竞赛。本课题智能小车,通过各种蓝牙模块获得外部的指令和内部的中断,实现简单的前进、后退、左转、右转、停止的简单遥控运动功能。通过研究完成简易智能小车的设计,增进了毕业生理论与实践相结合的基础知识,也锻炼了基本的动手能力。可以使学生在了解智能化电器工作原理的基础上,再获得完成整体项目的能力,还能够掌握stm32开发板的编程原理,为学生走上工程应用,成为优秀沉稳的工程师打下了无比坚固的基础。2开发环境及软件的介绍2.1开发环境系统环境:Windows72.2软件介绍①Eclipse(蓝牙遥控app)Eclipse是从事java开发的软件工作人员的不二选择,原因有n,一是因为它开放源代码,而且可扩展,可塑性很强。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境;二是因为它附带了一个标准的插件集,比如JDK,方便快捷,不用再次单独安装,省了麻烦;三是它界面友好,操作性强,很容易使用。我使用的是EclipseIDEforJavaEEDevelopers(MARS),是一个2015年发布的最新版本。eclipse有java和javaee两种产品,java的功能要少一点,而javaee可以用于安卓开发和web开发。工具都已经安装在内,是全面理想的Java开发工具,java语言开发手机app的理想平台。②Keil5(控制系统)KeilC51是美国KeilSoftwar公司出品的51系列C语言软件开发系统,易学易用,包括C编译器、宏汇编、链接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(μVision)将这些部分组合在一起。我用的并不是keil的c51版本,而是MDK版本,c51版本不能开发stm32芯片,二MDK版本是一个stm32开发的利器。Keil公司是一家微控制器(MCU)软件开发工具的独立供应商,于2005年由ARM公司收购。2011年3月ARM公司发布最新集成开发环境RealViewMDK开发工具中,集成了最新版本的KeilμVision4,其编译器、调试工具与ARM器件完美匹配。2013年10月,Keil正式发布了KeilμVision5IDE,本次设计用的就是这一版本的软件。它的界面强大而友好,功能栏漂亮又清晰,字号较大,颜色是绿色,起观看感受良好的护眼作用。③STM32STlinkUtility(烧写)STM32ST-LINKUtility软件主要的功能就是量产(批量下载代码的工具),它是一个功能多而全的实用工具,它的界面简洁专业,用色舒适,可以新建和编辑文件、对flash数据快速读取、对芯片进行基本信息例如型号、ID、版本等的检索、强大的IAR在线调试仿真功能、烧写功能、帮助功能,非常方便。此外,虽然我是单独安装驱动的,但它已经包含了ST-Link驱动,无需再次下载,可以直接使用stlink有关仿真烧写功能,是一款很好的下载(烧写)仿真软件。3总体设计3.1总体需求我认为主要的功能需求有两个:遥控、电机驱动。1.遥控通讯可选用的方式:①红外线②无线电波③蓝牙④总线总线因为不符合题意,所以不考虑。不管是蓝牙还是红外线都需要使用模块或者一个红外/蓝牙发送设备。我不太清楚无线电波是使用什么发送的,不过应该也是根据对频来发送数据。遥控器可以是实物,由电路或者模块控制,也可以是遥控软件。自己设计电路需要自己印制电路板。我想到可以编写手机app来遥控,我虽然学习过安卓开发,但关于蓝牙部分我从未学习过,很感兴趣,所以选择了使用蓝牙。2.电机驱动有两种方式:①自己设计电路来放大信号,从而驱动电机。②使用电机驱动模块。控制芯片发出的信号是一定要经过放大才能驱动电机的。如果自己设计电路,就要涉及印制电路的工作,包括打孔、覆膜、成膜、脱膜,因为我对设计和印制电路没有什么经验和把握,加上有一个编写app的任务,时间算上去比较紧迫,所以选择了简单的驱动模块方式来驱动电机。3.2芯片模块选择控制芯片的选择是一件重要的事情。C51和STM32的芯片是最为基础通用的,其中c51是课程内学过的,而STM32没有学过。现如今,c51单片机的使用通常是在大规模的复杂项目中,而stm32芯片以其小规模、低成本、易入门,在本次学习型开发上有着巨大的先天优势。也因为市面上有很多stm32芯片的项目,而我却没有学过,所以想在本次设计中好好学习一下。STM32控制芯片有很多不同的型号,如何选用,我的标准是,要一个热门通用的最小型芯片。既然是做最简单的遥控小车,芯片必然不需要很大。图3-1STM芯片型号上图3-1为STM32的各种型号。STM8是8位系统,32是32位系统,我感觉8位显然是不那么够用。而STM32分为H7、F7、F4、F2、F3、F1、F0、L4+、L4、L1、L0好几种型号。其中,F0、F1、F3为主流产品,L0、L1、L4、L4+为超低功耗产品,F2、F4、F7、H7为高性能产品。其中F101和F103最为主流,而F103C8T6的核心板十分小型,支持SWD烧写,比较简单。下图3-2为型号命名规则,我选择的stm32f103c8t6为增强型芯片子系列、48引脚、64K字节flash、LQFP封装、工作温度为-40°~85°。图3-2型号命名规则图3-3F103C8T6核心板孔位图上图3-3为c8t6的核心板孔位图,上侧为B1、0、10、11、A0~7、C13~15,下侧为B12~15、A8~15、B3~9,左侧为USB接口,右侧为SWD烧写的四个接口,中间为各种核心接口和芯片。3.3车体设计和工具使用1.车体设计虽然这只是简单的小车,不是小汽车,不需要车体设计学习基础,但实际上车体设计是不可小觑的。最主要的问题是底板的材料,材料的质量好坏其实是非常影响小车开起来的效果和使用寿命的。我有以下几种设想:①木材②PCB③菲林片④塑料面板木材不太好看,可能也不太牢固,塑料面板安装比较费劲,容易散架。我在网上看到了线程的PCB小车底板,孔位和大小都很合理,如下图3-4:图3-4底盘2.工具及使用工具:电烙铁、热熔胶枪。图3-5电烙铁因为在实际过程中,我遭遇了很大的困难(详情见下文第七章调试与测试),所以特别指出做小车的注意事项:①在电机安装在底板下之前对其进行焊接。②确认购买好的电烙铁进行焊接。焊接方法:一般来说是从针的两个方向焊接的,一面是电烙铁,一面是焊锡,但是劣质电烙铁和焊盘通常焊不上。就会变成焊锡与焊枪在同一侧,这样容易虚焊,一定要当心,最好拿一个微型放大镜检查。虚焊容易导致很多莫名其妙的(接触不良)错误。图3-6热熔胶、红黑线、杜邦线、备用电池盒3.4软件选择1.蓝牙遥控app:安卓开发常用软件:MyEclipse、Eclipse等。我选择Eclipse的原因是:方便安装、使用简单、在之前课程中已经安装过。2.控制系统:我学过c语言的keilC51,本次使用KeilMDK(version5),就能够编写stm32芯片的程序了。3.烧写:这是个非常重要的问题。因为只有定下了芯片型号,知道这块板支持什么烧写模式,才能够定下烧写模式,才能够定下烧写软件。烧写其实有很多种方法,C51单片机其实就比较通用com口、flash、boot等串口来烧写文件系统,而stm32的烧写方式则有J-link、ST-link、SWD、SPI、JTAG等。F103C8T6核心板支持SWD模式,可以使用STlink进行烧写,故而,我决定使用ST-link官方烧写软件。4硬件原理4.1STM32F103C8T6芯片图4-1主控模块(c8t6核心板)接口原理图GPIO口就是通用IO接口,有PA~G。其中,PA9为输出口,PA10为输入口,我使用PB12~15连接电机。如下图4-2,我使用STlink连接PC和SWD接口来实现仿真和烧写。在拿到排针和核心板的时候,我需要先用电烙铁把引脚焊起来,焊接方法如前页。图4-2功能分布图上图4-2为实物图,孔图在上章已经介绍过。下图4-3为核心板的详细参数,因为是核心板,所以是最mini的一个型号,适合用作完成简易遥控小车。图4-3参数介绍4.2HC05蓝牙模块图4-4HC05蓝牙模块引脚接口STATE状态引脚,正面有小灯闪烁表示状态:无连接状态为快闪,连接状态变为慢闪。板载3.3V稳压芯片,输入电压直流3.6V-6V;未配对时,电流约30mA(因LED灯闪烁,电流处于变化状态)。配对成功后,电流大约10mA。我连接TXD(输出端)到c8t6的A10口(输入口),GND和VCC接在主控板上即可。空旷地带有效传输距离10米。按下按键再给蓝牙模块通电可以进入AT模式,设置参数和查询信息。可以通过AT命令切换主机和从机模式。模块默认波特率为9600、默认配对密码为1234、默认名称为HC-05。带透明热缩管保护。4.3L298N电机驱动模块图4-5L298N电机驱动模块上图4-5为L298N实物图,输出AB口接两个电机,供电口接红黑电源线。下图4-6为原理图,电机驱动电路是一个放大电路,通过放大控制信号来驱动电机。图4-6L298N原理图图4-7输入口与电机状态根据上图4-7L298N的资料数据,只要了解输入口与电机状态的关系,就可以知道如何编写控制程序了。IN1、2控制一个电机(右),IN3、4控制另一个(左)。4.4马达、轮胎与电池马达是直流减速马达(俗称TT马达),电路图如下,由图可知马达电路的原理,是一个放大电路。图4-8马达电路图图4-9马达设计图上图4-9为马达设计图,我这里遇到了一个马达和轮胎的适配性的问题,如果离地的时候轮胎转得没有问题,但是在地上跑却不能正常运行,是马达和轮胎接触不好。考虑换一个轮胎。各模块的电压不同,我设计用电池盒(蓄电池)向L298N通过12V接口供电,并向主控芯片供电,主控芯片向HC05用3.3V接口供电。我采用4节1.5V的5号电池供电,肯定是够用的。而且我选择的电池盒自带开关,是小车电源安全的保障。下图4-10为供电流向图。图4-10供电流向图4.5STlink烧写器图4-11烧写器烧写器连接芯片的SWD接口,IO、GUN、CLK、3.3V四个接口就够了。SWD烧写以其简单为优势,可以通过最少的四根接线完成烧写。5控制系统设计5.1原理图和数据流程图图5-1控制系统原理图上图5-1为使用protues8画的控制系统原理图,画得比较简单,由三个模块(蓝牙模块未画出)和两个电机组成。蓝牙模块因为找不到其库文件,从而不能导入。下图5-2为蓝牙模块原理图。图5-2HC05原理图下图5-2为数据流程图,HC05从app上接收到数据,通过输入输出口传给C8T6,再通过L298N化为合格的高低电平信号。图5-3数据流程图5.2详细设计①IO口定义位带(bit-band)操作:支持了位带操作后,可以使用普通的加载/存储指令来对单一的比特进行读写。图5-4位带操作优势支持位带操作的两个内存区的范围是:0x2000_0000‐0x200F_FFFF(SRAM区中的最低1MB)0x4000_0000‐0x400F_FFFF(片上外设区中的最低1MB)对SRAM位带区的某个比特,记它所在字节地址为A,位序号为n(0<=n<=7),则该比特在别名区的地址为:AliasAddr=0x22000000+((A-0x20000000)*8+n)*4=0x22000000+(A-0x20000000)*32+n*4对于片上外设位带区的某个比特,记它所在字节的地址为A,位序号为n(0<=n<=7),则该比特在别名区的地址为:AliasAddr=0x42000000+((A-0x40000000)*8+n)*4=0x42000000+(A-0x40000000)*32+n*4上式中,“*4”表示一个字为4个字节,“*8”表示一个字节中有8个比特。图5-5位带操作②初始化输出口图5-6PB口的定义和初始化图5-7PB12~15的初始化定义为PB输出口设定模式、速度、初始化和reset。③串口定义图5-8串口定义对串口初始化并使能串口,确定字长、停止位、校验、模式、中断。对蓝牙模块传来的数据进行处理的函数也在串口(usart)的初始化之中,这是个比较重要的部分,使用GetITConfig函数来判断中断,然后使用ReceiveData函数进行寄存器的读取写入。④主函数图5-9主函数流程图在串口经过读取的数据再传入主函数,进行实际的电机控制。5.3仿真与烧写我在proteus8上画了原理图,但鉴于没有HC05,而且涉及蓝牙的连接控制,在proteus8上就不太好仿真了。Keil5也是可以连接STlink并连接真机仿真的,但网上说不太好用,而且看上去比较麻烦。我感觉没什么大问题,所以我直接烧写之后测试了。图5-10烧写成功6蓝牙遥控app设计6.1需求分析界面:①上、左、下、右、停五个按键界面②状态标题栏③蓝牙连接菜单功能:①蓝牙连接②状态(thread)③数据传送6.2详细设计 图6-1功能服务类 图6-2界面1.生命周期本项目有2个activity、1个service,activity的生命周期如下图6-3所示,先要经过创建(create)、启动(start)、(重新开始resume)、(暂停pause)、停止stop、销毁destory。图6-3生命周期上图6-3为一个activity的生命周期,下面从两大activity开始介绍流程和功能:图6-4生命周期与状态参数主界面进行create和start,然后进行连接操作,转到设备界面,进行操作后传参回到主界面。2.状态参数STATE_NONE 无连接STATE_LISTEN start后监听中STATE_CONNECTING 正在连接STATE_CONNECTED 已连接MESSAGE_STATE_CHANGE 状态变化MESSAGE_DEVICE_NAME 记录连接上的设备名MESSAGE_TOAST 蓝牙丢失/连接不上REQUEST_CONNECT_DEVICE 待连接设备REQUEST_ENABLE_BT 蓝牙已连接3.线程图6-5线程类根据不同的线程状态决定操作,有三个线程:accept、connect、connected。Accept线程主要负责蓝牙设备的预连接,connect主要负责连接,connected主要负责写操作。4.操作流程①初始化:新建listview、蓝牙适配、按键监听②连接→显示已配对→搜索并显示→选择→返回参数③按键监听→service.write()→线程(write)→connectedthread.write()(完成对蓝牙设备的数据传送)连接功能//Theon-clicklistenerforalldevicesintheListViewsprivateOnItemClickListenermDeviceClickListener=newOnItemClickListener(){publicvoidonItemClick(AdapterView<?>av,Viewv,intarg2,longarg3){//Canceldiscoverybecauseit'scostlyandwe'reabouttoconnectmBtAdapter.cancelDiscovery();//GetthedeviceMACaddress,whichisthelast17charsintheViewStringinfo=((TextView)v).getText().toString();Stringaddress=info.substring(info.length()-17);//CreatetheresultIntentandincludetheMACaddressIntentintent=newIntent();intent.putExtra(EXTRA_DEVICE_ADDRESS,address);//SetresultandfinishthisActivitysetResult(Activity.RESULT_OK,intent);finish();}};2)搜索并显示://Iftherearepaireddevices,addeachonetotheArrayAdapterif(pairedDevices.size()>0){findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);for(BluetoothDevicedevice:pairedDevices){mPairedDevicesArrayAdapter.add(device.getName()+"\n"+device.getAddress());}}else{StringnoDevices=getResources().getText(R.string.none_paired).toString();mPairedDevicesArrayAdapter.add(noDevices);}6.3蓝牙连接功能NYNY图6-4蓝牙连接流程图点击搜索按钮,搜索按钮会消失,找到的设备会出现。7测试与调试两个系统的调试步骤:①单个模块的调试:先把app和控制程序在各自的仿真环境下测试部分功能。为连接好的小车做通电测试。②把有关模块结合在一起调试:把app和HC05连接上,烧写控制程序,一起测试,测试全部功能。③综合调试:测试小车的安全、性能和强度。第二步看上去是比较困难的,原因如下:(1)模块相互调用时接口会引入许多新问题。(2)一个模块对另一个模块可能造成不良影响。(3)几个子功能组合起来不能并实现主功能。(4)误差不断积累达到不可接受的程度。7.1蓝牙app的连接和搜索 图7-1连接界面1 图7-2连接界面2上图7-1为主界面有两个标题栏、5个按键和两个菜单按钮。图7-2为初始连接设备界面,自动搜索已匹配设备并显示在Listview里,可以直接进行选择,如果没有要的设备,可以点击下面“查找设备”按键。 图7-3连接成功 图7-4搜索上图7-3为连接成功的界面,右上角状态标题显示为“连接到:XXX”,并弹出广播“connectedtoXXX”。图7-4为点击搜索按键后的连接界面,会显示出搜索到的设备和地址。Ps:地址为17位。7.2蓝牙app的前后左右停功能(后台测试)图7-5调试的log记录导出备份上图7-5为log的debug调试记录导出,第一列为日期,第二列为时间,第三列“I/E”为类型,第四列为debug名称,冒号后的第五列为内容。7.3小车连接通电测试第一次通上电就烧起来了,很可能是因为接线问题。图7-6电池盒电线烧坏后残余零件第二次我买了一些零件重新接线后,通电成功!图7-7通电成功!由于邮寄使得引脚变松,我不得不重新做第三次,通电成功。图7-8小车37.4整体(控制系统+蓝牙app)调试①不能直接切换别的按键,要点一下停止,否则HC05会失去连接(无电)。猜测原因:电压/电线连接。按理来说前后转是可以直接切换的,和蓝牙模块并无关系。解决方法:接触问题。结果:未解决②小车拿着测试,一切正常,但在地上跑的时候会有各种错误。猜测原因:轮胎和马达匹配不良。解决方法:换一对轮胎。结果:已解决③蓝牙连接偶尔有自动断开的情况,HC05通电正常。猜测原因:电线连接问题。解决方法:重新接线或者固定或者焊接。结果:已解决④邮到学校后:一个马达不会转了;蓝牙变得只能接收一个命令,然后就自动断开连接。过了一天:经过重新插拔、调整角度,蓝牙的“停”功能时而失灵。左侧马达依旧不转。猜测原因:马达问题,或者接线问题。解决方法:重新接线,测试马达。结果:蓝牙和马达都是因为接线和邮寄运输问题,使焊盘脱焊了,而且本来就因为电烙铁不太好而没焊好。重新焊接主控芯片后解决。7.5性能测试①安全性:安全性即小车是否安全。首先,我的接线避免了各种触碰短接的可能性,接口和芯片为止都用热熔胶或螺丝固定住。除非人为故意破坏,不然是不太可能短接引起安全事故的。图7-9HC05热熔胶固定图7-10马达热熔胶固定其次,小车的电压是5V。人体的安全电压是36V(潮湿坏境下12V),安全电压为10mA。所以小车不会对人体产生危害。②性能测试:因为是最简单的小车,所以没有在调速方面进行设计和编写。小车的速度视在什么地方跑而定,平地速度为5m/s。③强度测试:强度测试分为2项,抗摔和抗压。抗摔:因为不是越野小车,最好还是在平地跑,爬陡坡和石砾地还是比较困难的。抗压:因为小车没有车顶,所以应该是不抗压的,压坏电线就不好了。8总结时光如风,呼啸而过又消失无踪。在这个充满青春记忆的熟悉大学校园里,一草一木都承载着我和同学的同窗情谊。我们一同学习,在知识的广阔天空里翱翔,获取无尽的经验和能力,也为了各自的目标奋斗,最终在这里分道扬镳。在大四这一年我经历着成长的巨变,作为一个即将走入社会的毕业生,我开始明确自己的方向,变成一个需要肩负起责任的大人。我的专业并没有对电路设计有一个比较深入的涉及,所以我感觉电路对我来说真的很陌生,学习仿佛无从下手。但我想往这方面发展,所以在本次的毕业设计中,我选择了嵌入式的题目,以便对电子和电路有了更多的了解。我相信不着急慢慢来,打下扎实沉稳的基础,功夫就会不负有心人,水滴可以穿石,积少可以成多,我一定可以得到我想要的知识。在这半年里,我从刚开始的一头雾水,到后来的一知半解,再到最后的屡次失败,其实都是莫大的进步。初期,我着手了解软件的选择和硬件的基础知识,然后购买零件动手做小车,再编写软件进行遥控和电机控制,最后通过调试,获得了阶段性的胜利。之所以说是阶段性,是因为虽然小车成功运行,但本次还有未解决的问题,而且我觉得以后我还可以学习更多高级技术,来让小车功能更完善。比如PWM调速技术,可以通过编程对电机进行更好的调速控制;还有PID技术,我觉得只有入门这项高级控制技术,才算是摸到了自动化的门槛。磨刀不误砍柴功,在这次设计里,我觉得最重要的坎坷就是焊接部分,首先我买了一个不好的焊枪,焊得不是很牢固,导致出现了一两个莫名其妙的问题。后来邮寄到学校,出现了更多莫名其妙的问题,找了很久才发现焊锡脱落了。于是我重新找焊枪焊了,这些莫名其妙的问题就几乎都消失了。所以说做一个实物,手工活真的是基础又重要。其实嵌入式的技术知识非常的多而精深奥妙,比如FATFS文件系统涉及很多基层文件、CAN控制器的通信实现、FLASH和SD卡的使用等等,还有很多很多技术让我去熟悉和掌握,还有很多很多地方等待着我去跌倒。以后,我会殚精竭力地在职业生涯中升级自己,掌握更多的技能和细节经验,迎接激烈的竞争,走上更好的人生。参考文献刘火良.杨森.STM32库开发实战指南.北京:机械工业出版社.2017.沈红卫.STM32单片机应用与全案例实践.北京:电子工业出版社.2017.姚文详(英).ARMCortex-M3权威指南.北京:北京航空航天大学出版社.2009.柯博文.Android5.1实战指南.北京:清华大学出版社.2015.ShibuKizhakkeVallathal(印).嵌入式系统设计与开发实践.北京:清华大学出版社.2017.无线电编辑部.智能小车机器人制作大全.北京:人民邮电出版社.2017.刘军张洋左忠航.STM32F7原理与应用——寄存器版(下).北京:北京航空航天大学出版社.2017.周柱.基于STM32的智能小车研究[D].西南交通大学.2011.何立民.单片机技术的现状与未来[J].中国计算机报.2012年NO:30.赵振德.多功能遥控智能小车的制作[J].电子制作.2011年4期.李瀚霖等.智能小车研究与设计[J].科技致富向导.2011年26期.尹念东.智能车辆的研究及前景[J].上海汽车.2002.2.童诗白华成英.模拟电子技术基础.北京:高等教育出版社.2006姜宝华齐强.基于单片机的无线遥控智能小车的设计与制作[J].计算机测量与控制.2013,(2):24-25.王晶.智能小车运动控制技术研究.武汉理工大学.2009致谢经过紧张的设计和开发,我基本实现了遥控小车的简单功能,前进、后退、左转、右转,对这一嵌入式课题加深了很多理解。由于设计时间紧凑,虽然在开发过程中解决了很多意想不到的困难,但还是有几个问题没有解决,我会在以后多加学习,弥补这一遗憾。主要是硬件接线方面,因为我毫无经验,所以有很多低级而莫名其妙的奇怪错误,在此过程和毕业论文的写作过程中,我要感谢张秀坤老师的悉心指导和谆谆完善建议。老师对我的影响很大,她耐心的指导和不断的鼓励促使我增强了坚韧不拔的精神意志,才能在这段历程中坚持了下来,并最终完成了毕业设计。所以在此,我对老师表示衷心的感谢,让我学到了终生受益的东西。我就像一匹学步的小马,想着有一天可以驰骋在辽阔的大草原。在今后日子中,我将跨过山川河流,经过春天的百花,踏着夏天的明月,穿过秋天的清风,在冬天的雪夜中不断前行,继续学习深入实践,不断提升自我,做一个出色的大人。附录【app】1.Bluetoothchat.java片段 publicvoidonClick(Viewv){ //TODOAuto-generatedmethodstub switch(v.getId()){ caseR.id.button0: value[0]=0; break; caseR.id.button1: value[0]=1; break; caseR.id.button2: value[0]=3; break; caseR.id.button3: value[0]=5; break; caseR.id.button4: value[0]=7; break; default: break; } } mChatService.write(value); } } privatevoidsetupChat(){ Log.d(TAG,"setupChat()"); //InitializetheBluetoothChatServicetoperformbluetoothconnections mChatService=newBluetoothChatService(this,mHandler); } privatevoidensureDiscoverable(){ if(D) Log.d(TAG,"ensurediscoverable"); if(mBluetoothAdapter.getScanMode()!=BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){ IntentdiscoverableIntent=newIntent( BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra( BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300); startActivity(discoverableIntent); } } //TheHandlerthatgetsinformationbackfromtheBluetoothChatService privatefinalHandlermHandler=newHandler(){ @Override publicvoidhandleMessage(Messagemsg){ switch(msg.what){ caseMESSAGE_STATE_CHANGE: if(D) Log.i(TAG,"MESSAGE_STATE_CHANGE:"+msg.arg1); switch(msg.arg1){ caseBluetoothChatService.STATE_CONNECTED: mTitle.setText(R.string.title_connected_to); mTitle.append(mConnectedDeviceName);// mConversationArrayAdapter.clear(); break; caseBluetoothChatService.STATE_CONNECTING: mTitle.setText(R.string.title_connecting); break; caseBluetoothChatService.STATE_LISTEN: caseBluetoothChatService.STATE_NONE: mTitle.setText(R.string.title_not_connected); break; } break; caseMESSAGE_DEVICE_NAME: //savetheconnecteddevice'sname mConnectedDeviceName=msg.getData().getString(DEVICE_NAME); Toast.makeText(getApplicationContext(), "Connectedto"+mConnectedDeviceName, Toast.LENGTH_SHORT).show(); break; caseMESSAGE_TOAST: Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),Toast.LENGTH_SHORT) .show(); break; } } }; publicvoidonActivityResult(intrequestCode,intresultCode,Intentdata){ if(D) Log.d(TAG,"onActivityResult"+resultCode); switch(requestCode){ caseREQUEST_CONNECT_DEVICE: //WhenDeviceListActivityreturnswithadevicetoconnect if(resultCode==Activity.RESULT_OK){ //GetthedeviceMACaddress Stringaddress=data.getExtras().getString( DeviceListActivity.EXTRA_DEVICE_ADDRESS); //GettheBLuetoothDeviceobject BluetoothDevicedevice=mBluetoothAdapter .getRemoteDevice(address); //Attempttoconnecttothedevice mChatService.connect(device); } break; caseREQUEST_ENABLE_BT: //WhentherequesttoenableBluetoothreturns if(resultCode==Activity.RESULT_OK){ //Bluetoothisnowenabled,sosetupachatsession setupChat(); }else{ //UserdidnotenableBluetoothoranerroroccured Log.d(TAG,"BTnotenabled"); Toast.makeText(this,R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show(); finish(); } } } @Override publicbooleanonCreateOptionsMenu(Menumenu){ MenuInflaterinflater=getMenuInflater(); inflater.inflate(R.menu.option_menu,menu); returntrue; } @Override publicbooleanonOptionsItemSelected(MenuItemitem){ switch(item.getItemId()){ caseR.id.scan: //LaunchtheDeviceListActivitytoseedevicesanddoscan IntentserverIntent=newIntent(this,DeviceListActivity.class); startActivityForResult(serverIntent,REQUEST_CONNECT_DEVICE); returntrue; caseR.id.discoverable: //Ensurethisdeviceisdiscoverablebyothers ensureDiscoverable(); returntrue; } returnfalse; }}bluetoothchatservice.java片段/***Thisthreadrunswhilelisteningforincomingconnections.Itbehaves*likeaserver-sideclient.Itrunsuntilaconnectionisaccepted*(oruntilcancelled).*/privateclassAcceptThreadextendsThread{//ThelocalserversocketprivatefinalBluetoothServerSocketmmServerSocket;publicAcceptThread(){BluetoothServerSockettmp=null;//Createanewlisteningserversockettry{tmp=mAdapter.listenUsingRfcommWithServiceRecord(NAME,MY_UUID);}catch(IOExceptione){Log.e(TAG,"listen()failed",e);}mmServerSocket=tmp;}publicvoidrun(){if(D)Log.d(TAG,"BEGINmAcceptThread"+this);setName("AcceptThread");BluetoothSocketsocket=null;//Listentotheserversocketifwe'renotconnectedwhile(mState!=STATE_CONNECTED){try{//Thisisablockingcallandwillonlyreturnona//successfulconnectionoranexceptionsocket=mmServerSocket.accept();}catch(IOExceptione){Log.e(TAG,"accept()failed",e);break;}//Ifaconnectionwasacceptedif(socket!=null){synchronized(BluetoothChatService.this){switch(mState){caseSTATE_LISTEN:caseSTATE_CONNECTING://Situationnormal.Starttheconnectedthread.connected(socket,socket.getRemoteDevice());break;caseSTATE_NONE:caseSTATE_CONNECTED://Eithernotreadyoralreadyconnected.Terminatenewsocket.try{socket.close();}catch(IOExceptione){Log.e(TAG,"Couldnotcloseunwantedsocket",e);}break;}}}}if(D)Log.i(TAG,"ENDmAcceptThread");}}/***Thisthreadrunsduringaconnectionwitharemotedevice.*Ithandlesallincomingandoutgoingtransmissions.*/privateclassConnectedThreadextendsThread{privatefinalBluetoothSocketmmSocket;privatefinalInputStreammmInStream;privatefinalOutputStreammmOutStream;publicConnectedThread(BluetoothSocketsocket){Log.d(TAG,"createConnectedThread");mmSocket=socket;InputStreamtmpIn=null;OutputStreamtmpOut=null;//GettheBluetoothSocketinputandoutputstreamstry{tmpIn=socket.getInputStream();tmpOut=socket.getOutputStream();}catch(IOExceptione){Log.e(TAG,"tempsocketsnotcreated",e);}mmInStream=tmpIn;mmOutStream=tmpOut;}publicvoidrun(){Log.i(TAG,"BEGINmConnectedThread");byte[]buffer=newbyte[1024];intbytes;//KeeplisteningtotheInputStreamwhileconnectedwhile(true){try{//ReadfromtheInputStreambytes=mmInStream.read(buffer);//SendtheobtainedbytestotheUIActivity}catch(IOExceptione){Log.e(TAG,"disconnected",e);connectionLost();break;}}}/***WritetotheconnectedOutStream.*@parambufferThebytestowrite*/publicvoidwrite(byte[]buffer){try{mmOutStream.write(buffer);//SharethesentmessagebacktotheUIActivity}catch(IOExceptione){Log.e(TAG,"Exceptionduringwrite",e);}}Devicelistactivity.java片段@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);//SetupthewindowrequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);setContentView(R.layout.device_list);//SetresultCANCELEDincasetheuserbacksoutsetResult(Activity.RESULT_CANCELED);//InitializethebuttontoperformdevicediscoveryButtonscanButton=(Button)findViewById(R.id.button_scan);scanButton.setOnClickListener(newOnClickListener(){publicvoidonClick(Viewv){doDiscovery();v.setVisibility(View.GONE);}});//Initializearrayadapters.Oneforalreadypaireddevicesand//onefornewlydiscovereddevicesmPairedDevicesArrayAdapter=newArrayAdapter<String>(this,R.layout.device_name);mNewDevicesArrayAdapter=newArrayAdapter<String>(this,R.layout.device_name);//FindandsetuptheListViewforpaireddevicesListViewpairedListView=(ListView)findViewById(R.id.paired_devices);pairedListView.setAdapter(mPairedDevicesArrayAdapter);pairedListView.setOnItemClickListener(mDeviceClickListener);//FindandsetuptheListViewfornewlydiscovereddevicesListViewnewDevicesListView=(ListView)findViewById(R.id.new_devices);newDevicesListView.setAdapter(mNewDevicesArrayAdapter);newDevicesListView.setOnItemClickListener(mDeviceClickListener);//RegisterforbroadcastswhenadeviceisdiscoveredIntentFilterfilter=newIntentFilter(BluetoothDevice.ACTION_FOUND);this.registerReceiver(mReceiver,filter);//Registerforbroadcastswhendiscoveryhasfinishedfilter=newIntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);this.registerReceiver(mReceiver,filter);//GetthelocalBluetoothadaptermBtAdapter=BluetoothAdapter.getDefaultAdapter();//GetasetofcurrentlypaireddevicesSet<BluetoothDevice>pairedDevices=mBtAdapter.getBondedDevices();//Iftherearepaireddevices,addeachonetotheArrayAdapterif(pairedDevices.size()>0){findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);for(BluetoothDevicedevice:pairedDevices){mPairedDevicesArrayAdapter.add(device.getName()+"\n"+device.getAddress());}}else{StringnoDevices=getResources().getText(R.string.none_paired).toString();mPairedDevicesArrayAdapter.add(noDevices);}}@OverrideprotectedvoidonDestroy(){super.onDestroy();//Makesurewe'renotdoingdiscoveryanymoreif(mBtAdapter!=null){mBtAdapter.cancelDiscovery();}//Unregisterbroadcastlistenersthis.unregisterReceiver(mReceiver);}/***StartdevicediscoverwiththeBluetoothAdapter*/privatevoiddoDiscovery(){if(D)Log.d(TAG,"doDiscovery()");//IndicatescanninginthetitlesetProgressBarIndeterminateVisibility(true);setTitle(R.string.scanning);//Turnonsub-titlefornewdevicesfindView

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论