在linux系统上,利用蓝牙透传模块解析蓝牙协议。

/* 蓝牙协议
步数:55,AA,7E,12,70,02,23,45,EC,06,0D
心率:55,AA,7E,12,70,02,12,45,DB,37,0D
*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<termios.h>
#include<error.h>
#include<string.h>
#include<stdlib.h>


#define BUFF_SIZE 512


int main()
{
int stty_fd;
int n;
int number=1;


int state_machine=0;
int sumchkm;
int xorchkm;
int lencnt;
int retval;
int rcvcount;
int m_SrcAdr = 0x12; //目的地址
int m_DstAdr = 0x70; //源地址


int buffer[1];


int i,j=0;
int k=0;


struct termios opt;
/*打开串口设备*/
stty_fd = open("/dev/ttyUSB0",O_RDWR);
if(stty_fd == -1)
{
perror("open device");
return 0;
}
system("clear");
printf("Open device success, The Bluetooth protocol is being parsed.\n");
printf("Prepare for the %d receipt.\n",number);


/*取得当前串口配置*/
tcgetattr(stty_fd,&opt);
tcflush(stty_fd,TCIOFLUSH);


/*设置波特率 - 115200*/
cfsetispeed(&opt,B115200);
cfsetospeed(&opt,B115200);


/*设置数据位 - 8位数据位*/
opt.c_cflag &=~CSIZE;
opt.c_cflag |= CS8;


/*设置奇偶位 - 无奇偶校验*/
opt.c_cflag &= ~PARENB;


/*关闭回显,设置标准模式*/
opt.c_lflag &= ~ECHO;
opt.c_lflag &= ~ICANON;


/*设置停止位 - 1位停止位*/
opt.c_cflag &=~ CSTOPB;

/*使用RTS/CTS流控制*/
opt.c_cflag &= ~CRTSCTS;
opt.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);

/*原样输出*/
opt.c_oflag &= ~OPOST; 

/*设置超时时间 - 15秒*/
opt.c_cc[VTIME] = 150;
opt.c_cc[VMIN] = 1;

/*设置写入设备*/
if(tcsetattr(stty_fd,TCSANOW,&opt)!=0)
{
perror("set baudrate");
return 0;
}


/*同时刷新收到的数据但是不读,并且刷新写入的数据但是不传送*/
tcflush(stty_fd,TCIOFLUSH);




/*读取数据*/
while(1)
{
/*开始读取数据,并且判断是否读取成功*/
n=read(stty_fd,buffer,BUFF_SIZE);
fflush(stdout);
if(n<=0)
{
perror("Analytic protocol");
break;
}


/*打印输入的 串口命令*/
printf("%x\n",*buffer);
fflush(stdout);

/*测试步数是否解析成功*/
char Step[] = "123";
/*测试心率是否解析成功*/
char *Hear[] = {"80","81","82","83","84"};

/*开始解析读取的串口命令*/
if(state_machine == 0) //协议解析状态机
{
if(*buffer == 0x55) //接收到帧头第一个数据
{
state_machine = 1;
}
else
state_machine = 0; //状态机复位
}
else if(state_machine == 1)
{
if(*buffer == 0xAA) //接收到帧头第二个数据
state_machine = 2;
else
state_machine = 0; //状态机复位
}
else if(state_machine == 2)
{
if(*buffer == 0x7E)
state_machine = 3; //接收到帧头第三个数据
else
state_machine = 0; //状态机复位
}
else if(state_machine == 3)
{
sumchkm = *buffer; //开始计算累加、异或校验和
xorchkm = *buffer;
if(*buffer == m_SrcAdr) //判断目的地址是否正确
state_machine = 4;
else
state_machine = 0; //状态机复位
}
else if(state_machine == 4)
{
sumchkm += *buffer;
xorchkm ^= *buffer;
if(*buffer == m_DstAdr) //判断源地址是否正确
state_machine = 5;
else
state_machine = 0;
}
else if(state_machine == 5)
{
lencnt = 0; //接收数据计数器
rcvcount = *buffer; //接收数据长度
sumchkm += *buffer;
xorchkm ^= *buffer;
state_machine = 6;
}
else if(state_machine == 6 || state_machine == 7)
{
lencnt++;
sumchkm += *buffer;
xorchkm ^= *buffer;
if(lencnt == rcvcount) //判断数据是否接收完毕
state_machine = 8;
else
state_machine = 7;
}
else if(state_machine == 8)
{
if(sumchkm == 0xec) //判断步数累加和是否相等
{
retval = 1;
state_machine = 9;
}
else if(sumchkm == 0xdb) //判断心率累加和是否相等
{
retval = 2;
k++;
state_machine = 9;
}
else
state_machine = 0;
}
else if(state_machine == 9)
{
if(xorchkm == *buffer) //判断异或校验和是否相等
state_machine = 10;
else
state_machine = 0;
}
else if(state_machine == 10)
{
number++;
printf("Prepare for the %d receipt.\n",number);
if(*buffer == 0x0D) //判断是否接收到帧尾结束符
{
state_machine = 0; //状态机复位,等待接收下一次串口命令
if(retval == 1)
{
write(stty_fd,Step,3); //返回步数
tcflush(stty_fd, TCIOFLUSH);
}
else if(retval == 2)
{
write(stty_fd,Hear[k],2); //返回心率
tcflush(stty_fd, TCIOFLUSH);
}
}
}
}


printf("Program will exit!!!\n");


/*关闭串口*/
close(stty_fd);
return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值