您好,欢迎来到步遥情感网。
搜索
您的当前位置:首页单片机蓝牙控制小车

单片机蓝牙控制小车

来源:步遥情感网


课 题: 基于单片机的蓝牙控制小车 专 业: 班 级: 学 号: 姓 名: 指导教师: 设计日期: 成 绩:

重庆大学城市科技学院 电气信息学院

课程设计目录

目录

1.设计目的作用 ............................................. 2 2.设计要求 ................................................. 2 3.设计的具体实现 ........................................... 2 3.1设计原理........................................................................................................... 2 3.2系统设计......................................................................................................... 12 3.3系统实现......................................................................................................... 13 4.总结 ................................................... 19 参考文献 ................................................. 20 附录 .................................................... 21 附录1 .............................................................. 21 附录2.................................................................................................................... 22

I

课程设计正文

C51蓝牙控制小车设计报告

1设计目的与意义

目的与意义:提高学生动手能力,培养学生的思维,巩固理论知识,让我们能对单片机更加深入的了解,加深同学们对单片机的认识,通过自己动手让小车跑起来还能让同学们更加有积极性,参与感,成就感。让学生们亲自体验这门课程的神奇性。

因为无线技术的广泛使用,使蓝牙技术的发展成为了趋势之一,蓝牙可以发送和接受语音和数据,满足了大多数人的需求,它也融合了其他相关产品的特点,也是这样技术变得更多样性。实现了无线控制小车,摆脱了有线控制的不方便,更加智能。

2设计要求

SPP 蓝牙串口调试助手 ----》聊天窗口--》

1、在Bluetooth_Car项目中添加超声波躲避障碍功能 (在小车前进的过程中,实时检测障碍物,一旦检测的距离,接近设定的值,触发蜂鸣器,报警系统工作,小车停止前进);

2、在Bluetooth_Car项目中的串口中断服务函数中,添加小车前进的8个方向 ,前后左右,左前,右前,左后,右后;

3、利用外部中断,强制停止小车运行(无论小车现在处于什么状态),蜂鸣器报警1s后,可再运行;

4、用手机的蓝牙串口调试助手来远程操作小车。

3.设计的具体实现

3.1设计原理

芯片常识: STM8、C52 、STM32 、ARM C52:主要做末端的控制 11.0592MHZ STM32:主要做工业控制领域——智能设备 168M ARM:主要做消费市场——手机

2

课程设计正文

==============单片机小车========== 了解原理图和数据手册 一、软件建立工程

建立工程时芯片选择--》Atmel-->ATC52 设置芯片频率,选择生成16进制可执行文件。

=============中断======== 单片机获取外部数据的方式: 1.程序控制方式 a.无条件发送方式

单片机认为外部设备一直都是准备好的,直接就拿数据使用。

b.条件判断方式

在满足一定条件才获取数据。

2.中断方式

由外部控制的,当有中断请求产生的时候,就可以在中断里面去实现获取数据。

3.DMA直接存储控制器

当需要从外界获取数据的时候,DMA可以向CPU申请获取数据,由DMA直接获取数据。使用DMA可以绕过CPU处理数据,降低CPU的使用率。

中断:当CPU正常运行的时候,突然收到一个中断请求(任务),完成中断任务之后立即返回原来的程序继续执行。中断源:中断来源,发送中断的源头

中断请求:中断发出的请求,申请执行任务

中断响应:CPU响应中断请求,暂停正在执行的任务,转而执行中断任务 8个中断源:

INT0 INT1

外部中断0 外部中断1

3

课程设计正文

INT2 INT3 T0 T1 T2

外部中断2 外部中断3 定时器0 定时器1 定时器2

Uart 串口中断

中断有优先级:

分为4级,从0~3,数字越大优先级越高,高优先级的中断可以打断低优先级的中断。 中断的查询次序:

在中断优先级相同的情况下,并且两个中断同时产生的时候,会优先执行查询次序级别高的中断.查询次序不能打断中断. 中断服务函数: { }

小车两轮驱动:

单片机的IO口不能直接驱动电机运行,必须使用驱动模块才可以。

4

void INT1_func(void) interrupt 2

if()

课程设计正文

电机转动原理:

电机的两条线一根接电源正极,一根接负极就可以转动,当电极的方向改变,转动的方向也会改变。

BIA = 1; BIB = 0;

