0

我目前正在尝试为 Arduino Zero(基于 SAMD21 Cortex M0)编写一个低级位移寄存器(74HC595)。

我已经完成了一个看起来像这样的更高级别的课程:

位寄存器.h

#ifndef BitRegister_h
#define BitRegister_h

#include "Arduino.h"

class BitRegister
{
  public:
    BitRegister(byte dataPin, byte clockPin, byte latchPin, uint8_t registerSize = 1);
    
    void sendData(uint8_t led);
    void shiftOut2(uint8_t bitOrder, uint8_t val);

  private:
    byte m_dataPin;
    byte m_clockPin;
    byte m_latchPin;
    uint8_t m_registerSize; //allows register's cascade
};

#endif

位寄存器.cpp

#include "BitRegister.h"

//**************************************************************
  
BitRegister::BitRegister(byte dataPin, 
                        byte clockPin, 
                        byte latchPin,
                        uint8_t registerSize)
:   m_dataPin(dataPin),
    m_clockPin(clockPin),
    m_latchPin(latchPin),
    m_registerSize(registerSize) //Number of register (if cascade)
{
  pinMode(m_dataPin, OUTPUT);
  pinMode(m_clockPin, OUTPUT);
  pinMode(m_latchPin, OUTPUT);
}

//************************************************************** 

void BitRegister::sendData(uint8_t led)
{
  led -= 1; //first LED is number 1

  digitalWrite(m_latchPin, LOW);
  for(int i = 1; i < m_registerSize + 1; i++){
    int registerNumber = m_registerSize - i; //The number of the register we're working on in the loop
    shiftOut(m_dataPin, m_clockPin, MSBFIRST, ~( 1 << (led - registerNumber*8) ) & 0xFF);
  }

  digitalWrite(m_latchPin, HIGH);
}

void BitRegister::shiftOut2(uint8_t bitOrder, uint8_t val)
{
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        if (bitOrder == LSBFIRST)
            digitalWrite(m_dataPin, !!(val & (1 << i)));
        else    
            digitalWrite(m_dataPin, !!(val & (1 << (7 - i))));

        digitalWrite(m_clockPin, HIGH);
        digitalWrite(m_clockPin, LOW);        
    }
} 

问题是我必须在级联中将它与许多寄存器一起使用,该shiftOut2方法(基于 Arduino 的 shiftOut方法)非常慢(我认为是由于 multi digitalWrite)。

因此,基于此SAMD21 Cortex M0 教程和 Arduino 零引脚图(如下),我尝试创建一个较低级别的移位寄存器类。Arduino 零引脚图

我目前面临的问题是我无法重写我的shiftOut2方法的全部内容,因此对于我的测试,我必须直接在方法的主体中硬写端口号。

我将我的寄存器连接到 Arduino 的引脚 10、11 和 12,它们是 SAMD21 端口 18、16 和 19。

我班级的代码(有效)如下:

LowBitRegister.hBitRegister.h(类名和类构造函数名除外)相同。

低位寄存器.cpp

#include "LowBitRegister.h"

//**************************************************************  

LowBitRegister::LowBitRegister(byte dataPin, 
                        byte clockPin, 
                        byte latchPin,
                        uint8_t registerSize)
:   m_dataPin(dataPin),
    m_clockPin(clockPin),
    m_latchPin(latchPin),
    m_registerSize(registerSize) //Number of register (if cascade)
{
  REG_PORT_DIR0 |= (1 << 18) | (1 << 19) | (1 << 16); //Set dataPin, clockPin and latchPin to OUTPUT
}

//************************************************************** 

void LowBitRegister::sendData(uint8_t led)
{
  led -= 1; //first LED is number 1
  
  REG_PORT_OUT0 &= ~(1 << 16); //Set latchPin to LOW
  
  for(int i = 1; i < m_registerSize + 1; i++){
    int registerNumber = m_registerSize - i; //The number of the register we're working on in the loop
    shiftOut2(MSBFIRST, ~( 1 << (led - registerNumber*8) ) & 0xFF);
  }
  
  REG_PORT_OUT0 |= (1 << 16); //Set latchPin to HIGH
}

void LowBitRegister::shiftOut2(uint8_t bitOrder, uint8_t val)
{
  uint8_t i;

  for (i = 0; i < 8; i++)  {
    if (bitOrder == LSBFIRST)
      digitalWrite(m_dataPin, !!(val & (1 << i)));
    else    
      digitalWrite(m_dataPin, !!(val & (1 << (7 - i))));

    REG_PORT_OUT0 |= (1 << 19); //Set clockPin to HIGH
    REG_PORT_OUT0 &= ~(1 << 19); //Set clockPin to LOW     
  }
}

如您所见,我无法重写的唯一部分是:

digitalWrite(m_dataPin, !!(val & (1 << i)));

digitalWrite(m_dataPin, !!(val & (1 << (7 - i))));

如果您有解决我问题的想法,我将很乐意阅读。

谢谢!

4

1 回答 1

0

我终于找到了一个解决方案(但如果你看到我感兴趣的任何优化):

低位寄存器.h

#ifndef LowBitRegister_h
#define LowBitRegister_h

#include "Arduino.h"


class LowBitRegister
{
  public:
    LowBitRegister(byte dataPin, byte clockPin, byte latchPin, uint8_t registerSize = 1); //Multiple registers cascade
    
    void sendData(uint8_t led);
    void lowShiftOut(uint8_t bitOrder, uint8_t val);

  private:
    byte m_dataPin;
    byte m_clockPin;
    byte m_latchPin;
    uint8_t m_registerSize;
};

#endif

低位寄存器.cpp

#include "LowBitRegister.h"

//**************************************************************  

LowBitRegister::LowBitRegister(byte dataPin, 
                        byte clockPin, 
                        byte latchPin,
                        uint8_t registerSize)
:   m_dataPin(dataPin),
    m_clockPin(clockPin),
    m_latchPin(latchPin),
    m_registerSize(registerSize) //Number of register (if cascade)
{
  REG_PORT_DIR0 |= (1 << m_dataPin) | (1 << m_clockPin) | (1 << m_latchPin); //Set dataPin, clockPin and latchPin to OUTPUT
}

//************************************************************** 

void LowBitRegister::sendData(uint8_t led)
{
  led -= 1; //first LED is number 1
  
  REG_PORT_OUT0 &= ~(1 << m_latchPin); //Set latchPin to LOW
  
  for(int i = 1; i < m_registerSize + 1; i++){
    int registerNumber = m_registerSize - i; //The number of the register we're working on in the loop
    lowShiftOut(MSBFIRST, ~( 1 << (led - registerNumber*8) ) & 0xFF);
  }
  
  REG_PORT_OUT0 |= (1 << m_latchPin); //Set latchPin to HIGH
}

void LowBitRegister::lowShiftOut(uint8_t bitOrder, uint8_t val)
{
  uint8_t i;

  for (i = 0; i < 8; i++) {
    if (bitOrder == LSBFIRST){
      if(val & (1 << i))
        REG_PORT_OUT0 |= (1 << m_dataPin);
      else
        REG_PORT_OUT0 &= ~(1 << m_dataPin);
    }
    else {
      if (val & (1 << (7 - i)))
        REG_PORT_OUT0 |= (1 << m_dataPin);
      else
        REG_PORT_OUT0 &= ~(1 << m_dataPin);
    }
    REG_PORT_OUT0 |= (1 << m_clockPin); //Set clockPin to HIGH
    REG_PORT_OUT0 &= ~(1 << m_clockPin); //Set clockPin to LOW     
  }
}
于 2021-11-23T16:01:59.927 回答