0

好吧,我已经为一个 arduino 程序制作了一个 ntp 服务器库。我想让我在 ntp lib 中制作的函数成为静态的,这样我就可以从其他类调用它们,而无需制作该 ntp 服务器类的对象。

我的问题是,当我一一制作静态类的函数和变量时(因为某些函数使用一些类变量),我发现自己将某个函数设为静态,然后整个库都会出错。整个库无法理解任何变量。我收到无法解析变量的错误我也收到错误说无法使用 NTP 类的函数,因为它们没有对象(但它是类的函数并且存在没有在另一个类中实现)。我会给你我的代码。

#ifndef NTPLIB_H_
#define NTPLIB_H_

#include "Arduino.h"
#include "SPI.h"
#include "IPAddress.h"
#include "EthernetUdp.h"
#include "Ethernet.h"
#include "DayNumber.h"

class NTPlib {

private:


public:
    static EthernetUDP  Udp;
    static DayNumber DN;


    static const int Gmt=2;
    static const unsigned int localPort = 8888;
    static const int NTP_PACKET_SIZE=48;

    static byte  packetBuffer[NTP_PACKET_SIZE ];

    unsigned long secsSince1900;
    unsigned long UnixTime;
    static unsigned long daysPassedInYear;
    static int utchour;
    static int lcthour;
    static int min;
    static int sec;
    static int year;
    static int month;
    static int date;
    static int dayOfWeek;



    NTPlib();
    static NTPlib getTime();
    static bool testNtpServer();
    void startEthernetAndUdp();
    unsigned long  static sendNTPpacket(IPAddress& address);

    virtual ~NTPlib();
};

#endif /* NTPLIB_H_ */

这是头文件,这是 .cpp 文件

#include "NTPlib.h"


NTPlib::NTPlib() {
    // TODO Auto-generated constructor stub

}

NTPlib NTPlib::getTime(){

    if (testNtpServer()){
        // We've received a packet, read the data from it
        Udp.read((unsigned char*)packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer

        //the timestamp starts at byte 40 of the received packet and is four bytes,
        // or two words, long. First, extract the two words:
        unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
        unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);

    // combine the four bytes (two words) into a long integer
        // this is NTP time (seconds since Jan 1 1900):
        unsigned long secsSince1900 = highWord << 16 | lowWord;
        Serial.print("Seconds since Jan 1 1900 = " );
        Serial.println(secsSince1900);
        // now convert NTP time into everyday time:
        // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
        const unsigned long seventyYears = 2208988800UL;
        // subtract seventy years:
        unsigned long UnixTime = secsSince1900 - seventyYears;


        sec = UnixTime % 60;
        //calc min
        min = (UnixTime/60)%60;
        //calc hour
        utchour = (UnixTime/3600)%24;
        lcthour = utchour + Gmt;
        //day of the week
        dayOfWeek = (((UnixTime/86400UL) + 3) % 7) + 1;//setting first day Sunday=1

        // print Unix time:
        Serial.print("Unix time = ");
        Serial.println(UnixTime);

        Serial.print("the day is : ");
        Serial.println(dayOfWeek);

        Serial.print("The LTC time is ");
        Serial.println(lcthour);


        unsigned long UnixTimeToDays=UnixTime/86400UL;
        Serial.println(UnixTimeToDays);
        unsigned long calcDaysInYears=0;
        int calcYear=1970;
        while((calcDaysInYears+= (DN.checkLeapYear(calcYear)? 366:365)) <= UnixTimeToDays){
            calcYear++;
        }
        //setting year
        year = calcYear;
        Serial.print("the year is :");
        Serial.println(year);


        //calculating days in this year
        calcDaysInYears -= (DN.checkLeapYear(calcYear)? 366:365);
        daysPassedInYear = UnixTimeToDays - calcDaysInYears;
        Serial.println(daysPassedInYear);

        //set Daynumber one year loop
        DN.Days1YearLoop = daysPassedInYear+1;
        //calculating date and month
        static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31};

        int calcMonth;
        int monthLength;

        for (calcMonth=0; calcMonth<12;calcMonth++){
            if (DN.checkLeapYear(year)){
                monthLength = (calcMonth==1) ? 29: 28;
            }else{
                monthLength = monthDays[calcMonth];
            }
            if ( daysPassedInYear > monthLength){
                daysPassedInYear -= monthLength;
            }else{
                break;
            }
        }
        month = ++calcMonth;
        date = ++daysPassedInYear;
        Serial.print("Month is : ");
        Serial.print(month);
        Serial.print(" Date is: ");
        Serial.println(date);

        // print the hour, minute and second:
        Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
        Serial.print(utchour); // print the hour (86400 equals secs per day)
        Serial.print(':');

        if ( min < 10 ) {
        // In the first 10 minutes of each hour, we'll want a leading '0'
          Serial.print('0');
        }
        Serial.print(min); // print the minute (3600 equals secs per minute)
        Serial.print(':');

        if ( sec < 10 ) {
         // In the first 10 seconds of each minute, we'll want a leading '0'
           Serial.print('0');
        }
        Serial.println(sec); // print the seconds

        return NTPlib();

    }else{
    //error  ntp time from DS1307
        Serial.println("RTC");
        return NTPlib();
    }
}

