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(...);
    ...
};

3 番目の方法はUSART0、名前空間にすることです。

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

これらの最後の 2 つのケースでは、次のように関数を呼び出します。

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