1

将代码上传到 Arduino Atmega2560 时出错。

错误是:

herkulex.cpp: In member function 'void herkulex::hklx_SendPacket(DrsPacket)':
herkulex.cpp:121: error: 'USART0_PutNChar' was not declared in this scope
herkulex.cpp: In member function 'unsigned char herkulex::hklx_ucReceivePacket(DrsPacket*)':
herkulex.cpp:211: error: 'USART0_ucGetNChar' was not declared in this scope
herkulex.cpp: In member function 'void herkulex::hklx_RemoveInvalidData()':
herkulex.cpp:244: error: 'USART0_ucTrashNChar' was not declared in this scope

下面是发生错误的代码:(herkulex.cpp 代码)

#include<Arduino.h>
#include<Wire.h>
#include<Math.h> 

//ATmega128ì�˜ ë ˆì§€ìŠ¤í„° 등ì�´ ì •ì�˜ë�˜ì–´ 있ì�Œ
#include <avr/io.h>
//#include "TIMER0.h"
#include "USART0.h" 
//#include "USART0.c"

//#define __HERKULEX_C
#include "herkulex.h"
//#undef __HERKULEX_C

//void hklx_RemoveInvalidData(void);
#define herkulex_cpp

herkulex::herkulex()
{
  // Empty constructor. needed for lib
}



#define USART_BUF_SIZE 256  
#define PROTOCOL_SIZE_IDX 2
#define PROTOCOL_ID_IDX   3
#define PROTOCOL_CMD_IDX  4
#define PROTOCOL_CS1_IDX  5
#define PROTOCOL_CS2_IDX  6
#define PROTOCOL_DATA_IDX  7

//í—¤ë�” ê´€ë ¨
#define HEADER      0xFF

//SIZE ê´€ë ¨
#define MIN_PACKET_SIZE     7
#define MIN_ACK_PACKET_SIZE                 9
#define MAX_PACKET_SIZE                     223
#define MAX_DATA_SIZE                       (MAX_PACKET_SIZE-MIN_PACKET_SIZE)

//ID ê´€ë ¨
#define MAX_ID                              0xFD    
#define BROADCAST_ID                        0xFE  

//CMD ê´€ë ¨ - Request Packet
#define CMD_EEP_WRITE                       0x01
#define CMD_EEP_READ                        0x02
#define CMD_RAM_WRITE                       0x03
#define CMD_RAM_READ                        0x04    
    #define CMD_RW_DATA_ADDR_IDX            7
    #define CMD_RW_DATA_LEN_IDX             8
#define CMD_I_JOG                           0x05
    #define CMD_I_JOG_STRUCT_SIZE           5
    #define CMD_I_JOG_MAX_DRS               (MAX_DATA_SIZE/CMD_I_JOG_STRUCT_SIZE)
#define CMD_S_JOG                           0x06
    #define CMD_S_JOG_STRUCT_SIZE           4
    #define CMD_S_JOG_MAX_DRS               (MAX_DATA_SIZE/CMD_S_JOG_STRUCT_SIZE)
#define CMD_STAT                            0x07    
#define CMD_ROLLBACK                        0x08
#define CMD_REBOOT                          0x09

#define CMD_MIN                             (CMD_EEP_WRITE)
#define CMD_MAX                             (CMD_REBOOT)

//CMD ê´€ë ¨ - ACK Packet
#define CMD_ACK_MASK                        0x40

#define CMD_EEP_WRITE_ACK                   (CMD_EEP_WRITE|CMD_ACK_MASK)
#define CMD_EEP_READ_ACK                    (CMD_EEP_READ|CMD_ACK_MASK)
#define CMD_RAM_WRITE_ACK                   (CMD_RAM_WRITE|CMD_ACK_MASK)
#define CMD_RAM_READ_ACK                    (CMD_RAM_READ|CMD_ACK_MASK)
#define CMD_I_JOG_ACK                       (CMD_I_JOG|CMD_ACK_MASK)
#define CMD_S_JOG_ACK                       (CMD_S_JOG|CMD_ACK_MASK)
#define CMD_STAT_ACK                        (CMD_STAT|CMD_ACK_MASK)
#define CMD_ROLLBACK_ACK                    (CMD_ROLLBACK|CMD_ACK_MASK)
#define CMD_REBOOT_ACK                      (CMD_REBOOT|CMD_ACK_MASK)