unsigned long NTPlib::sendNTPpacket(IPAddress& address){

  // set all bytes in the buffer to 0    
  memset(packetBuffer, 0, NTP_PACKET_SIZE);   
  // Initialize values needed to form NTP request    
  // (see URL above for details on the packets)    
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode    
  packetBuffer[1] = 0;     // Stratum, or type of clock    
  packetBuffer[2] = 6;     // Polling Interval    
  packetBuffer[3] = 0xEC;  // Peer Clock Precision    
  // 8 bytes of zero for Root Delay & Root Dispersion    
  packetBuffer[12]  = 49;    
  packetBuffer[13]  = 0x4E;    
  packetBuffer[14]  = 49;    
  packetBuffer[15]  = 52;    
  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:    
  Udp.beginPacket(address, 123); //NTP requests are to port 123    
  Udp.write(packetBuffer,NTP_PACKET_SIZE);    
  Udp.endPacket();

}

void NTPlib::startEthernetAndUdp(){

//declaration of the mac address of ethernet shield
    byte mac[]= {0x00,0xAA,0xBB,0xCC,0xDE,0x02};   
    if (Ethernet.begin(mac) == 0) {   
        Serial.println("Failed to configure Ethernet using DHCP");   
        // no point in carrying on, so do nothing forevermore: 
        //for(;;)   
        //  ;  
    }

    Udp.begin(localPort);
}

bool NTPlib::testNtpServer(){

    byte serverslist[4][4]={
            193,93,167,241,
            129,215,160,240,
            138,195,130,71,
            132,163,4,101
    } ;
    IPAddress ntpServers(serverslist[0]);
    sendNTPpacket(ntpServers);
    int x=0;
    delay(1000);

    while(!Udp.parsePacket() && x<=3){
            x++;
            IPAddress ntpServers(serverslist[x]);
            Serial.println("ton pairneis");
            sendNTPpacket(ntpServers);
            delay(1000);
        }

    if (x<=3){
        Serial.print("leitoyrgei o server ");
        Serial.println(++x);
        return true;
    }else{
        return false;
    }
}


NTPlib::~NTPlib() {
    // TODO Auto-generated destructor stub
}

起初我将gettime函数设为静态,当然还有所有相关变量。之后我不得不将testNTPServer函数设为静态,而我只有1个错误。错误是

说明资源路径位置类型无法在没有对象 NTPlib.cpp /NTP/lib 第 191 行 C/C++ 问题的情况下调用成员函数 'long unsigned int NTPlib::sendNTPpacket(IPAddress&)'

这个函数是它不应该需要对象的类的函数。同样,当我执行此函数时,静态所有 cpp 都会为类的所有变量提供未定义的引用。一个示例是这样的:

说明 资源路径位置 键入更多未定义的对 `NTPlib::packetBuffer' 的引用遵循 NTPlib.cpp /NTP/lib 第 149 行 C/C++ 问题

有什么帮助吗?

4

1 回答 1

0

在 C++ 中,当您在类声明中声明静态数据成员时,您还必须在源文件中为这些数据成员提供定义:

头文件:

class C
{
    static int MyInt;
};

源文件:

int C::MyInt = 0;
于 2013-02-18T14:38:18.693 回答