在另一个类中使用非静态对象

时间:2019-06-24 02:24:07

标签: c++ oop object

编辑:为了使内容更清晰,我进行了一些较小的文书编辑。如果您不赞成我的问题,可以请您解释原因吗?

我看了几个看起来与我的代码非常相似的示例,但无法了解它们在做什么。

当单独使用PWMLED对象时,它们同时起作用,但是当我将它们组合在一起时,PWM对象将停止全部起作用。我最初尝试在构造函数之后的PWM文件中创建led.cpp对象(如下面的代码所示)。在这种配置下,代码编译没有错误,但是PWM不起作用(LED保持熄灭),并且在遇到pwm.startpwm.stop函数中的while循环时,整个程序冻结。 ,大概是因为未创建对象,因此while循环正在等待的事件永远不会发生。如果我注释掉这些while循环,它将不会挂起,但是pwm仍然无法运行。在全亮度下使用LED会绕过pwm功能,因此只要不首先以部分亮度打开led,这部分代码就可以正常工作。

正如我所阅读的,我看到在大多数情况下,第二个对象包含在头文件中,并与其他私有变量一起声明。尝试执行此操作(如下面的代码所示),该代码将不再编译,并为包含pwm。*指令的led.cpp中的每一行提供以下错误。

  

无效使用成员函数'PWM LED :: pwm(pwmModule,bool,bool,   int,prescaler)”(您忘了'()'吗?)

我的主要目标是能够创建一个LED对象,该对象创建一个PWM对象以调节亮度,同时保留我想将其用于电动机速度控制等时单独调用PWM对象的选项/功能。

led.h

#ifndef rav_nrf52840_led_h
#define rav_nrf52840_led_h

#include "rav_nrf52840_macros.h"
#include "rav_nrf52840_pwm.h"

typedef enum {RED = 1,GREEN = 2,YELLOW = 3,BLUE = 4,MAGENTA = 5,CYAN = 6,WHITE = 7} ledState;


class LED {

private:

    PWM pwm(pwmModule module, bool looping, bool mode, int count, prescaler scale);  //  Without this line the code compiles with no errors but the PWM does not function. With this line I get the error invalid use of member function.

    bool pwm_setup_flag;

    bool pwm_sequence_started_flag;

    bool LED_activeLow_flag;

    bool LED_RGB_flag;

    int  LED_portNumber[3];

    int  LED_pinNumber[3];

    int  LED_color;

    int  LED_intensity;

    bool setupPWM(void);

public:

    LED (bool activeLow,int portNumber[3],int pinNumber[3]);  //  Use this format for RGB LEDs. Port and pin numbers must be listed in order: red, green, then blue.

    LED (bool activeLow,int portNumber,int pinNumber);  //  Use this format for single color LEDs

    void on (ledState color, int brightness);  //  Do not use this format with single color LEDs. Valid options for brightness are 0 - 100(%)

    void off (void);
};

    #endif

led.cpp

#include "rav_nrf52840_led.h"

LED::LED (bool activeLow,int portNumber[3],int pinNumber[3]){
    LED_RGB_flag = true;
    LED_activeLow_flag = activeLow;
    LED_portNumber[0] = portNumber[0];
    LED_portNumber[1] = portNumber[1];
    LED_portNumber[2] = portNumber[2];
    LED_pinNumber[0] = pinNumber[0];
    LED_pinNumber[1] = pinNumber[1];
    LED_pinNumber[2] = pinNumber[2];
}

LED::LED (bool activeLow,int portNumber,int pinNumber){
    LED_RGB_flag = false;
    LED_activeLow_flag = activeLow;
    LED_portNumber[0] = portNumber;
    LED_pinNumber[0] = pinNumber;
}





// PRIVATE

PWM pwm(PWM0,true,0,0x7FFF,DIV4);    
bool pwm_setup_flag;
bool pwm_sequence_started_flag;
bool LED_activeLow_flag;
bool LED_RGB_flag;
int  LED_portNumber[3];
int  LED_pinNumber[3];
int  LED_color = RED;  //  Default value is RED.
int  LED_intensity = 0xFFFF;  //  Default value is 0xFFFF.

unsigned int sequence_0[4];

bool LED::setupPWM(void){
    if (!pwm_setup_flag){
        pwm_setup_flag = true;
        pwm.init(INDIVIDUAL,0,0xFFFF);
        pwm.sequence(0,sequence_0,4,0,0);
        pwm.pinSelect(0,LED_portNumber[0],LED_pinNumber[0],false);
        // if (LED_RGB_flag){
            // pwm.pinSelect(1,LED_portNumber[1],LED_pinNumber[1],false);
            // pwm.pinSelect(2,LED_portNumber[2],LED_pinNumber[2],false);
        // }
        pwm.enable();
        return 1;
    }
    else{
        return 0;
    }
}