#define CMD_ACK_MIN                         (CMD_EEP_WRITE_ACK)
#define CMD_ACK_MAX                         (CMD_REBOOT_ACK)

//CheckSum ê´€ë ¨
#define CHKSUM_MASK                         0xFE



//////////////////////////////receiving state result value //////////////////////////////
  enum{
    DRS_RXWAITING,
    DRS_RXCOMPLETE,
    DRS_HEADERNOTFOUND,
    DRS_INVALIDSIZE,
    DRS_UNKNOWNCMD,
    DRS_INVALIDID,
    DRS_CHKSUMERROR,
    DRS_RXTIMEOUT
  }DrsRxStatus;

void herkulex:: hklx_Init(unsigned long ulBaudRate){
//  TIMER0_Init();
//  USART0_Init(ulBaudRate);
    return;
}
#define HEADER      0xFF
void herkulex:: hklx_SendPacket(DrsPacket stPacket){
    unsigned char i;

    //í—¤ë�” ìž…ë ¥
    stPacket.ucHeader[0] = HEADER;
    stPacket.ucHeader[1] = HEADER;

    //CheckSum 계산 후 ìž…ë ¥
    stPacket.ucCheckSum1 = stPacket.ucPacketSize ^ stPacket.ucChipID ^ stPacket.ucCmd;
    for( i=0; i<(stPacket.ucPacketSize-MIN_PACKET_SIZE); i++ )    
        stPacket.ucCheckSum1 ^= stPacket.unData.ucData[i];

    stPacket.ucCheckSum2 = ~(stPacket.ucCheckSum1);
    stPacket.ucCheckSum1 &= CHKSUM_MASK;    
    stPacket.ucCheckSum2 &= CHKSUM_MASK;

    //PacketSize 만í�¼ USART0으로 ì†¡ì‹ 
    USART0_PutNChar(&stPacket.ucHeader[0], stPacket.ucPacketSize);

    return;
}

