打印

串口通信问题

[复制链接]
1114|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sinadz|  楼主 | 2014-2-26 18:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下位机是个单片机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));
}

相关帖子

沙发
秋天落叶| | 2014-2-26 18:19 | 只看该作者
代码太长了,实在是每耐心看完

使用特权

评论回复
板凳
xsgy123| | 2014-2-26 18:27 | 只看该作者
这么具体的问题,你要调试,很简单的。
1、PC发错,先不管单片机,先把你的PC发送的数据用PC的另一个串口开串口助手之类的软件看看有没有问题。
2、不管PC软件,直接用串口助手之类的软件把你的命令输入循环发送,看看单片机收到的数据有没有问题。
3、如果收发都没有问题,看看单片机的软件对命令的解释有没有问题。

使用特权

评论回复
地板
火箭球迷| | 2014-2-26 18:37 | 只看该作者
如果另一个软件串口收发都没有问题,就单步运行看看,到底是哪里的问题,看看你的各个寄存器有没有问题

使用特权

评论回复
5
骗子的片子| | 2014-2-26 18:52 | 只看该作者
这代码太长了吧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

304

主题

2313

帖子

0

粉丝