当前位置:文档之家› 单片机蓝牙控制小车

单片机蓝牙控制小车

课题:基于单片机得蓝牙控制小车专业:班级:学号:姓名:指导教师:设计日期:成绩:重庆大学城市科技学院电气信息学院目录1、设计目得作用 (2)2、设计要求.............................................. 23、设计得具体实现ﻩ23、1设计原理 (2)3、2系统设计12ﻩ3、3系统实现13ﻩ4、总结19ﻩ参考文献................................................ 20附录 ................................................... 21附录121ﻩ附录22ﻩ2C51蓝牙控制小车设计报告1设计目得与意义目得与意义:提高学生动手能力,培养学生得思维,巩固理论知识,让我们能对单片机更加深入得了解,加深同学们对单片机得认识,通过自己动手让小车跑起来还能让同学们更加有积极性,参与感,成就感.让学生们亲自体验这门课程得神奇性。

因为无线技术得广泛使用,使蓝牙技术得发展成为了趋势之一,蓝牙可以发送与接受语音与数据,满足了大多数人得需求,它也融合了其她相关产品得特点,也就是这样技术变得更多样性。

实现了无线控制小车,摆脱了有线控制得不方便,更加智能。

2设计要求SPP蓝牙串口调试助手---—》聊天窗口-—》1、在Bluetooth_Car项目中添加超声波躲避障碍功能(在小车前进得过程中,实时检测障碍物,一旦检测得距离,接近设定得值,触发蜂鸣器,报警系统工作,小车停止前进);2、在Bluetooth_Car项目中得串口中断服务函数中,添加小车前进得8个方向 ,前后左右,左前,右前,左后,右后;3、利用外部中断,强制停止小车运行(无论小车现在处于什么状态),蜂鸣器报警1s后,可再运行;4、用手机得蓝牙串口调试助手来远程操作小车。

3、设计得具体实现3、1设计原理芯片常识: STM8、C52 、STM32 、ARMC52:主要做末端得控制11、0592MHZSTM32:主要做工业控制领域--智能设备168MARM:主要做消费市场——手机==============单片机小车==========了解原理图与数据手册一、软件建立工程ﻩ建立工程时芯片选择—-》Atmel-—>AT89C52ﻩ设置芯片频率,选择生成16进制可执行文件.=============中断========单片机获取外部数据得方式:1、程序控制方式a、无条件发送方式单片机认为外部设备一直都就是准备好得,直接就拿数据使用。

b、条件判断方式在满足一定条件才获取数据.2、中断方式由外部控制得,当有中断请求产生得时候,就可以在中断里面去实现获取数据。

3、DMA直接存储控制器当需要从外界获取数据得时候,DMA可以向CPU申请获取数据,由DMA直接获取数据。

使用DMA可以绕过CPU处理数据,降低CPU得使用率。

中断:当CPU正常运行得时候,突然收到一个中断请求(任务),完成中断任务之后立即返回原来得程序继续执行.中断源:中断来源,发送中断得源头中断请求:中断发出得请求,申请执行任务中断响应:CPU响应中断请求,暂停正在执行得任务,转而执行中断任务8个中断源:ﻩINT0ﻩ外部中断0ﻩINT1 外部中断1ﻩINT2 外部中断2ﻩINT3外部中断3T0ﻩ定时器0T1 定时器1ﻩT2ﻩ定时器2Uart 串口中断中断有优先级:分为4级,从0~3,数字越大优先级越高,高优先级得中断可以打断低优先级得中断。

中断得查询次序:在中断优先级相同得情况下,并且两个中断同时产生得时候,会优先执行查询次序级别高得中断、查询次序不能打断中断、中断服务函数:void INT1_func(void) interrupt 2{ﻩif()}小车两轮驱动:单片机得IO口不能直接驱动电机运行,必须使用驱动模块才可以。

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

BIB = 0;控制右轮电机,如果想让轮子转动,只需要设置以上两个引脚,一个为1,一个为0、P0、0 左轮 1P0、1左轮 0P0、2 右轮 1P0、3右轮0如果轮子想要动起来,需要接电源线。

思考:封装函数:前进、后退、停止、左前转、右前转、左后转、右后转=============定时器==============定时器就就是定时,定时产生中断或者就是计数.工作方式:定时器:主要产生定时中断计数器:计时计数工作模式:模式0:12位寄存器模式1:16位寄存器模式2:8位自动重装载寄存器模式3:两个8位寄存器,T1无效时钟周期:就就是频率得倒数假设晶振12M,时钟周期就是1/12us,实际上大多使用得就是:1/11、0592状态周期:状态周期就是时钟周期得两倍:1/12*212个时钟周期定为1个机器周期,如果晶振就是12M,那么一个机器周期就刚好就是1us。