unsigned char herkulex:: hklx_ucReceivePacket(DrsPacket *pstPacket){
    unsigned char i, ucPacketSize, ucChipID, ucCmd, ucReadLen, ucCheckSum1, ucCheckSum2;

    //ë°›ì�€ ë�°ì�´í„° 수가 ACK 패킷ì�˜ 최소 사ì�´ì¦ˆë³´ë‹¤ ì �ì�„ 경우
    if(gucRxBufferCnt < MIN_ACK_PACKET_SIZE){
        return DRS_RXWAITING;
    }

    //패킷� 처� � 바�트가 헤�가 아� 경우
    if(gucRxBuffer[gucRxBufferReadIdx] != HEADER || 
       gucRxBuffer[((unsigned int)gucRxBufferReadIdx+1)%USART_BUF_SIZE] != HEADER){
        hklx_RemoveInvalidData();
        return DRS_HEADERNOTFOUND;   
    }
    //맞� 경우 Size, ID, Cmd를 �어옴
    else{
        ucPacketSize = gucRxBuffer[ ((unsigned int)gucRxBufferReadIdx + PROTOCOL_SIZE_IDX ) % USART_BUF_SIZE ];
        ucChipID = gucRxBuffer[ ((unsigned int)gucRxBufferReadIdx + PROTOCOL_ID_IDX ) % USART_BUF_SIZE ];
        ucCmd = gucRxBuffer[ ((unsigned int)gucRxBufferReadIdx + PROTOCOL_CMD_IDX ) % USART_BUF_SIZE ];
    }

    //Size가 최대보다 � 경우
    if(ucPacketSize > MAX_PACKET_SIZE){
        hklx_RemoveInvalidData();
        return DRS_INVALIDSIZE;
    }
    //아� Size 만�� ��터가 들어오지 않았� 경우
    else if(ucPacketSize > gucRxBufferCnt){
        return DRS_RXWAITING;
    }

    //Cmd가 범위를 벗어난 경우
    if(!(ucCmd >= CMD_ACK_MIN && ucCmd <= CMD_ACK_MAX)){
        hklx_RemoveInvalidData();
        return DRS_UNKNOWNCMD;
    }

    //ID가 범위를 벗어난 경우
    if(ucChipID >= BROADCAST_ID){
        hklx_RemoveInvalidData();
        return DRS_INVALIDID;
    }

    //ê°� Cmdì—� ë”°ë�¼ì„œ Sizeê°€ ì �합한지 검사
    switch(ucCmd){
        case CMD_EEP_WRITE_ACK:
        case CMD_RAM_WRITE_ACK:
        case CMD_I_JOG_ACK:
        case CMD_S_JOG_ACK:
        case CMD_STAT_ACK:
        case CMD_ROLLBACK_ACK:
        case CMD_REBOOT_ACK:
            if(ucPacketSize != MIN_ACK_PACKET_SIZE){
                hklx_RemoveInvalidData();
                return DRS_INVALIDSIZE;
            }
            break;
        case CMD_EEP_READ_ACK:
        case CMD_RAM_READ_ACK:
            ucReadLen = gucRxBuffer[ ((unsigned int)gucRxBufferReadIdx + CMD_RW_DATA_LEN_IDX ) % USART_BUF_SIZE ];
            if(ucPacketSize != (MIN_ACK_PACKET_SIZE + 2 + ucReadLen)){
                hklx_RemoveInvalidData();
                return DRS_INVALIDSIZE;
            }   
            break;
    }

    //ìˆ˜ì‹ ë�œ 패킷ì�˜ CheckSumì�„ 계산
    ucCheckSum1 = ucPacketSize ^ ucChipID ^ ucCmd;
    for(i=0;i<(ucPacketSize-MIN_PACKET_SIZE);i++){
        ucCheckSum1 ^= gucRxBuffer[ ((unsigned int)gucRxBufferReadIdx + i ) % USART_BUF_SIZE ];
    }
    ucCheckSum2 = ~(ucCheckSum1);
    ucCheckSum1 &= CHKSUM_MASK;
    ucCheckSum2 &= CHKSUM_MASK;

    //계산ë�œ CheckSumì�´ ì‹¤ì œë¡œ ë°›ì�€ ë�°ì�´í„°ì™€ ì�¼ì¹˜í•˜ëŠ”지 검사
    if(ucCheckSum1 != gucRxBuffer[ ((unsigned int)gucRxBufferReadIdx + PROTOCOL_CS1_IDX) % USART_BUF_SIZE ] ||
       ucCheckSum2 != gucRxBuffer[ ((unsigned int)gucRxBufferReadIdx + PROTOCOL_CS2_IDX) % USART_BUF_SIZE ])
    {
        hklx_RemoveInvalidData();
        return DRS_CHKSUMERROR;
    }       

    //ëª¨ë“  검사를 통과했다면, 받는 pstPacketì—� 패킷ì�„ 복사
    USART0_ucGetNChar(&(pstPacket->ucHeader[0]), ucPacketSize);

    //완료 �태를 반환
    return DRS_RXCOMPLETE;
}

