目录
前言
xTaskCreate(atkpTxTask, "ATKP_TX", 150, NULL, 3, NULL); /*atkp发送任务*/
xTaskCreate(atkpRxAnlTask, "ATKP_RX_ANL", 300, NULL, 6, NULL); /*atkp解析任务*/
一、void atkpTxTask(void *param)
void atkpTxTask(void *param)
{
sendMsgACK();
while(1)
{
atkpSendPeriod();
vTaskDelay(1);
}
}
1. sendMsgACK();
void sendMsgACK(void)
{
//测试MUP Baro气压 是否初始化完毕
msg.version = configParam.version;
msg.mpu_selfTest = getIsMPU9250Present();//MPU是否初始化完毕(应该在后文传感器任务初始)
msg.baro_slfTest = getIsBaroPresent();//气压计是否初始化完毕
msg.isCanFly = getIsCalibrated();//重力是否校准完成
msg.isLowpower = getIsLowpower();//是否低电量
msg.moduleID = getModuleID();//获取扩展模块 下文任务
atkp_t p;
p.msgID = UP_REMOTER;
p.dataLen = sizeof(msg)+1;
p.data[0] = ACK_MSG;
memcpy(p.data+1, &msg, sizeof(msg));
//这个数据包的格式为 上行两字节 UP_REMOTER dataLen data:ACK_MSG +msg
radiolinkSendPacketBlocking(&p); //发送到 txQueue队列句柄
}
//msg的格式如下
typedef __packed struct
{
u8 version;
bool mpu_selfTest;
bool baro_slfTest;
bool isCanFly;
bool isLowpower;
enum expModuleID moduleID;
} MiniFlyMsg_t;
2. atkpSendPeriod();/*数据周期性发送给上位机,每1ms调用一次*/
static void atkpSendPeriod(void)
{
static u16 count_ms = 1;
if(!(count_ms % PERIOD_STATUS)) //在没有30次之前都会进if,之后每到一定PERIOD的倍数 就会余0 然后就会进入if
{
attitude_t attitude;//定义了 时间戳 yaw pitch raw
getAttitudeData(&attitude);
int positionZ = getPositionZ();
sendStatus(attitude.roll, attitude.pitch, attitude.yaw, positionZ, 0, flyable);
}
if(!(count_ms % PERIOD_SENSOR))
{
Axis3i16 acc;
Axis3i16 gyro;
Axis3i16 mag;
getSensorRawData(&acc, &gyro, &mag);
sendSenser(acc.x, acc.y, acc.z, gyro.x,gyro.y, gyro.z, mag.x, mag.y,mag.z);
}
if(!(count_ms % PERIOD_RCDATA))
{
sendRCData(rcdata.thrust, rcdata.yaw, rcdata.roll,
rcdata.pitch, 0, 0, 0, 0, 0, 0);
}
if(!(count_ms % PERIOD_POWER))
{
float bat = pmGetBatteryVoltage();
sendPower(bat*100,500);
}
if(!(count_ms % PERIOD_MOTOR))
{
u16 m1,m2,m3,m4;
motorPWM_t motorPWM;
getMotorPWM(&motorPWM);
m1 = (float)motorPWM.m1/65535*1000;
m2 = (float)motorPWM.m2/65535*1000;
m3 = (float)motorPWM.m3/65535*1000;
m4 = (float)motorPWM.m4/65535*1000;
sendMotorPWM(m1,m2,m3,m4,0,0,0,0);
}
if(!(count_ms % PERIOD_SENSOR2))
{
int baro = getBaroData() * 100.f;
sendSenser2(baro, 0);
}
if(++count_ms>=65535)
count_ms = 1;
}
主要是获取各个传感器的数据 然后根据不同的 msgID 传给txQueue 队列
3. vTaskDelay(1);
https://blog.youkuaiyun.com/crjmail/article/details/80015628
二、void atkpRxAnlTask(void *param)
void atkpRxAnlTask(void *param)
{
atkp_t p;
while(1)
{
xQueueReceive(rxQueue, &p, portMAX_DELAY);
atkpReceiveAnl(&p);
}
}
1.
2.static void atkpReceiveAnl(atkp_t *anlPacket)
static void atkpReceiveAnl(atkp_t *anlPacket)
{
if(anlPacket->msgID == DOWN_COMMAND) //👈
{
switch(anlPacket->data[0])
{
case D_COMMAND_ACC_CALIB:
break;
case D_COMMAND_GYRO_CALIB:
break;
case D_COMMAND_MAG_CALIB:
break;
case D_COMMAND_BARO_CALIB:
break;
case D_COMMAND_ACC_CALIB_STEP1:
break;
case D_COMMAND_ACC_CALIB_STEP2:
break;
case D_COMMAND_ACC_CALIB_STEP3:
break;
case D_COMMAND_ACC_CALIB_STEP4:
break;
case D_COMMAND_ACC_CALIB_STEP5:
break;
case D_COMMAND_ACC_CALIB_STEP6:
break;
//主要是这里👇👇👇👇👇👇
case D_COMMAND_FLIGHT_LOCK:
flyable = false;
break;
case D_COMMAND_FLIGHT_ULOCK:
flyable = true;
}
}
总结
- 主要是将姿态数据 atkp格式数据 通过不同的 IDmsg 发送到 txQueue队列
- 接收队列 读取的是 rxQueue?
- 后期手动计算和整理一下时间片的配置