sum += data_to_send[i];
data_to_send[_cnt++]=sum;
DT_Send_Data(data_to_send, _cnt);
}
/*----------------------------------------------------------
+ 实现功能:任务调度调用周期1ms
----------------------------------------------------------*/
void Call_Data_transfer(void)
{
/* 定义局部静态变量控制发送周期 */
static int cnt = 0;
/* cnt是从1到10000的数据 */
if(++cnt>10000) cnt = 1;
/* 1发送姿态数据,周期49ms */
if((cnt % 49) == 0)
// f.send_status = 1;
f.send_senser2 = 1;
/* 2发送速度数据,周期199ms */
if((cnt % 199) == 0)
f.send_speed = 1;
...
/* 6发送高度数据,周期399ms */
if((cnt % 399) == 0)
// f.send_senser2 = 1;
f.send_status = 1;
/* 1发送姿态数据,周期49ms */
if(f.send_status)
{
f.send_status = 0;
/* 横滚、俯仰、航向、气压cm高度、控制高度模式、解锁状态 */
DT_Send_Status(IMU_Roll,IMU_Pitch,IMU_Yaw,(0.1f *baro_height),height_ctrl_mode,unlocked_to_fly);
}
/* 2发送速度数据,周期199ms */
else if(f.send_speed)
{
f.send_speed = 0;
/* 向北速度 向西速度 向上速度 单位毫米每秒 */
DT_Send_Speed(0.1f *north_speed,0.1f *west_speed,0.1f *wz_speed);
}
...
/* 6发送高度数据 */
else if(f.send_senser2)
{
f.send_senser2 = 0;
/* 发送气压计高度 超声波高度 发送单位厘米 */
DT_Send_Senser2(baro_height*0.1f,ultra_distance/10);
}
...
}
数据接收
那么如何对接收到的数据解析?每次接收到的数据长度是多少?
一般写个USART2_IRQHandler类似函数为接收中断,系统会自动调用每次只能接收到单字节数据,通过中断的方式调用函数DT_Data_Receive_Prepare将接收到的数据完整的组合在一起
/*----------------------------------------------------------
+ 实现功能:串口发送数据
+ 中断调用
----------------------------------------------------------*/
void USART2_IRQHandler(void)
{
/* 接收数据临时变量 */
u8 com_data;
/* 判断过载错误中断 */
if(USART2->SR & USART_SR_ORE)
com_data = USART2->DR;
/* 判断是否接收中断 */
if( USART_GetITStatus(USART2,USART_IT_RXNE) )
{
/* 清除中断标志 */
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
/* 接收数据及后续的任务 */
com_data = USART2->DR;
/* 数传数据处理解析 */
DT_Data_Receive_Prepare(com_data);
}
接受数据过程中怎样处理接收数据的状态?如何对接收到的数据判断、校验?
通过Mooer状态机的方式:
Mooer状态机的输出只与当前的状态有关,也就是数当前的状态决定输出,输入只决定状态机的状态改变。
如何数据校验:当判断输入数据无效时重新等待判断下一帧数据
/*----------------------------------------------------------
+ 实现功能:数据接收并保存
+ 调用参数:接收到的单字节数据
----------------------------------------------------------*/
void DT_Data_Receive_Prepare(u8 data)
{
/* 局部静态变量:接收缓存 */
static u8 RxBuffer[50];
/* 数据长度 *//* 数据数组下标 */
static u8 _data_len = 0,_data_cnt = 0;
/* 接收状态 */
static u8 state = 0;
/* 帧头1 一个数据帧中第一个数据并且判断是否与宏定义帧头1相等*/
if(state==0&&data==title1_received)
{
state=1;
RxBuffer[0]=data;
}
/* 帧头2 一个数据帧中第二个数据并且判断是否与宏定义帧头2相等*/
else if(state==1&&data==title2_received)
{
state=2;
RxBuffer[1]=data;
}
/* 功能字 */
else if(state==2&&data<0XF1)
{
state=3;
RxBuffer[2]=data;
}
/* 长度 */
else if(state==3&&data<50)
{
state = 4;
RxBuffer[3]=data;
_data_len = data;
_data_cnt = 0;
}
/* 接收数据组*/
else if(state==4&&_data_len>0)
{
_data_len--;
RxBuffer[4+_data_cnt++]=data;
if(_data_len==0)
state = 5;
}
/* 校验累加和 */
else if(state==5)
{
state = 0;
RxBuffer[4+_data_cnt]=data;
DT_Data_Receive_Anl(RxBuffer,_data_cnt+5); //调用数据分析函数,总长比索引+1
}
/* 若有错误重新等待接收帧头 */
else
state = 0;
}
/*----------------------------------------------------------
+ 实现功能:数据分析
+ 调用参数:传入接受到的一个数据帧和长度
----------------------------------------------------------*/
void DT_Data_Receive_Anl(u8 *data_buf,u8 num)
{
u8 sum = 0;
/* 首先计算校验累加和 */
for(u8 i=0; i
sum += *(data_buf+i);
/* 判断校验累加和 若不同则舍弃*/
if(!(sum==*(data_buf+num-1))) return;
/* 判断帧头 */
if(!(*(data_buf)==title1_received && *(data_buf+1)==title2_received)) return;
/* 判断功能字:主要命令集 */
if(*(data_buf+2)==0X01)
{
/* 加速度计校准 */
if(*(data_buf+4)==0X01)
{
mpu6050.Acc_CALIBRATE = 1;
start_height=0;
}
/* 陀螺仪校准 */
else if(*(data_buf+4)==0X02)
{
mpu6050.Gyro_CALIBRATE = 1;
start_height=0;
}
...
}
/* 判断功能字:次要命令集 */
if(*(data_buf+2)==0X02)
{
...
}
/* 判断功能字 接收数据 */
if(*(data_buf+2)==0X03)
{
...
}
/* 回传校验累加和 */
if(*(data_buf+2)==0X14)
{
DT_Send_Check(*(data_buf+2),sum);
}
/* 回传校验累加和 */
if(*(data_buf+2)==0X15)
{
DT_Send_Check(*(data_buf+2),sum);
}
}
小结
对项目中使用的数据传输方法进行了简
[1] [2] [3]
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。