// PUBLIC

void LED::on (ledState color, int brightness){
    setupPWM();
    LED_intensity = brightness;//(scale(brightness,0,100,0x8000,0xFFFF));
    if (LED_RGB_flag){
        LED_color = color;
        if (brightness >= 0xFFFF){//100){
            LED_activeLow_flag ? writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 0:1) : writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 1:0);
            LED_activeLow_flag ? writePin(LED_portNumber[1],LED_pinNumber[1],readBit(LED_color,1) ? 0:1) : writePin(LED_portNumber[1],LED_pinNumber[1],readBit(LED_color,1) ? 1:0);
            LED_activeLow_flag ? writePin(LED_portNumber[2],LED_pinNumber[2],readBit(LED_color,2) ? 0:1) : writePin(LED_portNumber[2],LED_pinNumber[2],readBit(LED_color,2) ? 1:0);
        }
        else{
            if (pwm_sequence_started_flag){
                pwm.stop();
                pwm_sequence_started_flag = false;
            }
            sequence_0[0] = LED_intensity;
//          sequence_0[1] = LED_intensity;
//          sequence_0[2] = LED_intensity;
            pwm_sequence_started_flag = pwm.start();
        }
    }
    else{
        if (brightness >= 100){
            LED_activeLow_flag ? writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 0:1) : writePin(LED_portNumber[0],LED_pinNumber[0],readBit(LED_color,0) ? 1:0);
        }
        else{
            if (pwm_sequence_started_flag){
                pwm.stop();
                pwm_sequence_started_flag = false;
            }
            sequence_0[0] = LED_intensity;
            pwm_sequence_started_flag = pwm.start();
        }
    }
}

void LED::off (void){
    setupPWM();
    if (pwm_sequence_started_flag){
        pwm.stop();
        pwm_sequence_started_flag = false;
    }
    if (LED_RGB_flag){
        LED_activeLow_flag ? writePin(LED_portNumber[1],LED_pinNumber[1],1) : writePin(LED_portNumber[1],LED_pinNumber[1],0);
        LED_activeLow_flag ? writePin(LED_portNumber[2],LED_pinNumber[2],1) : writePin(LED_portNumber[2],LED_pinNumber[2],0);
    }
    LED_activeLow_flag ? writePin(LED_portNumber[0],LED_pinNumber[0],1) : writePin(LED_portNumber[0],LED_pinNumber[0],0);
}

pwm.h

#ifndef rav_nrf52840_pwm_h
#define rav_nrf52840_pwm_h

#include "rav_nrf52840_baseConst.h"

typedef enum {DIV1,DIV2,DIV4,DIV8,DIV16,DIV32,DIV64,DIV128} prescaler;
typedef enum {PWM0,PWM1,PWM2,PWM3} pwmModule;
typedef enum {COMMON,GROUPED,INDIVIDUAL,WAVEFORM} decoderLoad;

class PWM {

private:

    unsigned int base_address;

    void enable_pwm (bool en);

    bool start_pwm (void);

    void stop_pwm (void);

public:

    PWM (pwmModule module, bool looping, bool mode, int count, prescaler scale);

    void init (decoderLoad load, bool decoder_mode, int loop_count);

    void sequence (int seq_number, unsigned int *pointer, int count, int refresh, int enddelay);

    void pinSelect (int channel, int port, int pin, bool disconnect);

    void enable (void);

    void disable (void);

    bool start (void);

    void stop (void);
};

#endif

pwm.cpp

#include "rav_nrf52840_pwm.h"
#include <cstdint>

PWM::PWM (pwmModule module, bool looping, bool mode, int count, prescaler scale){
    switch (module){

        default:
            ;
        break;

        case PWM0:
            base_address = BASE_ADDRESS_PWM0;
        break;

        case PWM1:
            base_address = BASE_ADDRESS_PWM1;
        break;

        case PWM2:
            base_address = BASE_ADDRESS_PWM2;
        break;

        case PWM3:
            base_address = BASE_ADDRESS_PWM3;
        break;
    }
    unsigned int * pwm_mode_reg = (unsigned int *)(base_address + REGISTER_OFFSET_PWM_MODE);
    unsigned int * countertop_reg = (unsigned int *)(base_address + REGISTER_OFFSET_COUNTERTOP);
    unsigned int * prescaler_reg = (unsigned int *)(base_address + REGISTER_OFFSET_PRESCALER);
    unsigned int * shortcut_reg = (unsigned int *)(base_address + REGISTER_OFFSET_SHORTS);
    *pwm_mode_reg = mode;
    *countertop_reg = count;
    *prescaler_reg = scale;
    if (looping){
        *shortcut_reg = 0x04;  //  Enable looping
    }
}