void herkulex:: hklx_RemoveInvalidData(void){
    unsigned char ucRcvCnt, ucRdIndex, i;

    //버�� �태를 변수� 복사
    ucRcvCnt=gucRxBufferCnt;
    ucRdIndex=gucRxBufferReadIdx;

    //받� ��터가 없� 경우 반환
    if(ucRcvCnt==0){
        return;
    }

    //다ì�Œ í—¤ë�”를 찾거나 ë°›ì�€ ë�°ì�´í„°ì�˜ ë��ì—� ë�„ë‹¬í•  때까지 진행

    for(i=1;i<ucRcvCnt-1;i++){
        if( (gucRxBuffer[ ((unsigned int)ucRdIndex + i ) % USART_BUF_SIZE ] == HEADER ) &&
            (gucRxBuffer[ ((unsigned int)ucRdIndex + i + 1) % USART_BUF_SIZE ] == HEADER) )
        {
            break;
        }
    }
    if((i==ucRcvCnt-1) && (gucRxBuffer[ ((unsigned int)ucRdIndex + ucRcvCnt - 1) % USART_BUF_SIZE ] != HEADER))
    {
        i++;
    }       

    //i만� ��터를 버림
    USART0_ucTrashNChar(i);     

    return;
}

错误声明它们未声明的变量都在我已包含在 herkulex.cpp 文件中的 USART0.h 文件下声明。我可以知道代码有什么问题吗?谢谢!

USART0.h code: 
#ifndef USART0_lib
#define USART0_lib

#include <Arduino.h>
#include <Wire.h> 
#include <inttypes.h>
//ìˆ˜ì‹  버í�¼ì�˜ 사ì�´ì¦ˆ ì„ ì–¸
#define USART_BUF_SIZE 256

//ìˆ˜ì‹  버í�¼, ì�½ê¸° ì�¸ë�±ìŠ¤, 쓰기 ì�¸ë�±ìŠ¤, ë�°ì�´í„° 수를 ì €ìž¥í•  변수 ì„ ì–¸
volatile unsigned char gucRxBuffer[USART_BUF_SIZE];
volatile unsigned char gucRxBufferReadIdx;
volatile unsigned char gucRxBufferWriteIdx;
volatile unsigned char gucRxBufferCnt;

#ifdef USART0_cpp
#define EXTERN 
#else 
#define EXTERN extern 
#endif 

class USART0
{
  public: 
  USART0();

  void USART0_Init(unsigned long ulBaudRate);
  void USART0_PutChar(unsigned char ucData);
  void USART0_PutNChar(unsigned char *pucData, unsigned char ucCnt);
  unsigned char USART0_ucGetNChar(unsigned char *pucTarget, unsigned char ucCnt);
  unsigned char USART0_ucTrashNChar(unsigned char ucCnt);
  void USART0_ClearBuffer(void);

//  private :no private
};


#endif
4

2 回答 2

0

USART0_PutChar是类的成员函数USART0。您正尝试从另一个类成员函数调用它,就像独立非成员函数一样 - 您需要一个实例USART0来调用该函数。

关于您的评论,您需要创建一个实例,USART0然后像调用任何其他成员函数一样调用该函数

 USART0 obj;
 obj.USART0_PutChar();

除非您从同一类的另一个成员函数调用它,否则您不能像当前尝试那样调用成员函数。您可以通过将实例USART0(或指针或引用)作为参数传递给您需要调用的函数来实现您想要的USART0_PutChar()。或者,您可以考虑将此函数设为静态成员函数,USART0尽管这可能不合适,具体取决于函数是否需要访问非静态成员变量。

于 2012-11-13T13:36:05.757 回答
0

该函数USART0_PutNChar(和其他函数)是另一个类的成员函数。您需要创建该类的实例并通过此对象调用函数:

USART0 usart0;

usart0.USART0_PutNChar(...);

但是,该类USART0似乎不包含任何状态,这意味着您可以将函数设为全局(即不在类中);使函数静态,如

// Using `struct` as there is no private or protected data/functions
struct USART0
{
    static void USART0_PutNChar(...);
    ...
};

第三种选择是制作USART0命名空间:

namespace USART0
{
    void USART0_PutNChar(...);
    ...
}

在最后两种情况下,您可以像这样调用函数:

USART0::USART0_PutNChar(...);
于 2012-11-13T13:37:49.937 回答