控制右轮电机,如果想让轮子转动,只需要设置以上两个引脚,一个为1,一个为0.

P0.0 左轮 1 P0.1 左轮 0 P0.2 右轮 1 P0.3 右轮 0

如果轮子想要动起来,需要接电源线。 思考:

封装函数:前进、后退、停止、左前转、右前转、左后转、右后转 =============定时器============== 定时器就是定时,定时产生中断或者是计数。 工作方式:

定时器:主要产生定时中断 计数器:计时计数 工作模式:

模式0:12位寄存器 模式1:16位寄存器

模式2:8位自动重装载寄存器 模式3:两个8位寄存器,T1无效 时钟周期:就是频率的倒数

5

课程设计正文

假设晶振12M,时钟周期是1/12us,实际上大多使用的是:1/11.0592 状态周期:

状态周期是时钟周期的两倍:1/12*2 机器周期:

12个时钟周期定为1个机器周期,如果晶振是12M,那么一个机器周期就刚好是1us。 寄存器:

TCON 控制寄存器 TMOD 模式寄存器 定时器0作模式1: TMOD.1 = 0 TMOD.0 = 1

设置寄存器计数的初值:TL0和TH0

50ms = (65536-初值)* (1/11.0592*12) 50000us = (65536-初值 ) * 1.08507 46080 = 65536-初值 初值 = 19456 ==》 0x4C00 TH0 = 0x4C; TL0 = 0x00;

=============串口============== 一、计算机内部通讯的方式:

UART(串口)、I2C、SPI、1-Write(单总线) 二、数据通讯方式

并行通讯:多个任务同时进行,增加速度。

6

课程设计正文

串行通讯:数据只通过一根数据线传输,一位一位的传输数据。 三、串行通讯

同步通讯:发送一位数据必须要接收一位数据,通过时钟线确定数据收发:

I2C、SPI

异步通讯:可以收发数据,不需要发送数据的时候接收数据。:串口UART、1w总线

单工:只能一方发送数据,一方接收数据(收音机)

半双工:同一时刻只能一方发送数据,一方接收数据,但是方向可以转换。(对讲机)

全双工:数据在同一时刻可以收也可以发。(电话) 四、电平特性

TTL和RS232

TTL:0V~5V 0V表示数据0 3.3V/5V表示数据1

RS232:-15V~+15V 3V~15V表示数据0 -15V~-3V表示数据1 单片机直接使用的是TTL电平:

VCC正极; GND负极; TXD数据发送; RXD数据接收 五、串行通讯的协议

7

课程设计正文

六、单片机串口寄存器

SCON控制寄存器

串口选择方式1,8位UART,波特率可变。 设置SCON寄存器:

SCON = // 0101 0000 ==》 0x50 PCON电源管理寄存器,设置SMOD的值

8

课程设计正文

SMOD默认值就是0,也可以主动设置为0. 设置好之后需要开启总中断:

EA = 1;

串口波特率计算:

波特率 = (2^SMOD /32)* (定时器溢出率) 9600 = (1 /32)* (11059200/12/(256-TH1)) 9600 = (1 /32)* (921600/(256-TH1)) 921600/(256-TH1) = 307200 (256-TH1) = 3 TH1 = 253 ==> 0xFD 串口发送数据

SUBF = 'h'; // 发送数据,还要判断是否发送 3.2系统设计 项目框图:

ES = 1;

9

课程设计正文

3.3系统实现

程序代码如下: #include #include #define uint unsigned int #define uchar unsigned char #define LCM_Data P2

#define Busy 0x80 //用于检测LCM状态字中的Busy标识 sbit RX = P1^1 sbit TX = P1^2

; ;

//器件配置文件

sbit LCM_RW = P0^3; //定义LCD引脚 sbit LCM_RS = P0^4; sbit LCM_E = P0^2;

sbit FM = P0^7; //定义蜂鸣器 sbit AIA = P2^3; //定义电机 sbit AIB = P2^2; sbit BIB = P2^1; sbit BIA = P2^0; void LCMInit(void);

void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData); void Delay5Ms(void); void Delay400Ms(void);

void Decode(unsigned char ScanCode); void WriteDataLCM(unsigned char WDLCM);

void WriteCommandLCM(unsigned char WCLCM,BuysC); void SendOneByte(unsigned char c); unsigned char ReadDataLCM(void); unsigned char ReadStatusLCM(void);

