低级移位寄存器 class 使用 Arduino Zero 的端口操作
Low-level bit shift register class using port manipulation for Arduino Zero
我目前正在尝试为 Arduino Zero(基于 SAMD21 Cortex M0)编写低级移位寄存器 (74HC595)。
我已经完成了更高级别的 class 看起来像这样:
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);
}
}
问题是我必须在级联蚂蚁中与许多寄存器一起使用它 shiftOut2
方法(基于 Arduino 的 shiftOut
方法)真的很慢(我认为由于多个 digitalWrite
).
所以基于此SAMD21 Cortex M0 tutorial and on the Arduino Zero Pinout Diagram (below), I tried to create a lower-level of my bit shift register class.
我目前面临的问题是我无法重写我的 shiftOut2
方法的全部内容,因此对于我的测试,我必须直接在方法主体中硬写端口号。
我将我的寄存器连接到 Arduino 的引脚 10、11 和 12,它们是 SAMD21 端口 18、16 和 19。
我的 class 代码如下:
LowBitRegister.h
与 BitRegister.h
相同(class 名称和 class 构造函数名称除外)。
低BitRegister.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))));
如果你有解决我问题的想法,我会很乐意阅读它。
谢谢!
我终于找到了解决方案(但如果您看到我感兴趣的任何优化):
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
}
}
我目前正在尝试为 Arduino Zero(基于 SAMD21 Cortex M0)编写低级移位寄存器 (74HC595)。
我已经完成了更高级别的 class 看起来像这样:
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);
}
}
问题是我必须在级联蚂蚁中与许多寄存器一起使用它 shiftOut2
方法(基于 Arduino 的 shiftOut
方法)真的很慢(我认为由于多个 digitalWrite
).
所以基于此SAMD21 Cortex M0 tutorial and on the Arduino Zero Pinout Diagram (below), I tried to create a lower-level of my bit shift register class.
我目前面临的问题是我无法重写我的 shiftOut2
方法的全部内容,因此对于我的测试,我必须直接在方法主体中硬写端口号。
我将我的寄存器连接到 Arduino 的引脚 10、11 和 12,它们是 SAMD21 端口 18、16 和 19。
我的 class 代码如下:
LowBitRegister.h
与 BitRegister.h
相同(class 名称和 class 构造函数名称除外)。
低BitRegister.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))));
如果你有解决我问题的想法,我会很乐意阅读它。
谢谢!
我终于找到了解决方案(但如果您看到我感兴趣的任何优化):
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
}
}