将代码上传到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;
}
错误声明它们未声明的变量都是在USART0.h文件中声明的,我已将其包含在herkulex.cpp文件中。我可以知道代码有什么问题吗?谢谢!
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
答案 0 :(得分:0)
USART0_PutChar
是类USART0
的成员函数。您试图以与独立非成员函数相同的方式从另一个类成员函数调用此函数 - 您需要一个USART0
实例来调用该函数。
关于你的评论,你需要创建一个USART0
的实例然后调用该函数就像你任何其他成员函数一样
USART0 obj;
obj.USART0_PutChar();
除非您从同一类的另一个成员函数调用它,否则您无法调用当前正在尝试的成员函数。您可以通过将USART0
(或指针或引用)的实例作为参数传递给您需要调用USART0_PutChar()
的函数来实现您想要的结果。或者,您可以考虑将此函数设置为USART0
的静态成员函数,尽管这可能不合适,具体取决于函数是否需要访问非静态成员变量。
答案 1 :(得分: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(...);