———————————————————————————————— 作者: ———————————————————————————————— 日期:
单片机大作业
“基于单片机的蓝牙遥控小车”
姓名:
班级:通信工程卓越2014-1
学号:
在班编号:
基于单片机的蓝牙遥控小车
目录
第一章 绪论1ﻩ
1.1 研究背景和意义 .................................................................... 1
第二章 系统框架及软硬件结构设计 .................................................... 2
2.1 系统要求2ﻩ
2.2 系统整体算法流程2ﻩ
2.3 总体任务设计 .......................................................................... 3 2.4 整体硬件结构设计 .................................................................. 4 2.5 整体软件结构设计4ﻩ
第三章 模块的详细设计 ........................................ 错误!未定义书签。
3.1 L293D电机驱动模块 .......................................................... 5
3.1.1模块介绍ﻩ5
3.1.2 PWM脉冲控制原理ﻩ6 3.1.3 脉冲控制代码6ﻩ
3.2 HC05蓝牙模块 ................................................................... 7
3.2.1 模块简介ﻩ7
3.2.2 蓝牙串口程序说明 .............................................. 8
3.2.3 模块引脚说明8ﻩ
3.3 USB转TTL模块9ﻩ
第四章 系统功能设计与实现 ................................................................ 11
4.1 安卓手机蓝牙遥控的设计与实现 ...................................... 11
4.1.1 设计基本思路11ﻩ 4.1.2 遥控任务分配1ﻩ1
4.2.3 蓝牙遥控操作流程 ............. 错误!未定义书签。
第五章 软硬件调试14ﻩ
5.1 硬件调试 ......................................................................... 14 5.2 软件调试ﻩ14
第一章 绪论
1.1 研究背景和意义
智能化无处不在。各种智能化设备在不同的领域中发挥着自己的特长,而在家用方面的智能有着相当重要的意义。
本次所设计的智能小车系统包含着对周围环境的检测、舵机控制以及短距离无线遥控等的功能,它需要实现微控制器、多传感器技术、蓝牙遥控、机械结构原理、数字逻辑、自动控制等各学科技术内容的渗透融合。智能小车通过其上部搭载的89C52芯片作为核心控制器,通过多种传感器来获取周围环境信息并将采集到的信息输送给CPU,然后由CPU来给各个部分下达相对应的指令。智能小车不仅价格低廉,而且甚至能够担任人类难以从事的任务,它在工业、农业以及社会生产生活等许多领域都起到了重要作用。本次课题设计中所采用到的短距离无线遥控、单片机控制原理、多传感器技术、自动避障技术等等。现在在工业制造、农业生产、国家安全、军事武器,医疗保健、太空探测等许多领域都日益发挥着其作用,在军事侦察、反恐、防暴、防核化等高危任务方面、环境污染检测方面和在恶劣环境中均有着非常好的发展前景,从这些方面可知本课题研究意义非凡。
第二章 系统框架及软硬件结构设计
2.1 系统要求
在综合考量了单片机的使用性能、成本和时间等问题,本次课题主要旨在实现以下性能指标:
1)根据力学结构完成小车整体框架的搭建,稳固其整体重心; 2)完成底层运动系统的搭建,保证小车能够正常行进; 3)完成小车自主避障功能,能够在简单地形避开障碍物; 4)完成小车的简单路径规划;
5)完成手机遥控功能,通过手机控制底层小车的工作方式。
整体小车车身采用深圳欧鹏公司设计生产的金属框架,通过自己的设计和搭建,完成底层硬件系统的搭载,再通过上层安卓手机APP遥控,通过无线蓝牙通信协议,实现小车能够遵从指令实现在室内的自主避障的巡航功能与手机遥控功能,整体电路图如图所示
图2-1 系统整体电路设计
2.2 系统整体算法流程
整个系统的算法结构具体流程如图2-1所示。
图2-2 系统整体算法流程图
2.3 总体任务设计
小车总体任务分配如下图2-2所示。 按键1 前进 按键2 后退 按键3 左转 按键4 右转 按键5 第一档 按键6 第二档 按键7 第三档 按键8 停止 蓝牙遥控按键任务选择 STC89C52
图2-3 小车任务分配
2.4 整体硬件结构设计
智能小车系统整体硬件结构以89C51单片机为中心主要分为以下几个部分:
1)运动结构,即舵机模块是整个系统的基础,通过对舵机性能参数的测定对舵机进行标定、控速;
2)供电结构,采用分压式供电。由于各,模块对电压的要求不同,所以需要通过分压以适应不同模块对电压的需求。其中舵机需要8v电压的供应,而单片机、传感器、蓝牙等模块则需要较低一点的电压5v供电;
3)无线通信结构,通过对蓝牙模块与单片机通信电路的设计与单片机串口功能的调试,做到小车与手机的无线通信。 小车实物图如下图2-3所示。
图2-4 小车实物图
2.5 整体软件结构设计
当启动电源系统初始化完成后,小车进入等待的任务模式,等待上层安卓终端手机的APP客户端发送任务指令。小车接收到上层手机发送的小车行进方向的指令后相对应的前进(forward)、后退(backward)、左转(left)、右转(right)、停止(stop)等。
第三章 模块的详细设计
3.1 L293D电机驱动模块
3.1.1模块介绍
L293D采用16引脚DIP封装,其内部集成了双极型H-桥电路,所有的开量都做成n型。这种双极型脉冲调宽方式具有很多优点,如电流连续;电机可四角限运行;电机停止时有微振电流,起到“动力润滑”作用,消除正反向时的静摩擦死区:低速平稳性好等。L293D通过内部逻辑生成使能信号。H-桥电路的输入量可以用来设置马达转动方向,使能信号可以用于脉宽调整(PWM)。另外,L293D将2个H-桥电路集成到1片芯片上,这就意味着用1片芯片可以同时控制2个电机。每1个电机需要3个控制信号EN12、IN1、IN2,其中EN12是使能信号,IN1、IN2为电机转动方向控制信号,IN1、IN2分别为1,0时,电机正转,反之,电机反转。选用一路PWM连接EN12引脚,通过调整PWM的占空比可以调整电机的转速。选择一路I/O口,经反向器74HC14分别接IN1和IN2引脚,控制电机的正反转。实物图如下图3-1所示。
图3-1 模块实物图
3.1.2 PWM脉冲控制原理
所谓PWM就是脉宽调制器,通过调制器给电机提供一个具有一定频率的脉冲宽度可调的脉冲电。脉冲宽度越大即占空比越大,提供给电机的平均电压越大,电机转速就高。反之脉冲宽度越小,则占空比越越小。提供给电机的平均电压越小,电机转速就低。
PWM不管是高电平还是低电平时电机都是转动的,电机的转速取决于平均电压。
3.1.3 脉冲控制代码
ﻫvoid T0_time() interrupt 1 //定时器1中断程序 {
ﻩﻩPWMCnt1++; ﻩ
PWMCnt2++; ﻩ{
if(PWMCnt1 >= 200)
ﻩﻩ PWMCnt1 = 1; ﻩ
}
ﻩif(PWMCnt1 <= cntPWM1)ﻩ//230
ﻩﻩ{
ﻩﻩ PWM1 = 1; ﻩ ﻩ
ﻩ{
ﻩﻩPWM1 = 0; }
} else
if(PWMCnt2 >= 200)
{
ﻩ ﻩ ﻩﻩ}
{
PWMCnt2 = 1; }
ﻩif(PWMCnt1 <= cntPWM2)230//ﻩ
PWM2 = 1;
ﻩﻩ else ﻩ ﻩ
{
PWM2 = 0;
ﻩﻩ} }
TH0 = (65536 - 50) / 256; TL0 = (65536 - 50) % 256;
3.2 HC05蓝牙模块
3.2.1 模块简介
HC-05蓝牙无线通信模块有两种工作方式,一个是命令响应工作模式,另一个是自动连接工作模式。在命令响应工作模式下,使用者通过向模块发送AT工作指令来对模块的控制参数进行设定和下达控制指令。而在自动连接工作模式下, 模块又有三种工作模式,分别为主机(Master)、从机(Slave)和回环(Loopback)三种工作模式,选定工作模式后,模块就自动按照提前设定好的方式进行数据传输。通过调节模块外部引脚的输入电平来动态转换模块的工作状态。模块实物图如图3-5所示。
图3-2 HC05实物图
3.2.2 蓝牙串口程序说明
void usart_receive(void) interrupt 4 //串口中断程序 {
if(RI == 1)//收到字符 {
RI = 0;//软件清零
bluetoothdata = SBUF;//读取数据 }
if(TI == 1)//发送数据 {
TI = 0;//清零 } }
3.2.3 模块引脚说明
模块引脚说明及电路原理图如下图3-6、3-7所示。
图3-3 模块引脚说明
图3-4 HC05原理图
3.3 USB转TTL模块
本次课题需要通过使用串口调试软件使得上位机与底层小车进行通信达到调试小车的目的,但是目前笔记本电脑因为空间的限制和其他方面考虑的原因都没有串口,所以需要使用到这一个USB转串口模块。
模块与单片机需要按下图3-8所示相连接。
HC05
图3-5 USB转TTL模块与单片机的连接示意图
单 片
图3-6 USB转TTL串口模块实物图
。
第四章 系统功能设计与实现
4.1 安卓手机蓝牙遥控的设计与实现
4.1.1 设计基本思路
遥控功能的实现基于蓝牙通信协议的建立,需要从依次实现以下几个步骤:
1)检测HC05蓝牙模块是否能够正常工作,将蓝牙模块按要求接上5v或3.3v电压,等待一段时间后,使用安卓终端搜索,查看蓝牙模块是否能够被搜索并与其相连接;
2)单片机串口能否正常通信,编写好串口通信程序并将其烧录字单片机中,将单片机通过开发板与电脑串口连接,打开电脑端串口调试工具查看是否能够正常通信;
3)查看蓝牙模块是否能够正常发送和接收数据,将蓝牙模块通过USB转TTL模块与电脑USB口相连,打开电脑串口调试助手。安装好手机APP,与蓝牙模块连接好后,使用手机端APP查看是否能够正常发送和接收数据;
4)将蓝牙模块的串口与智能小车上的单片机串口相连,并编写好遥控选择功能代码,使用手机发送数据,查看智能小车能否执行相应的的指令。
下图为电脑端的串口调试助手。
图4-1 串口调试工具
4.1.2 遥控任务分配
通过无线蓝牙通信的实现,上层安卓终端主要可以实现以下小车的行进方向,进入的工作模式等,具体功能如下表所示。
表4-2 蓝牙遥控按键及选择功能表
按键 功能 F 前进 B 后退 S 停止 L 左转 R 右转 1 2 3 第一档 第二档 第三档 4.2.3 蓝牙遥控操作流程
蓝牙遥控操作流程示意图如下。
图4-3 蓝牙遥控流程图
首先将智能小车正常上电工作,待小车初始化完成后,打开安卓终端的APP进行连接,连接成功后即可选择功能。可按avoid键进入自主避障模式,如需进入遥控模式则仅需按back键返回上一层。
图4-4 蓝牙模块连接示意图
图4-5 安卓终端APP界面
第五章 软硬件调试
5.1 硬件调试
硬件调试采用从整体到部分的考量方法。
1)智能小车整体框架的搭建,确保各模块能够搭载在其上面而相互没有影响; 2)完成整体电源电路、工作电路的设计,保证各模块之间供电正常使用和与单片机之间的合理连接;
3)烧录测试程序,保证单片机能够正常进行烧录和擦除程序,同时还需要测试其串口功能,实现单片机与手机之间的正常通信;
4)小车底层运动系统的完成,测试舵机的基本性能,保证其能正常工作;
5)对HC05蓝牙模块进行基本性能测试,保证其在正常工作电压下能够正常工作。再通过上位机的测试,确保其能够正常的收发数据。
5.2 软件调试
1)通过编写代码实现对底层小车的驱动,包括舵机参数的测定,电机的标定,对电机进行速度调控,实现小车的方向控制;
2)避障算法的设计,通过考量3个传感器将出现的8种情况(000、001、010、011、100、101、110、111),考虑每一种情况出现时的应对方式,设计出较为合理的避障算法,并将传感器采集的数据与舵机控制结合起来,实现智能小车的避障功能;
3)蓝牙模块与单片机、上位机、上层安卓终端的正常通信。先使用上位机端的串口调试工具测试蓝牙模块是否能够正常与上位机之间进行正常通信,然后编写串口调试代码烧录至单片机,使用手机发送数据确保单片机能够接收指令并命令小车作出相应反应;
4)选择功能算法设计,设计出简洁合理的算法,使得小车在初始化完成后操作者使用APP能够选择相应功能,进入自主避障模式或者是手机的蓝牙遥控模式;
5)将舵机驱动代码、小车避障算法和选择功能算法有机结合起来,使得小车的功能完善,各个模块能够独立工作完成各自任务,并且有效率的执行小车的工作。
代码
#include <reg52.h>
sbit PWM1 = P2^0;//PWM波产生的端口 sbit PWM2 = P2^1;
sbit motor_control_1 = P2^7;//左轮控制 sbit motor_control_2 = P2^6;// sbit motor_control_3 = P2^5; sbit motor_control_4 = P2^4;//
unsigned int PWMCnt1 = 0; unsigned int cntPWM1 = 60; unsigned int PWMCnt2 = 0; unsigned int cntPWM2 = 60;
unsigned char bluetoothdata; void initial_myself(); void initial_interrupt(); void usart_service(void); void delay_long(unsigned int time); void go_forward(void);// void stop();
void turn_right(); void turn_left(); void back();
void main() {
initial_myself(); delay_long(100); initial_interrupt();
stop();
while(1) {
usart_service(); } }
void usart_service() { ﻩ{ ﻩ
case 'f':go_forward(); ﻩdelay_long(100);
SBUF = 'f';//返回数据到手机 switch(bluetoothdata)
ﻩﻩbluetoothdata = 'a'; ﻩﻩbreak; ﻩ ﻩ ﻩ ﻩ ﻩ
case 'r':turn_right(); delay_long(100); SBUF = 'r';
case 's':stop(); delay_long(100); SBUF = 's';
ﻩbluetoothdata = 'a';
ﻩﻩbreak;
ﻩﻩbluetoothdata = 'a'; ﻩﻩbreak; ﻩ ﻩ ﻩ ﻩ
case '1':cntPWM1 = 60; cntPWM2 = 60;
SBUF = '1'; ﻩcase 'b':back(); ﻩdelay_long(100);
SBUF = 'b'; bluetoothdata = 'a'; ﻩbreak;
case 'l':turn_left();
delay_long(100);
ﻩﻩSBUF = 'l';
ﻩbluetoothdata = 'a'; break;
ﻩﻩdelay_long(100);
ﻩ
bluetoothdata = 'a';
break;
ﻩﻩcase '2':cntPWM1 = 100; ﻩ
cntPWM2 = 100; ﻩdelay_long(100);
SBUF = '2';
ﻩﻩbluetoothdata = 'a'; ﻩﻩbreak;
ﻩﻩcase '3':cntPWM1 = 140; ﻩﻩcntPWM2 = 140; ﻩ ﻩ ﻩ }
void usart_receive(void) interrupt 4 //串口中断程序 {
if(RI == 1)//收到字符 {
RI = 0;//软件清零
bluetoothdata = SBUF;//读取数据 }
if(TI == 1)//发送数据 {
TI = 0;//清零 } }
void T0_time() interrupt 1 //定时器1中断程序
}
ﻩdelay_long(100); SBUF = '3';
bluetoothdata = 'a'; break;
{ ﻩ ﻩ ﻩ ﻩ ﻩﻩ} ﻩ ﻩ ﻩﻩ} ﻩﻩ ﻩﻩ{ ﻩﻩ} ﻩﻩ{
PWM2 = 0;
ﻩﻩ}
ﻩﻩTH0 = (65536 - 50) / 256; }
void initial_myself() {
TMOD = 0x01;//
TH0 = (65536 - 50) / 256;//定时50微秒 TL0 = (65536 - 50) % 256;
TL0 = (65536 - 50) % 256; ﻩ ﻩ} ﻩ else
if(PWMCnt1 <= cntPWM2)ﻩ//230 {
ﻩPWMCnt2 = 1;
if(PWMCnt2 >= 200) else { ﻩ
PWM1 = 0; }
if(PWMCnt1 <= cntPWM1) //230 {
ﻩﻩPWM1 = 1;
PWMCnt1++; if(PWMCnt1 >= 200)
PWMCnt1 = 1;
PWMCnt2++;
ﻩﻩ{
ﻩﻩPWM2 = 1;
//
ﻩSCON = 0x50; TMOD = 0x21;
TH1 = TL1 = 0xfd;//设置波特率9600 IP = 0x10;//设置串口中断为高优先级 }
void initial_interrupt() {
EA = 1;// 开总中断 ES = 1;// 开串口中断 ET0 = 1;//开定时器0中断? TR0 = 1;//开定时器0 TR1 = 1;// 开定时器1 }
void delay_long(unsigned int time) {
unsigned int i; unsigned int j;
for(i = 0 ; i < time ; i++) {
ﻩfor(j = 0; j < 500; j++); } }
void go_forward() {
motor_control_1 = 0; motor_control_2 = 1; }
motor_control_3 = 0; motor_control_4 = 1;
void stop() {
ﻩmotor_control_1 = 0;
motor_control_2 = 0; ﻩmotor_control_3 = 0; motor_control_4 = 0; }
void turn_left() {
ﻩint i=5000; ﻩ{ ﻩ ﻩ ﻩ
ﻩif(i) ﻩ{
ﻩ motor_control_2 = 0; ﻩmotor_control_3 = 0; motor_control_4 = 1; { ﻩ
motor_control_1 = 0; else for(;i>=0;i--)
ﻩﻩ ﻩmotor_control_1 = 0;
ﻩﻩ}
ﻩﻩﻩmotor_control_2 = 0; ﻩﻩﻩmotor_control_3 = 0; ﻩ }
void turn_right() { ﻩ{
if(i) int i=5000; ﻩfor(;i>=0;i--)
motor_control_4 = 0;ﻩ ﻩ} }
ﻩ ﻩ ﻩ ﻩ ﻩ ﻩﻩ} }
{
ﻩmotor_control_2 = 1;
ﻩﻩ motor_control_1 = 0;
ﻩﻩmotor_control_3 = 0; motor_control_4 = 0; } ﻩelse ﻩ{
ﻩmotor_control_1 = 0; motor_control_3 = 0; ﻩmotor_control_2 = 0; motor_control_4 = 0; }
void back() {
motor_control_1 = 1; motor_control_2 = 0; }
motor_control_3 = 1; motor_control_4 = 0;
因篇幅问题不能全部显示,请点此查看更多更全内容