Bajo nivel de bits de registro de desplazamiento de la clase utilizando el puerto de manipulación para Arduino Zero

0

Pregunta

Actualmente estoy tratando de código debajo de la palanca de bits de registro de desplazamiento (integrado 74hc595) para Arduino Zero (que se basa en SAMD21 Cortex M0).

Ya he hecho un mayor nivel de clase se parece a :

BitRegister.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

BitRegister.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);        
    }
} 

El problema es que tengo que usarlo con muchos registros en cascada de la hormiga shiftOut2 método (basado en Arduino shiftOut método) es realmente lento (creo que debido a las múltiples digitalWrite).

Así que basado en este SAMD21 Cortex M0 tutorial y en el Arduino Zero Pinout Diagrama a continuación), traté de crear un nivel inferior de mi bits de registro de desplazamiento de la clase. Arduino Zero Pinout Diagram

El problema que estoy enfrentando actualmente es que yo no administrar a reescribir la totalidad de mi shiftOut2 método por lo que para mi prueba de que tengo que escribir los números de puertos en el disco duro directamente en el método del cuerpo.

Puedo conectar mi de los registros de Arduino pines 10, 11 y 12, que son SAMD21 puertos de 18, 16 y 19.

El código de mi clase (que funciona) es la siguiente :

LowBitRegister.h es el mismo BitRegister.h (excepto el nombre de la clase y constructor de la clase nombre).

LowBitRegister.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     
  }
}

Como se puede ver, las únicas partes yo no administrar a reescribir son :

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

y

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

Si usted tiene una idea para solucionar mi problema, voy a ser feliz de leer.

Gracias!

1

Mejor respuesta

0

Por fin he encontrado una solución (pero si usted ve cualquier optimización estoy interesado) :

LowBitRegister.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

LowBitRegister.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-23 16:09:17

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................