寄存器:TCON 控制寄存器 TMOD模式寄存器定时器0作模式1: TMOD、1 = 0TMOD、0 = 1设置寄存器计数得初值:TL0与TH050ms = (65536-初值)* (1/11、0592*12)50000us = (65536-初值ﻩ)* 1、0850746080 =65536—初值初值= 19456 ==》0x4C00TH0= 0x4C;TL0 = 0x00;=============串口==============一、计算机内部通讯得方式:UART(串口)、I2C、SPI、1-Write(单总线)二、数据通讯方式并行通讯:多个任务同时进行,增加速度。

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

三、串行通讯同步通讯:发送一位数据必须要接收一位数据,通过时钟线确定数据收发:I2C、SPI异步通讯:可以独立收发数据,不需要发送数据得时候接收数据。

:串口UART、1w总线单工:只能一方发送数据,一方接收数据(收音机)半双工:同一时刻只能一方发送数据,一方接收数据,但就是方向可以转换.(对讲机)全双工:数据在同一时刻可以收也可以发.(电话)四、电平特性TTL与RS232TTL:0V~5V 0V表示数据0 3、3V/5V表示数据1RS232:—15V~+15V 3V~15V表示数据0 -15V~-3V表示数据1 单片机直接使用得就是TTL电平:VCC正极;GND负极; TXD数据发送; RXD数据接收五、串行通讯得协议六、单片机串口寄存器SCON控制寄存器串口选择方式1,8位UART,波特率可变。

