/*
蓝牙协议
步数:55,AA,7E,12,70,02,23,45,EC,06,0D
心率:55,AA,7E,12,70,02,12,45,DB,37,0D
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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;
}