本文主要介绍了针对android的蓝牙串口上位机开发。

程序下载地址:点击打开链接

一、帧定义

androidclient依照一定的数据帧格式通过蓝牙串口发送数据到连接到MCU的蓝牙从机。MCU接收到数据后。依照帧格式的定义,接收数据帧。并解析数据帧,得到须要的数据。

androidclient依照下面帧格式来发送和接收数据。

clnchanpin-p-7060216.html

b5b32d82115ebdde922bd80cb52b5ad2.png

1.1client发送的数据帧内容

发送频率:10Hz

Center

clnchanpin-p-7060216.html

帧校验的和是从帧长開始到帧校验前全部数据的和对256取余。

即sum%256。

pitch roll yaw数据各16位,由高低8位组成。MCU接收数据时须要将其再复合成一个16位数据。

0x5A:帧头

14:针长度

0xA1:帧功能,标明这帧数据是pitch yaw roll内容。

pitch_set_H:pitch高8位

pitch_set_L:pitch低8位

...

...

帧校验:(帧长+帧功能+数据)%256

0xA5:帧尾。

(注:帧是这么定义的,但实际上编写接收程序的时候。我将帧尾0xA5当作了一帧数据的帧头。

这样帧头就变成了 0xA5 0x5A。此时就不存在帧尾了)

以下是androidclient发送字节信息的程序:

b[0] = (byte)0XA5; //帧头

b[1] = (byte)14; //帧长

b[2] = (byte)0xA1; //帧功能

b[3] = (byte)(pitchSet>>8); //数据

b[4] = (byte)(pitchSet);

b[5] = (byte)(rollSet>>8);

b[6] = (byte)(rollSet);

b[7] = (byte)(yawSet>>8);

b[8] = (byte)(yawSet);

b[9] = (byte)0;

b[10] = (byte)0;

b[11] = (byte)0;

b[12] = (byte)0;

int temp = 0;

for(int j=1;j<13;j++)

{

temp = temp+b[j];

}

b[13] = (byte)(temp%256); //校验

b[14] = (byte)0x5A; //帧结束

1.2MCU接收帧数据

因为串口是依照一个一个字节的格式发送数据,所以MCU接收数据时,要依照client发送的帧格式的定义。找到一帧数据的開始与结束,确认一帧数据接收无误后,再将当中的数据解析出来。

使用一个为来标志(状态机)接收程序对一阵数据的接收状态。

编写的DSP2808接收程序例如以下:

定义数据类型

typedef struct

{

int status; //data status

int Rx_Data; //the receivced data

int data[15];//

int rx_buf[13];

int buf_index;

int sum;

int yawSet;

int pitchSet;

int rollSet;

}Sci_Data;

Sci_Data sci_data;

interrupt void SCIB_RX_ISR() //以中断的方式接收数据

{

//接收程序

sci_data.Rx_Data = ScibRegs.SCIRXBUF.all;

ScibRegs.SCIFFRX.bit.RXFFOVRCLR = 1; //clear overflow flag

ScibRegs.SCIFFRX.bit.RXFFINTCLR = 1; //clear the interrupt flag

PieCtrlRegs.PIEACK.all |= PIEACK_GROUP9; //enable more interrupt from PIE group 9

Decode_Frame(sci_data.Rx_Data); //数据帧解码

}

void Decode_Frame(int rx_data)

{

if(sci_data.status==0 && rx_data == 0x5A) //推断帧尾 假设找到帧尾,status=1

{

sci_data.status = 1;

}

else if(sci_data.status == 1 &&rx_data == 0xA5) //帧尾下一个字符是帧头。status=2

{

sci_data.status = 2;

}

else if(sci_data.status ==2) //帧头后是13个字节数据 从帧长到帧校验

{

if(sci_data.buf_index<13)

{

sci_data.rx_buf[sci_data.buf_index] = rx_data; // 0-12 to save data length function data... sum

if(sci_data.buf_index<12) //求取校验和

{

sci_data.sum += sci_data.rx_buf[sci_data.buf_index];

}

sci_data.buf_index++;

}

if(sci_data.buf_index >= 13)

{

if(sci_data.rx_buf[12] == sci_data.sum%256)

{

int j=0;

for(j=0;j<10;j++)

{

sci_data.data[j] = sci_data.rx_buf[j+2]; //save data to the data buf

}

sci_data.pitchSet = sci_data.data[0]<<8|sci_data.data[1];

}

sci_data.buf_index = 0;

sci_data.status = 0;

sci_data.sum = 0;

}

}

else

{

sci_data.buf_index = 0;

sci_data.status = 0;

sci_data.sum = 0;

}

}

这样DSP2808就接收到了从client发送来的数据。保存在sci_data.pitchSet、sci_data.rollSet、sci_data.yawSet三个变量中。

二、androidclient开发流程

问题:检測蓝牙的连接状态

android蓝牙串口程序状态机

在程序中,通过broadcast来检測蓝牙的连接状态,根绝蓝牙的连接状态来决定操作。

打开蓝牙---扫描设备---选择设备---连接设备---连接正常---发送数据---

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