设置SCON寄存器:SCON = // 0101 0000 ==》 0x50PCON电源管理寄存器,设置SMOD得值SMOD默认值就就是0,也可以主动设置为0、设置好之后需要开启总中断:EA = 1;ﻩES = 1;串口波特率计算:波特率 = (2^SMOD /32)* (定时器溢出率)9600 = (1/32)* (11059200/12/(256—TH1)) 9600 = (1/32)*(921600/(256-TH1))921600/(256-TH1)= 307200(256-TH1) = 3TH1 = 253 ==〉0xFD串口发送数据SUBF = 'h’; // 发送数据,还要判断就是否发送3、2系统设计项目框图:3、3系统实现程序代码如下:#include 〈reg52、h>ﻩ//器件配置文件#include<intrins、h>#defineuintunsigned int#define uchar unsignedchar#define LCM_DataP2#defineBusy 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;sbitFM=P0^7;//定义蜂鸣器sbit AIA= P2^3;//定义电机sbit AIB = P2^2;sbit BIB = P2^1;sbitBIA =P2^0;void LCMInit(void);void DisplayOneChar(unsigned char X, unsignedchar Y,unsigned char DData);voidDisplayListChar(unsigned charX,unsigned char Y,unsigned char code*DData);void Delay5Ms(void);void Delay400Ms(void);void Decode(unsignedcharScanCode);void WriteDataLCM(unsigned char WDLCM);void WritemandLCM(unsigned charWCLCM,BuysC);void SendOneByte(unsigned char c);unsignedcharReadDataLCM(void);unsigned char ReadStatusLCM(void);unsigned charcodemcustudio[]={"YueQian"};unsignedchar code email[]={" "};unsigned char code Cls[]= {" ”};unsignedchar code ASCII[15] = {'0’,'1','2',’3’,’4','5’,'6',’7’,'8','9','、',’-','M'};static unsigned char DisNum=0; //显示用指针ﻩﻩﻩunsigned int time=0;unsignedlong S=0;bit flag =0;unsigned chardisbuff[4]={0,0,0,0,};void Init_Int1(void){ﻩ IT1= 1; //下降沿触发ﻩEX1= 1;//开启外部中断1ﻩ EA=1;//开启总中断}void delay_ms(uintx)//延时函数ﻩuinti;while(x--){ﻩfor(i=0;i〈133;i++);ﻩ}}void car_go() //控制小车得函数前进{ﻩAIA = 1;//运用电机得电位差来控制小车得前进方向ﻩAIB = 0;ﻩBIA=1;BIB =0;}void car_back()//后退{AIA= 0;ﻩ AIB =1;BIA=0;ﻩBIB= 1;}voidright()//右转{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;ﻩ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;}voidback_left()//左转后退{AIA =1;AIB =0;ﻩBIA = 1;BIB =1;delay_ms(500);AIA = 0;ﻩAIB = 1;BIA =0;BIB = 1;}void WriteDataLCM(unsigned charWDLCM)//写数据{ReadStatusLCM();//检测忙ﻩLCM_Data=WDLCM;LCM_RS = 1;ﻩLCM_RW=0;ﻩLCM_E = 0; //若晶振速度太高可以在这后加小得延时LCM_E =0; //延时ﻩLCM_E= 1;}voidWritemandLCM(unsignedcharWCLCM,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 charReadStatusLCM(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);}voidLCMInit(void) //LCM初始化{ﻩLCM_Data =0;ﻩWritemandLCM(0x38,0); //三次显示模式设置,不检测忙信号Delay5Ms();WritemandLCM(0x38,0);Delay5Ms();WritemandLCM(0x38,0);Delay5Ms();ﻩWritemandLCM(0x38,1);//显示模式设置,开始要求每次检测忙信号WritemandLCM(0x08,1);//关闭显示ﻩWritemandLCM(0x01,1);//显示清屏WritemandLCM(0x06,1);//显示光标移动设置ﻩWritemandLCM(0x0F,1);// 显示开及光标设置}//按指定位置显示一个字符voidDisplayOneChar(unsigned char X,unsigned charY,unsigned charDData){ﻩY&=0x1;X &= 0xF;//限制X不能大于15,Y不能大于1ﻩif (Y)X|= 0x40;//当要显示第二行时地址码+0x40;X |=0x80; //算出指令码WritemandLCM(X,1);//发命令字WriteDataLCM(DData);//发数据}//按指定位置显示一串字符void DisplayListChar(unsignedcharX, unsigned char Y,unsigned char code*DData){unsigned charListLength;ListLength =0;Y &=0x1;X&=0xF; //限制X不能大于15,Y不能大于1while(DData[ListLength]>0x19)//若到达字串尾则退出ﻩﻩ{ﻩﻩﻩif(X〈= 0xF)//X坐标应小于0xFﻩﻩ{ﻩDisplayOneChar(X, Y, DData[ListLength]); /显示单个字符ﻩﻩﻩListLength++;ﻩﻩX++;ﻩﻩ}}}void Delay5Ms(void) //5ms延时{unsigned intTempCyc = 5552;while(TempCyc—-);}voidDelay400Ms(void)//400ms延时{ﻩunsigned char TempCycA=5;unsigned intTempCycB;while(TempCycA--)ﻩﻩ{TempCycB=7269;while(TempCycB--);ﻩﻩ};}/**************超声波测距函数*************************/ voidConut(void){time=TH0*256+TL0;TH0=0;TL0=0;S=(time*1、87)/100;//算出来就是CM/*晶振为11、0592MHz时|t(us)= 计数* (12/11、0592)*(1/58)| = 计数* 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]); //显示M}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]);ﻩ//显示点DisplayOneChar(2, 1, ASCII[disbuff[1]]);DisplayOneChar(3,1,ASCII[disbuff[2]]);DisplayOneChar(4,1,ASCII[12]);//显示M}}/********************************************************//***********定时器T0中断服务函数***********/void Timer0IRQ()interrupt1 //T0中断用来计数器溢出,超过测距范围{flag=1;}/********************触发超声波模块************************************/ //超声波模块Trig控制端给大于10us得高电平触发模块测距voidStartModule()ﻩ//启动模块{ﻩ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 chari=100,j;for(;ms;ms—-){ﻩwhile(--i){ﻩﻩj=10;ﻩﻩwhile(——j);ﻩﻩ}ﻩ}}/******************************/void SendOneByte(unsigned char c)//发送单个字符{SBUF= c;while(!TI);TI =0;}/*********************************************************/ voidmain(void){ﻩunsignedchar 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;ﻩ// TMOD=0x01;ﻩ//设T0为方式1;// TH0=0;//ﻩ TL0=0;//ﻩET0=1; //允许T0中断// EA=1;ﻩ//开启总中断ﻩTMOD=0x21;ﻩﻩ//设T0为方式1,定时器1方式2; // 0010 0001 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]);ﻩwhile(!RX);//当RX为零时等待TR0=1; ﻩ//开启计数ﻩwhile(RX);//当RX为1计数并等待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;ﻩ}elseﻩﻩFM =1;//80MSdelayms(80);ﻩﻩ}}void UARTInterrupt(void)interrupt4{ﻩunsigned charbuf;if(RI){RI = 0;//add your code here!ﻩﻩbuf = SBUF; ﻩﻩ//作回显没有任何作用ﻩﻩSendOneByte(buf);ﻩif(buf== ’1')ﻩﻩ{ﻩﻩcar_go();ﻩﻩdelay_ms(1000);ﻩ}elseif(buf=='2’){ﻩcar_back();ﻩﻩﻩdelay_ms(1000);}ﻩelse if(buf==’3’)ﻩ{ﻩﻩ right();ﻩdelay_ms(1000);ﻩﻩ}else if(buf== ’4')ﻩ{ﻩleft();ﻩdelay_ms(1000);ﻩ}else if(buf== '5'){ﻩﻩgo_right();ﻩdelay_ms(1000);ﻩﻩ }ﻩﻩelse if(buf == '6')ﻩﻩ{ﻩﻩgo_left();ﻩﻩdelay_ms(1000);ﻩﻩ}elseif(buf == '7')ﻩﻩ{ﻩﻩback_right();ﻩdelay_ms(1000);ﻩ}ﻩelseif(buf== '8’)ﻩ{back_left();ﻩﻩdelay_ms(1000);ﻩﻩ }}elseTI=0;}voidInt1_Routine(void) interrupt2{ﻩEX1 = 0;ﻩAIA=1;AIB=1;BIA=1;ﻩBIB =1;ﻩFM = 0;delay_ms(500);ﻩﻩFM = 1;EX1 = 1;}总结学习单片机要有一定得c语言基础,单片机得基础知识我还就是多多少少知道一些,可就是让我直接来做这一个项目,我却无从下手。

相关主题