unsigned char code mcustudio[] ={\"YueQian \unsigned char code email[] = {\"www.gec-edu.org \unsigned char code Cls[] = {\" \

unsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-','M'};

10

课程设计正文

static unsigned char DisNum = 0; //显示用指针 unsigned int time=0; unsigned long S=0; bit flag =0; unsigned char disbuff[4] void Init_Int1(void) {

IT1 = 1; //下降沿触发 EX1 = 1; //开启外部中断1 EA = 1; //开启总中断 }

void delay_ms(uint x) //延时函数 { uint i; while(x--) { } }

void car_go() //控制小车的函数 前进 {

AIA = 1; //运用电机的电位差来控制小车的前进方向 AIB = 0; BIA = 1; BIB = 0; }

void car_back() //后退 { AIA = 0; AIB = 1; BIA = 0; BIB = 1; }

void right() //右转

for(i=0;i<133;i++);

={ 0,0,0,0,};

11

{ AIA = 1; AIB = 0; BIA = 1; BIB = 1; }

void left() //左转 { AIA = 1; AIB = 1; BIA = 1; BIB = 0; }

void go_right() //右转前进 { AIA = 1; AIB = 0; BIA = 1; BIB = 1; delay_ms(500); AIA = 1; AIB = 0; BIA = 1; BIB = 0; }

void go_left() //左转前进 {

AIA = 1; AIB = 1; BIA = 1; BIB = 0; delay_ms(500); AIA = 1;

课程设计正文

12

AIB = 0; BIA = 1; BIB = 0; }

void back_right() //右转后退 { AIA = 1; AIB = 1; BIA = 1; BIB = 0; delay_ms(500); AIA = 0; AIB = 1; BIA = 0; BIB = 1; }

void back_left() //左转后退 { AIA = 1; AIB = 0; BIA = 1; BIB = 1; delay_ms(500); AIA = 0; AIB = 1; BIA = 0; BIB = 1;

}

void WriteDataLCM(unsigned char WDLCM) {

ReadStatusLCM(); //检测忙 LCM_Data = WDLCM; LCM_RS = 1; LCM_RW = 0;

课程设计正文

//写数据 13

课程设计正文

LCM_E = 0; //若晶振速度太高可以在这后加小的延时 LCM_E = 0; //延时 LCM_E = 1; }

void WriteCommandLCM(unsigned char WCLCM,BuysC) //写指令 BuysC为0时忽略忙检测

{

if (BuysC) ReadStatusLCM(); //根据需要检测忙 LCM_Data = WCLCM; LCM_RS = 0; LCM_RW = 0;

LCM_E = 0; LCM_E = 0; LCM_E = 1; }

unsigned char ReadDataLCM(void) //读数据 {

LCM_RS = 1; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; return(LCM_Data); }

unsigned char ReadStatusLCM(void) //读状态 {

LCM_Data = 0xFF; LCM_RS = 0; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1;

while (LCM_Data & Busy); //检测忙信号 return(LCM_Data); }

14

课程设计正文

void LCMInit(void) //LCM初始化 {

LCM_Data = 0;

WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号 Delay5Ms();

WriteCommandLCM(0x38,0); Delay5Ms();

WriteCommandLCM(0x38,0); Delay5Ms();

WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号 WriteCommandLCM(0x08,1); //关闭显示 WriteCommandLCM(0x01,1); //显示清屏

WriteCommandLCM(0x06,1); // 显示光标移动设置 WriteCommandLCM(0x0F,1); // 显示开及光标设置 }

//按指定位置显示一个字符

void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData) {

Y &= 0x1;

X &= 0xF; //X不能大于15,Y不能大于1 if (Y) X |= 0x40; //当要显示第二行时地址码+0x40; X |= 0x80; //算出指令码 WriteCommandLCM(X, 1); //发命令字 WriteDataLCM(DData); //发数据 }

//按指定位置显示一串字符

void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData) {

unsigned char ListLength; ListLength = 0; Y &= 0x1;

X &= 0xF; //X不能大于15,Y不能大于1 while (DData[ListLength]>0x19) //若到达字串尾则退出

{

15

课程设计正文

}

void Delay5Ms(void) //5ms延时 {

unsigned int TempCyc = 5552; while(TempCyc--); }

