3

8、16、および 32 ビット値をシフトアウトできる 74HC595 シフトレジスタにデータをシフトアウトできる関数を作成しようとしています。

オーバーロードされた関数を使用すると、次のようになります。

/**********************************************************************************
* Software SPI Pin Settings
*********************************************************************************/
#define SPIPINPORT  PORTB   //The Port that the Pins are on.  
#define LatchPin    2   //_RCLK  Shift register clock pin       
#define DataPin     3   //SER DS Serial data input              
#define ClockPin    5

/**********************************************************************************
* Preproccesor PIN to PIN Mask
*********************************************************************************/
#define LATCHMASK   (1 << LatchPin) 
#define MOSIMASK    (1 << DataPin)              
#define CLOCKMASK   (1 << ClockPin) 

/**********************************************************************************
* Macros
*********************************************************************************/
#define tggl(port,bit) (port)^=(1<<(bit))
#define LATCH   (SPIPINPORT &=~ LATCHMASK) 
#define unLATCH (SPIPINPORT |= LATCHMASK)  
#define PULSE   { tggl(SPIPINPORT,ClockPin); tggl(SPIPINPORT,ClockPin); }


void zShiftClass::ShiftOut(uint8_t value)
{
    LATCH;
    for (uint8_t i = 0; i <= 7; i++) 
    {   
        if( !!(value&(1<<i)) == true)   //If value is not a 1, turn off MOSIMASK
        { SPIPINPORT |= MOSIMASK; } 
        else    
        { SPIPINPORT &= ~MOSIMASK; }        

        PULSE;  //Pulse the Clock
    }
    unLATCH;
}

void zShiftClass::ShiftOut(uint16_t value)
{
    LATCH;
    for (uint8_t i = 0; i <= 15; i++) 
    {   
        if( !!(value&(1<<i)) == true)   //If value is not a 1, turn off MOSIMASK
        { SPIPINPORT |= MOSIMASK; } 
        else    
        { SPIPINPORT &= ~MOSIMASK; }        

        PULSE;  //Pulse the Clock
    }
    unLATCH;
}


void zShiftClass::ShiftOut(uint32_t value)
{
    LATCH;
    for (uint8_t i = 0; i <= 31; i++) 
    {   
        if( !!(value&(1<<i)) == true)   //If value is not a 1, turn off MOSIMASK
        { SPIPINPORT |= MOSIMASK; } 
        else    
        { SPIPINPORT &= ~MOSIMASK; }        

        PULSE;  //Pulse the Clock
    }
    unLATCH;
}

そして、このテンプレートを使用してこれらの関数を置き換えたい:

template<typename TYPE>void Shift(TYPE value)
{
    uint8_t loops = (( 8 * sizeof(value) ) - 1 );

    LATCH;
    for (uint8_t i = 0; i <= loops; i++) 
    {   
        if( !!(value&(1<<i)) == true)   //If value is not a 1, turn off MOSIMASK
        { SPIPINPORT |= MOSIMASK; } 
        else    
        { SPIPINPORT &= ~MOSIMASK; }        

        PULSE;  //Pulse the Clock
    }
    unLATCH;
}

コンパイルすると、次のエラーが発生します。

 Compiling 'zLEDArray' for 'Arduino Uno' 
 zLEDArray.ino : variable or field 'Shift' declared void 
 zLEDArray.ino : 'TYPE' was not declared in this scope
 Error compiling

私は何を間違っていますか?

4

2 に答える 2

3

ino ファイルに正しい前方宣言を追加することで、エラーを取り除くことができます。直観的に言えば、関数を使用する前に関数を定義する場合は、これも行う必要があります。

template <typename TYPE> void Shift(TYPE value);

// you may use the function here or you can have the declaration
// immediately before the definition

template<typename TYPE>void Shift(TYPE value)
{
    // your implementation
}

これが当てはまる理由の説明は、jdr5ca's answer にあります。明確にしていただきありがとうございます。試行錯誤でこれを見つけました。

于 2016-01-10T14:04:49.803 に答える