// PRIVATE

unsigned int base_address;

void PWM::enable_pwm (bool en){
    unsigned int * pwm_enable_reg = (unsigned int *)(base_address + REGISTER_OFFSET_ENABLE);
    *pwm_enable_reg = en;
}

bool PWM::start_pwm (void){
    unsigned int * start_seq0_task = (unsigned int *)(base_address + TASK_OFFSET_SEQSTART_0);
    volatile unsigned int * seq0_started_event = (unsigned int *)(base_address + EVENT_OFFSET_SEQSTARTED_0);
    *start_seq0_task = true;
    while(!*seq0_started_event){}
    *seq0_started_event = false;
    return 1;
}

void PWM::stop_pwm (void){
    unsigned int * pwm_stop_task = (unsigned int *)(base_address + TASK_OFFSET_PWM_STOP);
    volatile unsigned int * pwm_stopped_event = (unsigned int *)(base_address + EVENT_OFFSET_STOPPED);
    *pwm_stop_task = true;
    while(!*pwm_stopped_event){}
    *pwm_stopped_event = false;
}





// PUBLIC

void PWM::init (decoderLoad load, bool decoder_mode, int loop_count){
    unsigned int * decoder_reg = (unsigned int *)(base_address + REGISTER_OFFSET_DECODER);
    unsigned int * loop_reg = (unsigned int *)(base_address + REGISTER_OFFSET_LOOP);
    *decoder_reg = load;
    if (decoder_mode){
        *decoder_reg |= 0x100;
    }
    *loop_reg = loop_count;
}

void PWM::sequence (int seq_number, unsigned int *pointer, int count, int refresh, int enddelay){
    unsigned int * seq_pointer_reg = (unsigned int *)(base_address + REGISTER_OFFSET_SEQ_0_PTR + (MODIFIER_SEQ * seq_number));
    unsigned int * seq_count_reg = (unsigned int *)(base_address + REGISTER_OFFSET_SEQ_0_CNT + (MODIFIER_SEQ * seq_number));
    unsigned int * seq_refresh_reg = (unsigned int *)(base_address + REGISTER_OFFSET_SEQ_0_REFRESH + (MODIFIER_SEQ * seq_number));
    unsigned int * seq_enddelay_reg = (unsigned int *)(base_address + REGISTER_OFFSET_SEQ_0_ENDDELAY + (MODIFIER_SEQ * seq_number));
    *seq_pointer_reg = reinterpret_cast<std::uintptr_t>(pointer);
    *seq_count_reg = count;
    *seq_refresh_reg = refresh;
    *seq_enddelay_reg = enddelay;
}

void PWM::pinSelect (int channel, int port, int pin, bool disconnect){
    unsigned int * pin_select_reg = (unsigned int *)(base_address + REGISTER_OFFSET_PSEL_OUT_0 + (MODIFIER_PSEL_OUT * channel));
    *pin_select_reg = ((disconnect << 31) | (port << 5) | pin);
}

void PWM::enable (void){
    enable_pwm(true);
}

void PWM::disable (void){
    enable_pwm(false);
}

bool PWM::start (void){
    bool pwm_seq_started = start_pwm();
    return pwm_seq_started;
}

void PWM::stop (void){
    stop_pwm();
}

main.cpp

#include "rav_nrf52840_base.h"
#include "rav_nrf52840_led.h"


int main(void){  //  TX

    setupClock (HF_64MHz_XTAL, START);
    setupClock (LF_32_768kHz_XTAL, START);

    int my_led_ports[3] = {0,0,0};
    int my_led_pins[3] = {23,22,24};  //  RED, GREEN, BLUE
    LED led(true,my_led_ports,my_led_pins);

    setupPin (0, 3,INPUT);
    pullPin  (0, 3,PULLUP);
    setupPin (0,18,INPUT);  //  External (? Ohm) pullup resistor.
    setupPin (0,22,OUTPUT);
    writePin (0,22,HIGH);
    setupPin (0,23,OUTPUT);
    writePin (0,23,HIGH);
    setupPin (0,24,OUTPUT);
    writePin (0,24,HIGH);


    for(;;){
        if (readPin(0,3)){
            ;
        }
        else{
            led.on(RED,0xFFFF);
        }
        if (readPin(0,18)){
            ;
        }
        else{
            led.on(RED,0xF000);
        }
    }
    return -1;
}

0 个答案:

没有答案