下位机是个单片机C8051F020,KEIL开发,上位机用VC6.0做的,现在问题是上位机控制时有时会出现需要发几次命令,下位机才能响应并控制上,中间通过串口服务器转换。
下位机串口程序:
#include "Communication.h"
#include "stdlib.h"
#include "String.h"
#include "SCommunication.h"
#include "Crc.h"
#include "Mcu.h"
#include "Timer.h"
#include "Motors.h"
#define RECV_MAX_BYTES 48
#define TRAN_MAX_BYTES 64
static volatile byte recvbuff[RECV_MAX_BYTES] = {0};
static volatile byte recvtail = 0;
static volatile byte tranbuff[TRAN_MAX_BYTES] = {0};
static volatile byte trantail = 0;
static volatile byte temprecv[RECV_MAX_BYTES] = {0};
static volatile frame recvframe = {0};
volatile frame ctrlframebuffer = {0};
volatile frame transframe = {0};
static volatile bool isParaseMessage = false;
volatile frame transMessage = {0};
//volatile frame recvmessage = {0};
/***************************************************************************************
*fun-name :COMM_Recv
*input :no
*output :no
*describtion :数据接收函数
****************************************************************************************/
void COMM_Recv(byte rxdat)
{
if(recvtail >= RECV_MAX_BYTES)
{
memset(recvbuff,0,RECV_MAX_BYTES);
recvtail = 0;
}
recvbuff[recvtail++] = rxdat;
}
/***************************************************************************************
*fun-name :COMM_RecvPoll
*input :no
*output :no
*describtion :数据校验,处理
****************************************************************************************/
void COMM_RecvPoll()
{
static volatile byte recvtail1 = 0;
static volatile byte msglen = 0;
static volatile byte msgtype = 0;
static volatile byte msgStartPos = 0;
static volatile bool msgHead = false;
//int i = 0;
bool checkOk = false;
if(recvtail1 == recvtail)
{
return;
}
else
{
recvtail1 = recvtail;
if(recvtail == 0)
{
msgHead = false;
msglen = 0;
msgtype = 0;
msgStartPos = 0;
}
//最小字节数为4
if(recvtail < 4)
return;
//搜寻帧头
if(msgHead == false)
{
if(recvbuff[recvtail-4] == MSG_FRAME_HEAD_FIRST && recvbuff[recvtail-3] == MSG_FRAME_HEAD_SECOND)
{
msglen = recvbuff[recvtail-2];
msgtype = recvbuff[recvtail-1];
msgStartPos = recvtail-4;
msgHead = true;
}
}
else
{
if(recvtail - msgStartPos >= msglen)
{
//Interrupt_Disable();
checkOk = CheckSum(&recvbuff[msgStartPos],recvbuff[msgStartPos+2]);
if(checkOk /*!crc_compute_16(&recvbuff[i],recvbuff[i+2])*/)
{
//memset(temprecv,0,sizeof(temprecv));
memcpy(&recvframe,&recvbuff[msgStartPos],recvbuff[msgStartPos+2]);
//memcpy(temprecv,&recvbuff[i+recvbuff[i+2]],recvtail -=(i+recvbuff[i+2]));
//memcpy(recvbuff,temprecv,sizeof(temprecv));
isParaseMessage = true;
}
memset(recvbuff,0,RECV_MAX_BYTES);
recvtail1 = recvtail = 0;
msgHead = false;
msglen = 0;
msgtype = 0;
msgStartPos = 0;
//Interrupt_Enable();
}
}
/***************************************************************************************
*fun-name :ParaseMessage
*input :no
*output :no
*describtion :数据包解析
***************************************************************************************/
void ParaseMessage()
{
// union ufloat{unsigned char ftmp[4];float fval;}frecvtmp;
// union uuint{unsigned char uitmp[2];unsigned int uival;}uirecvtmp;
unsigned char errorByte = 0;
if(isParaseMessage)
{
isParaseMessage = false;
switch(recvframe.type)
{
case MSG_TYPE_SERVO_CTRL:
//复制到数据缓存
memcpy(&ctrlframebuffer,&recvframe,recvframe.len);
//置控制新数据标志
antCtrlStatus.hasNew = true;
break;
}
memset(&recvframe,0,sizeof(frame)); //清空缓冲区
}
}
/***************************************************************************************
*fun-name :UploadMessage
*input :msgtype = 上传的数据类型
*output :no
*describtion :上传相应的消息数据
****************************************************************************************/
void UploadMessage(byte msgtype)
{
int i = 0; //临时计数器
unsigned int temp1 = 0; //临时整型变量
unsigned int sum = 0; //临时整型变量
// union ufloat{unsigned char ftmp[4];float fval;}frecvtmp;
// union uuint{unsigned char uitmp[2];unsigned int uival;}uirecvtmp;
byte datbuff[32] = {0};
switch(msgtype)
{
case MSG_TYPE_SERVO_STATUS:
transframe.header[0] = MSG_FRAME_HEAD_FIRST;
transframe.header[1] = MSG_FRAME_HEAD_SECOND;
transframe.len = sizeof(statusframe)-2+4;
transframe.type= MSG_TYPE_SERVO_STATUS;
transframe.unData.status.Cmd = antCtrlStatus.antCmd;
transframe.unData.status.aziWork= antCtrlStatus.aziWork;
transframe.unData.status.eleWork= antCtrlStatus.eleWork;
transframe.unData.status.aziAntAngle = (float)(antCtrlTemps.aziAngle.iangle/ANGLE_UNIT_CODE);
transframe.unData.status.eleAntAngle = (float)(antCtrlTemps.eleAngle.iangle/ANGLE_UNIT_CODE);
transframe.unData.status.aziGuideAngle= (float)(antCtrlStatus.aziDigitAngle.iangle/ANGLE_UNIT_CODE);
transframe.unData.status.eleGuideAngle= antCtrlStatus.eleDigitAngle.iangle/ANGLE_UNIT_CODE;
transframe.unData.status.aziScanStartAngle= antCtrlStatus.aziScanStartAngle.iangle/ANGLE_UNIT_CODE;
transframe.unData.status.aziScanEndAngle= antCtrlStatus.aziScanEndAngle.iangle/ANGLE_UNIT_CODE;
transframe.unData.status.aziScanSpeed= antCtrlStatus.aziSASpeedLevel;
transframe.unData.status.aziLeftLtFlag = MOTORS_GetStatus(ASot);
transframe.unData.status.aziRightLtFlag = MOTORS_GetStatus(APot);
transframe.unData.status.eleUpLtFlag= MOTORS_GetStatus(ESot);
transframe.unData.status.eleDownLtFlag= MOTORS_GetStatus(EPot);
transframe.unData.status.sqFlag = MOTORS_GetStatus(Sq);
transframe.unData.status.fqFlag = MOTORS_GetStatus(Fq);
transframe.unData.status.antState= antCtrlTemps.antState;
transframe.unData.status.sysRunTime= TIME_GetCurTimeMs(0);
transframe.unData.status.aziHand= antCtrlStatus.aziHand;
transframe.unData.status.eleHand= antCtrlStatus.eleHand;
transframe.unData.status.aziAntPosCode= antCtrlTemps.aziAngle.uangle;
transframe.unData.status.eleAntPosCode= antCtrlTemps.eleAngle.uangle;
transframe.unData.status.aziDAOUT= antCtrlTemps.aziDAOut;
transframe.unData.status.eleDAOUT= antCtrlTemps.eleDAOut;
transframe.unData.status.aziOffset= antCtrlTemps.aziSecondOrderDev;
transframe.unData.status.eleOffset= antCtrlTemps.eleSecondOrderDev;
//transframe.unData.status.crcsum= crc_compute_16((byte *)(&transframe),transframe.len-2);
transframe.unData.status.crcsum = CalculteSum((byte *)(&transframe),transframe.len-2);
transframe.unData.status.endctls[0] = 0xfd;
transframe.unData.status.endctls[1] = 0xfe;
break;
}
//发送
SendBytes((byte *)(&transframe),transframe.len+2);
memset((byte *)(&transframe),0,sizeof(frame));
} |