实例9、stc8a蓝牙模块HC05或者HC06模块,控制小车。利用定时器1产生通信的波特率9600

一、目的
二、设备模块
三、背景任务和原理接线
四、步骤
五、效果
六、心得
**

一、目的

**
掌握串口通信的基本知识,先照葫芦画瓢,跟着大概了解做一遍,慢慢了解;
掌握蓝牙模块的知识;
掌握定时器产生波特率的写法;
掌握串口中断的写法。

二、设备

stc8a自制开发板;
OLED屏幕;
HC05蓝牙模块;
stc下载软件里面的串口助手;
手机,以及手机端的蓝牙调试软件
三、背景任务
我们现在在一个大数据的时代,蓝牙是非常重要的一个手段,比如蓝牙耳机,蓝牙音箱等等;蓝牙怎么回事,我们尝试初步学习下。
任务:
手机开蓝牙,和单片机端蓝牙匹配;
手机开蓝牙软件,单片机端蓝牙接收到手机发过来的不同指令,LED0和LED1不同的亮灭状态,验证通信的正常。
如果通信正常,判断正常,那么就可以控制小车了。

**

原理接线

**
蓝牙模块
在这里插入图片描述
在这里插入图片描述

接线

用单片机的串口1,(UART1,就是P30和P31通信引脚)和蓝牙通信。
蓝牙模块的RXD接单片机的P30(TXD),蓝牙模块的TXD接单片机的P31(TXD);
VCC--------5V
GND--------GND。

**

串口知识简单讲解:

**
串口就是一个通信的名字,比如4G,5G这种,通过串口进行通信,就是说A和B都要一个串口,不然通信不了,不在一个频道。
好了,A和B都有串口了,那么两边的对话暗号协议等等要一致,不然鸡同鸭讲,说不通,还得找翻译,所以有串口的通信格式的模式的设置。包括波特率,奇偶校验,等等。后面慢慢学习。先知道,需要这么设置。
主要是波特率先讲多一点点

oo
波特率
就是A和B对话,两个人说话的速度。
两个人速度要一样,不然都听不懂,不在一个频道。单片机的串口的波特率,可以用定时器产生,我们现在使用定时器1产生波特率,给一个对话的心脏,因为定时器0我们用来计算小车运行的时间了。现在我们就用定时器1做波特率发生器。
波特率越快,交流越快,但是有时候数据会丢失等等,所以我们设定一个稳定可靠点的波特率,我们设置为9600,bps单位
缓冲
****
单片机接收到外部的数据,通过串口接收。
会暂时把数据放到缓冲区里面,缓冲区的名字是SBUF(串口1的缓冲区);
当外部数据继续进来,会把SBUF刷新掉,
所以要把SBUF的数据及时拿出来,先放着。
串口中断:
串口接收一个字节的数据,就会触发串口中断;
如果中断允许打开,就会跳到串口的中断服务函数里面。执行里面的代码;
可以在里面做简单的数据判断,看下是不是我们需要的,不是,我们就不要,是,我们继续接收。

x
单片机串口端的设置,主要是串口波特率发生,串口模式设置,打开串口中断,3个步骤。
x
x
看看下载软件的案例代码。
我们摘取我们需要的部分。

里面主要由有几个子函数,一个主函数。我们只需要子函数的串口中断函数,另外的发送的函数不要。因为我们单片机只接受手机蓝牙发过来的信息,单片机不发信息给手机蓝牙。


在这里插入图片描述

#include "reg51.h"
#include "intrins.h"

#define FOSC            11059200UL
#define BRT             (65536 - FOSC / 115200 / 4)

sfr     AUXR        =   0x8e;

bit busy;
char wptr;
char rptr;
char buffer[16];

void UartIsr() interrupt 4 using 1
{
    if (TI)
    {
        TI = 0;
        busy = 0;
    }
    if (RI)
    {
        RI = 0;
        buffer[wptr++] = SBUF;
        wptr &= 0x0f;
    }
}

void UartInit()
{
    SCON = 0x50;
    TMOD = 0x00;
    TL1 = BRT;
    TH1 = BRT >> 8;
    TR1 = 1;
    AUXR = 0x40;
    wptr = 0x00;
    rptr = 0x00;
    busy = 0;
}

void UartSend(char dat)
{
    while (busy);
    busy = 1;
    SBUF = dat;
}

void UartSendStr(char *p)
{
    while (*p)
    {
        UartSend(*p++);
    }
}

void main()
{
    UartInit();
    ES = 1;
    EA = 1;
    UartSendStr("Uart Test !\r\n");

    while (1)
    {
        if (rptr != wptr)
        {
            UartSend(buffer[rptr++]);
            rptr &= 0x0f;
        }
    }
}

改造一下代码:实现串口1,波特率9600,接收到
0+N两个都验证接收到,才对第三个进行处理判断。为了防止数据的错误的接收,需要验证字头等内容。这里我们验证0和N就好了,自己定义也行。

‘0’+‘N’+‘R’======LED0=1,LED1=0;
‘0’+‘N’+‘L’,LED0=1,LED1=1;
‘0’+‘N’+‘D’,LED0=0,LED1=1;
‘0’+‘N’+‘F’,LED0=0,LED1=0;

好。前面的基本概念:
串口
波特率
串口中断,缓冲区
蓝牙模块,
我们有了基本了解。

我们开始动手:
1、配置蓝牙模块,让蓝牙模块的波特率是9600;
2、设置单片机程序,是波特率9600,串口1中断打开;
3、可以通信。