void Delay400Ms(void) //400ms延时 {

unsigned char TempCycA = 5; unsigned int TempCycB; while(TempCycA--) }

/**************超声波测距函数*************************/ void Conut(void) {

time=TH0*256+TL0; TH0=0; TL0=0;

S=(time*1.87)/100; //算出来是CM /*

晶振为11.0592MHz时

|t(us) = 计数 * (12/11.0592) * (1/58)

{ };

TempCycB=7269; while(TempCycB--); }

if (X <= 0xF) //X坐标应小于0xF

{ }

DisplayOneChar(X, Y, DData[ListLength]); /显示单个字符 ListLength++; X++;

16

课程设计正文

| = 计数 * 0.0187 | = (计数 * 1.87)/100 */

if((S>=700)||flag==1) //超出测量范围显示“-” {

flag=0;

DisplayOneChar(0, 1, ASCII[11]); DisplayOneChar(1, 1, ASCII[10]); DisplayOneChar(2, 1, ASCII[11]); DisplayOneChar(3, 1, ASCII[11]); DisplayOneChar(4, 1, ASCII[12]); } else {

disbuff[0]=S%1000/100; disbuff[1]=S%1000%100/10; disbuff[2]=S%1000%10 %10;

DisplayOneChar(0, 1, ASCII[disbuff[0]]); DisplayOneChar(1, 1, ASCII[10]);

//显示点 //显示M //显示点

DisplayOneChar(2, 1, ASCII[disbuff[1]]); DisplayOneChar(3, 1, ASCII[disbuff[2]]); DisplayOneChar(4, 1, ASCII[12]); } }

/********************************************************/ /*********** 定时器T0中断服务函数 ***********/

void Timer0IRQ() interrupt 1 //T0中断用来计数器溢出,超过测距范围 {

flag=1; }

/********************触发超声波模块************************************/ //超声波模块Trig控制端给大于10us的高电平触发模块测距

//显示M

17

课程设计正文

void StartModule() { TX=1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); TX=0; }

/********************************************************/ void delayms(unsigned int ms) {

unsigned char i=100,j; for(;ms;ms--) {

while(--i) {

//启动一次模块 //启动模块

18

课程设计正文

} }

/******************************/

void SendOneByte(unsigned char c) //发送单个字符 {

SBUF = c; while(!TI); TI = 0; }

/*********************************************************/ void main(void) {

unsigned char TempCyc;

Delay400Ms(); //启动等待,等LCM讲入工作状态 LCMInit(); //LCM初始化 Delay5Ms(); //延时片刻(可不要) DisplayListChar(0, 0, mcustudio); DisplayListChar(0, 1, email);

ReadDataLCM(); //测试用句无意义 for (TempCyc=0; TempCyc<10; TempCyc++) Delay400Ms(); //延时 DisplayListChar(0, 1, Cls); FM = 1;

//设T0为方式1;

}

j=10; while(--j);

// TMOD=0x01; // TH0=0;

// TL0=0;

// ET0=1; //允许T0中断 // EA=1;

//开启总中断

TMOD=0x21; //设T0为方式1,定时器1方式2; // 0010 0001

19

课程设计正文

SCON=0x50; TH1=0xFD; TL1=0xFD; TH0=0; TL0=0; TR0=1;

ET0=1; //允许T0中断 TR1=1; TI=1; ES = 1; EA=1; Init_Int1(); while(1) {

StartModule();

// DisplayOneChar(0, 1, ASCII[0]);

//当RX为零时等待

//开启计数 //当RX为1计数并等待

//关闭计数

//开启总中断

//开启定时器

while(!RX); TR0=1; while(RX); TR0=0; Conut();

FM = 1; AIA = 1; AIB = 1; BIA = 1;

//计算

BIB = 1;

//超声波测距 检测 if(S<20) {

FM = 0; AIA = 1; AIB = 1; BIA = 1; BIB = 1;

20

} else

FM =1;

delayms(80);

//80MS

} }

