我目前正在尝试为 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 零引脚图(如下),我尝试创建一个较低级别的移位寄存器类。
我目前面临的问题是我无法重写我的shiftOut2
方法的全部内容,因此对于我的测试,我必须直接在方法的主体中硬写端口号。
我将我的寄存器连接到 Arduino 的引脚 10、11 和 12,它们是 SAMD21 端口 18、16 和 19。
我班级的代码(有效)如下:
LowBitRegister.h
与BitRegister.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))));
如果您有解决我问题的想法,我将很乐意阅读。
谢谢!