我用的uart通信协议如下 第1个字节:帧头,值为0x80 + 数据长度 第2个字节-第n个字节:数据 数据的第1个字节:命令 规定:1. 每帧发送的总长度不超过127; 2. 数据的bit7永为0 1. 解析uart缓存区接收到的数据的流程如下 ① 读取uart缓存区数据,数据长度可以设为缓冲区的长度 ② 解析出帧头和该帧数据的长度n,该帧数据的命令 ③ 执行该命令的函数 2. 发送数据流程如下 ① 调用不同命令接口函数发送数据 ② 接口函数将命令打包成规定通信格式 ③ 同uart dma方式发送数据 3. 解析数据的框架 //处理命令的函数 //参数:len 数据长度 // data 数据 void cmd_proc(uint_8 *data, uint_8 len) { switch(data[0])//第一个数据是命令 { case 0: //do.. break; case 1: //do.. break; ... } } //解析出数据域及长度函数 //参数:void (*callback)(uint_8*, uint_8) 回调函数,调用的是命令处理函数 void recv_proc(void (*callback)(uint_8*, uint_8)) { len = uart1_read(buf, 255); for(i=0; i<len; i++) { ch = buf[i]; switch(count) { case 0: if(ch > 0x80) { packet[count]=ch; packet_len = ch - 0x80; count++; } break; default: packet[count]=ch; count++; if(count == (packet_len + 1)) { callback(&packet[1], packet_len); count = 0; } break; } } } 每50ms运行一次recv_proc(cmd_proc);函数处理接收到的数据即可。 4. 发送数据框架 1)做好打包函数 //发送软件版本号 void send_version(uint_8 major, uint_8 minor) { uint_8 data[5]; data[0] = 0x83; data[1] = PDAT_VERSION; data[2] = major & 0x7F; data[3] = minor & 0x7F; uart1_write(data,4); } //发送心率 void send_heartrate(uint_16 hr) { uint8_t data[5]; data[0] = 0x83; data[1] = PID_SEND_HEART; data[2] = (hr>>7) & 0x7F; data[3] = hr & 0x7F; uart1_write(data, 4); } 2)调用上面的接口函数就可以发送相关数据出去了。 -------------------------------------------------------------------------- 这个协议牺牲了bit7来区别帧头和数据域,我看过别的协议的做法是 帧头帧尾是0x7f,数据域里出现0x7f的数据用0x7d 0x5f代替,出现0x7d用 0x7d 0x5d代替。不过我没去弄过。感兴趣的自己试一下吧。 |
|