void UARTInterrupt(void) interrupt 4 {

unsigned char buf; if(RI) {

RI = 0;

//add your code here! buf = SBUF; //作回显没有任何作用 SendOneByte(buf); if(buf == '1') { car_go(); delay_ms(1000);

}

else if(buf == '2') { car_back(); delay_ms(1000); }

else if(buf == '3') { right(); delay_ms(1000); }

else if(buf == '4') {

left();

课程设计正文

21

delay_ms(1000);

} else if(buf == '5') { go_right(); delay_ms(1000);

}

else if(buf == '6') { go_left(); delay_ms(1000);

}

else if(buf == '7') { back_right(); delay_ms(1000);

}

else if(buf == '8') { back_left(); delay_ms(1000);

}

} else TI = 0; }

void Int1_Routine(void) interrupt 2 { EX1 = 0; AIA = 1; AIB = 1; BIA = 1; BIB = 1; FM = 0;

课程设计正文

22

课程设计正文

delay_ms(500); FM = 1; EX1 = 1; }

总结

学习单片机要有一定的c语言基础,单片机的基础知识我还是多多少少知道一些,可是让我直接来做这一个项目,我却无从下手。通过老师的细心讲解,我大概知道了大概框架和流程,再通过同学们的帮助更加了解和熟悉的掌握了其知识。

首先这次单片机课程设计对我的收获还是非常的大,我的c语言方面的知识掌握程度有所提升,这次给我们上课的不是学校的老师,而是公司里面的直系工程师,通过他的教学,让我明白了以后出身社会不努力学习是无法立足的。 从最开始的点灯,到中断,后来的让轮子动起来。也是一步比一步的难,可是我不怕困难,有问题就请教。其实世界上难倒我们的不是问题本身,而是不去解决问题的懒惰。

点灯:我们使用的是低电平有效,硬件的一个字节的变量是8位。中断:中断方式是由外部控制的,老师让我们练习了一个程序,“按键中断实现:按键1按下数码管的数字增加1,按键2按下数码管的数字减少1”。紧接着是让小车的轮子动起来,要使轮子动起来就需要控制电机,控制电机的引脚为P0口,如果要控制左轮,就需要使引脚一个为1,一个为0。而且轮子要转起来还需要接电源线。定时器就是定时,定时产生中断或者是计数,我们练习的是定时器0的方式1。最后讲的串口,单片机直接使用的是TTL电平:VCC正极、GND 负极、TXD数据发送、RXD 数据接收。串口编程的实现:初始化SCON、PCON、EA、ES、TMOD 定时器1 方式2、TR1、TH1、TL1。

这次课程设计的题目十分全面,把我们知道的不知道的都运用到了其中,其中也遇到很多问题。特别是那个蓝牙模块,很多都是坏的,只有我们一个一个去试。

写出的程序,经过不断地调试,最终完成。蓝牙需要设计成按键控制,所以要在程序中进行按键设计case,设计要求,转弯时要亮灯,我开始做出来时,灯不亮,是因为我没有加延时,加上延时就可以亮了。其中还有一个要求是后退时,蜂鸣器响两声,我用亮灯同样的方法,蜂鸣器就一直响,我就把P0^7单独定义为k,对k给1或0,还单独写了void feng(),专门控制蜂鸣器响两声,最终我成功了。

23

课程设计正文

这次单片机的课程设计非常的nice,让我收获很大,也希望以后有更多的这样的机会,我也会努力去学习,去克服这些有趣的难题。

24

课程设计正文

参考文献

[1]黄青颖.单片机课程项目化教学探索[J].山东工业技术,2018(24):232+196.

[2]王瑜,宋文学,杨武成,孙俊茹.基于STCC52单片机的多通道扭矩无线传输系统设计[J].电子设计工程,2018(22):185-1.

[3]杨宇翔. 单片机串行接口工作方式[N]. 电子报,2018-11-18(009).

[4]邓春. PLC和单片机的区别[N]. 电子报,2018-11-11(009).

[5]张跃博,王亚丽.基于MSP430F5529单片机的蓝牙遥控小车[J].信息系统工程,2016(07):40.

[6]马惠兰.基于单片机的蓝牙搜救小车设计[J].工业仪表与自动化装置,2016(03):111-114.

[7]卢胜昌.基于STC12C5A60S2单片机无线蓝牙智能追踪小车[J].电子技术与软件工程,2015(01):261.

[8]谈敏,刘高平,陈红良.基于手机蓝牙接口的小车遥控系统[J].浙江万里学院学报,2012,25(04):77-80.

25

课程设计附录

附录

附录1

26

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- obuygou.com 版权所有 赣ICP备2024042798号-5

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务