1、配置蓝牙。
https://www.cnblogs.com/Sonny-xby/p/11197973.html
接线:
用蓝牙模块和下载模块直接相连接,不要单片机开发板。
接线,蓝牙模块的VCC—5V0,GND–GND,蓝牙模块的RXD—下载模块的TXD,蓝牙模块的TXD接下载模块的RXD;
下载模块先不插电脑;先按住蓝牙模块的按钮,然后下载模块插进电脑。
三秒后放手松开按钮。
(带小黑色按钮的,要选按着黑色按钮,然后再加电(即插上电脑的USB口)
不带按钮的,要给KEY接线端接上一个电压(VCC),然后再插入电脑,即可

当蓝牙模块state灯变为慢闪,则表明已经进入AT模式。
HC-05蓝牙模块:使用AT命令配置详细步骤
进入AT命令模式方法:
先按住按键,再给模块上电,此时灯是慢闪,进入AT命令模式,默认波特率是38400。
注意:不按按钮给模块上电,是通信模式,灯光为快闪。

常用AT命令:
看不同的AT指令集,要多百度测试下。
这个是HC-05的指令集AT指令集。有一些可能不太合适使用。
AT+VERSION?          返回HC-05的软件版本号
AT+NAME?          返回HC-05的名字
AT+UART?           返回蓝牙波特率
AT+UART=115200,0,0      设置串口波特率115200,1位停止位,无校验
【AT+UART=,,  param1: 波特率  param2: 停止位, 0=1位,1=2位  param3: 校验位, 0=无校验,1=奇校验,2=偶校验  默认设置为9600,0,0】
AT+NAME=bluetooth       修改蓝牙模块的名字为bluetooth
AT+PSWD?          查询配对密码
AT+PSWD=”1234”       设置密码1234
AT+ROLE?           查询主从状态,=1:设置成主,=0:设置成从,=2:设置成回环
AT+ROLE=0          设置成从
AT+ORGL           恢复出厂默认设置
使用串口监视器就可以发送指令进行设置了。)

蓝牙的代码,手机蓝牙连接之后,输入0nr,显信息,等等

#include "stc8a8k.h"
#include "intrins.h"
#include "4pinOLED.h"
//波特率是9600
#define FOSC            11059200UL
#define BRT             (65536 - FOSC / 9600 / 4)

sbit LED0=P0^0;
sbit LED1=P0^1;
//蓝牙接收到字符,左,右,前进,后退,停止,调头,开始循迹
bit  cmdflag_REC=0; //接收数据的标记位
bit  cmdflag=0;  
unsigned char  cmdnum=0; //接收数据的个数
unsigned char  cmddat=0; //接收的数据
unsigned char  cmdbuff[5]=0; //接收缓冲字节	
void delay_tms(unsigned int tms)
{
	unsigned int i,j;
	for(i=tms;i>0;i--)
		for(j=0;j<1100;j++);
}
void UartIsr() interrupt 4 using 1
{   
   
     if(RI)	                 //是否接收中断
    {
       RI=0;
       cmddat=SBUF;  //将缓冲区的数据一个字节,赋值给cmddat,中转一下,不然下次数据进来,把缓冲区刷新了,数据就不见了
       if(cmddat=='0'&&(cmdnum==0)) //接收数据第一帧
         {
            cmdbuff[cmdnum]=cmddat;
            cmdflag=1;        //开始接收数据
         }
       else
					if(cmdflag==1)  //如果不是第一个数据,说明帧头校验通过,就继续接收,
					{
						cmdnum++;
						cmdbuff[cmdnum]=cmddat;//0---1--2--0
						if(cmdnum>=2)
						{
							cmdnum=0;
							cmdflag=0;
							cmdflag_REC=1;// 停止接收
						}  
					}
		}
      

}

void UartInit()
{
   SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设定定时器1为16位自动重装方式
	TL1 = 0xE8;		//设定定时初值
	TH1 = 0xFF;		//设定定时初值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}

                                                              
void main()
{
    UartInit();
    ES = 1;
    EA = 1;
    OLED_Init();
    OLED_Clear();//清空屏幕
	 OLED_ShowString(0,0,"eeeefxx",16);//显示字符串
	
    while (1)
    {
      //***********************蓝牙控制的代码,前进,后退,左转,右转,停止,调头
	     if(cmdflag_REC==1)				    //
	   {
				cmdflag_REC=0;
				if(cmdbuff[0]=='0'&&cmdbuff[1]=='n')	//第一个字节为O,第二个字节为N,第三个字节为控制码,手机端发送的应该是0NB等
				switch(cmdbuff[2])
	     {
		      case 'f' :						    // 前进forward
						   OLED_ShowString(0,0,"forward",16);//显示字符串
						  LED0=1;LED0=0;
							break;
		      case 'b':						// 后退backxxx
			        LED0=0;LED0=1;
					    OLED_ShowString(0,0,"backxxx",16);//显示字符串
							break;
					
		      case 'l':						// 左转leftxxx
						   LED0=1;LED0=1;
							    OLED_ShowString(0,0,"leftxxx",16);//显示字符串
							break;
					
		      case 'r':						// 右转rightxx
						  LED0=0;LED0=0;
					    OLED_ShowString(0,0,"rightxx",16);//显示字符串
							break;
		      case 's':						// 停止stopxxx
						  OLED_ShowString(0,0,"stopxxx",16);//显示字符串
			        LED0=1;LED0=0;
					    delay_tms(500);
					    LED0=0;LED0=1;
					    delay_tms(500);
					    LED0=1;LED0=0;
					    delay_tms(500);
					    LED0=0;LED0=1;
					    delay_tms(500);
							break;
				
          default:break;
	     }	
		 }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值