目录
前言
最近要用到蓝牙,发现蓝牙调试器上自定义数据挺合适的,有点难,网上的教程都是基于stm32,看他们的代码研究思路,太折磨了。所以,写完后我就把我基于stc8的用法,以及思路写下。
一、材料
我所用到的是STC8A8K64S4A12核心板,蓝牙模块(HC-05),蓝牙调试器(手机软件)
二、步骤
1.软件中定义数据包
- 打开软件,点击下方导航栏的专业调试,来到图一。点击下方+号,可创建一个工程。点击新建的工程,点击通信设置。
- 来到图二,在这里可以定义发送和接收的数据包的结构,在接收数据包这,我定义了两个数据。
- 图三,通信模式的配置。(右上角的问号有详细介绍,下文会有用到)
2.软件中定义控件
按步骤,添加控件。
- 图七框中的三个参数分别是:接收还是发送,数据类型,数据名。(图片中控件有数据残留,那是因为,之前调试时留下的)
- 图八中,我添加了两个可编辑文本来接收,和一个按钮来发送。
- 图九,就是数据包的结构介绍。
3.数据包结构分析
由图九可知,一个数据收发满足以下结构
- 包头:0xA5 (一个字节)
- 元数据:自定义(X个字节)
- 校验和:原始数据所有字节之和的低8bit数据 (一个字节)
- 包尾:0x5A (一个字节)
例如我们要收发一个包含一个整型(占4个字节)和一个浮点型(占4个字节)数据
那么收发的字节量就是:包头(1)+元数据(4+4)+校验和(1)+包尾(1)=11
4.代码流程
- 基础设置
#define LY_Data_Len 11 //蓝牙数据包大小(长度) char LY_Data_Sz[LY_Data_Len]; //蓝牙数据包缓存区 char LY_JSXY=0; //接收校验
- 蓝牙串口初始化函数,波特率9600。
void LY_Init() { PCON &= 0x7F; //波特率不倍速 SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x40; //定时器时钟1T模式 AUXR &= 0xFE; //串口1选择定时器1为波特率发生器 TMOD &= 0x0F; //设置定时器模式 TMOD |= 0x20; //设置定时器模式 TL1 = 0xDC; //设置定时初始值 TH1 = 0xDC; //设置定时重载值 ES=1; //打开接收中断 EA=1; //打开总中断 TR1=1; //打开计数器 }
- 串口中断
void LY_Routine() interrupt 4 { int a; int b=0x01; if(RI==1) //如果接收标志位为1,接收到了数据 { a=SBUF; // LY_SendByte(a); if(a==0xA5) LY_JSXY=1; if(LY_JSXY==1) { LY_Send_MA(); } if(a==0x5A) LY_JSXY=0; RI=0; //接收标志位清0 } }
- 串口发送函数
//单次发送 void LY_SendByte(unsigned char Byte) { SBUF=Byte; while(TI==0); TI=0; } //多次发送 void LY_Send_For(char* Data,int Len) { char fora=0; while(fora<Len) { SBUF=Data[fora]; fora++; while(TI==0); TI=0; } }
- 装配函数(装配的目的,因为int型,float型的数据比较长有4个字节,而串口只能一个字节一个字节的发送,所以,要给这些长字节分段。)
//整型装配 //参数:要写入的int型的值,在蓝牙数据包位置 void LY_Int(int num,char *byte) { byte[3] = (num & 0xFF000000) >> 24; byte[2] = (num & 0x00FF0000) >> 16; byte[1] = (num & 0x0000FF00) >> 8; byte[0] = (num & 0x000000FF); } //浮点型装配 //参数:要写入的float型的值,在蓝牙数据包位置 void LY_float(float num,char *byte) { unsigned long longdata = 0; longdata = *(unsigned long*)# byte[3] = (longdata & 0xFF000000) >> 24; byte[2] = (longdata & 0x00FF0000) >> 16; byte[1] = (longdata & 0x0000FF00) >> 8; byte[0] = (longdata & 0x000000FF); } //计算校验和,并自动装配 void LY_check() { int LY_Zh=0; char DataLen=LY_Data_Len-3,fora; for(fora=1;fora<=DataLen;fora++) { LY_Zh=LY_Data_Sz[fora]+LY_Zh; } LY_Data_Sz[LY_Data_Len-2]=LY_Zh & 0xff; }
- 蓝牙发送主函数(串口触发事件)
//蓝牙发送主函数 void LY_Send_MA() { LY_Data_Sz[0]=0xA5; LY_Data_Sz[LY_Data_Len-1]=0x5A; LY_Int(1521,&LY_Data_Sz[1]); LY_float(1.23,&LY_Data_Sz[5]); LY_check(); LY_Send_For(LY_Data_Sz,LY_Data_Len); }
5.效果
当你按下发送按键后,就能得到返回数据(该数据是在上述代码中设置好的),并展示在连接在可编辑文本中。
三、总结
第一次写文章,总感觉有点拖沓了,不知道还有什么遗漏,见谅见谅。在摸索一下怎么把库文件发出来先。
我的蓝牙库:
链接:https://pan.baidu.com/s/1KJ4KfjjlL0i4a_JMfavFXg
提取码:3wv5