unsigned long counter1 = 0;
const int dataPin = 2; /* DS */
const int clockPin = 4; /* SHCP (clock do Master) */
const int latchPinMaster = 3; /* STCP do Master (também funciona como clock do segundo nível) */
const int latchPinSegundoNivel = 5; /* STCP dos shift registers no segundo nível (também funciona como clock do terceiro nível) */
const int latchPinTerceiroNivel = 6; /* STCP dos shift registers no terceiro nível */
void setup() {
TCCR1A = 0;
// colocando registrador timer counter no modo CTC (Clear Timer on Compare-match)
TCCR1B &= ~(1 << WGM13);
TCCR1B |= (B00000001 << WGM12);
// setando o prescaler para 64 (16 mHz / 64 = 250 kHz)
TCCR1B &= ~(1 << CS12);
TCCR1B |= (1 << CS11);
TCCR1B |= (1 << CS10);
TCNT1 = 0;
OCR1A = 249995; // valor do Compare-match
TIMSK1 = (1 << OCIE1A);
sei(); // habilita interrupts
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPinMaster, OUTPUT);
pinMode(latchPinSegundoNivel , OUTPUT);
pinMode(latchPinTerceiroNivel, OUTPUT);
digitalWrite(clockPin, LOW);
digitalWrite(latchPinMaster, LOW);
digitalWrite(latchPinSegundoNivel, LOW);
digitalWrite(latchPinTerceiroNivel, LOW);
// começo do programa
digitalWrite(dataPin, HIGH); // bit 1
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW); // pulsou o clock, o bit está na posição 0 no Master
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW); // pulsou o clock de novo, o bit está na posição 1 no Master
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW); // pulsou o clock de novo, o bit está na posição 2 no Master
digitalWrite(dataPin, LOW); // economizar energia
digitalWrite(latchPinMaster, HIGH);
digitalWrite(latchPinMaster, LOW); // pulsou o Latch 1, portanto pulsou o clock de todos os secundarios
digitalWrite(latchPinMaster, HIGH);
digitalWrite(latchPinMaster, LOW); // pulsou o Latch 1 de novo, bit na posição 1 no secundário
digitalWrite(latchPinMaster, HIGH);
digitalWrite(latchPinMaster, LOW); // pulsou o Latch 1 de novo, bit na posição 2 no secundário
digitalWrite(latchPinSegundoNivel, HIGH);
digitalWrite(latchPinSegundoNivel, LOW); // pulsou o Latch 2º nivel, portanto pulsou o clock de todos os terciarios
digitalWrite(latchPinSegundoNivel, HIGH);
digitalWrite(latchPinSegundoNivel, LOW); // pulsou o Latch 2º nivel de novo, bit na posição 2 no terciário
digitalWrite(latchPinTerceiroNivel, HIGH);
digitalWrite(latchPinTerceiroNivel, LOW); // pulsou o Latch 3º nivel, mostrou resultado
}
void loop() { // loop vazio
}
ISR(TIMER1_COMPA_vect){ // Rotina de Serviço de Interrupção do timer
counter1++;
}
void Latch1(){
digitalWrite(latchPinMaster, HIGH);
digitalWrite(latchPinMaster, LOW);
}
void Latch2(){
digitalWrite(latchPinSegundoNivel, HIGH);
digitalWrite(latchPinSegundoNivel, LOW);
}
void Latch3(){
digitalWrite(latchPinTerceiroNivel, HIGH);
digitalWrite(latchPinTerceiroNivel, LOW);
}
void EnviaBitNivel3(boolean val, byte pos1, byte pos2, byte pos3){ // função para enviar bit para nivel 3 (interfere com os demais bits)
if( (pos1 < 8) && (pos2 < 8) && (pos3 < 8) ){
if(val){
EnviaBitNivel2(true, pos1, pos2);
}else{
EnviaBitNivel2(false, pos1, pos2);
}
Latch2();
}
}
void EnviaBitNivel2(boolean val, byte pos1, byte pos2){ // função para enviar bit para nivel 2 (interfere com os demais bits)
if( (pos1 < 8) && (pos2 < 8) ){
if(val){
EnviaBitMaster(true, pos1);
}else{
EnviaBitMaster(false, pos1);
}
for(byte i = 0; i <= pos2; i++){
Latch1();
}
}
}
void EnviaBitMaster(boolean val, byte pos){ // função para enviar bit para o controlador master (interfere com os demais bits)
if(pos < 8){
if(val){
digitalWrite(dataPin, HIGH);
}else{
digitalWrite(dataPin, LOW);
}
for(byte i = 0; i <= pos; i++){
// pulsa o clock
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}
}
void EnviaByteMaster(byte valor){ // função BIG ENDIAN para enviar um byte para o shift register
byte mascara0 = 0b00000001;
byte mascara = (mascara0 << 7); //testando bit mais significativo (posição 7 do byte);
EnviaBit(mascara, valor);
mascara = (mascara0 << 6); // testando próximo bit
EnviaBit(mascara, valor);
mascara = (mascara0 << 5); // testando próximo bit
EnviaBit(mascara, valor);
mascara = (mascara0 << 4); // testando próximo bit
EnviaBit(mascara, valor);
mascara = (mascara0 << 3); // testando próximo bit
EnviaBit(mascara, valor);
mascara = (mascara0 << 2); // testando próximo bit
EnviaBit(mascara, valor);
mascara = (mascara0 << 1); // testando próximo bit
EnviaBit(mascara, valor);
EnviaBit(mascara0, valor); //testando bit menos significativo (posição 0 do byte);
}
void EnviaBit(byte mascara, byte valor){ // função para enviar cada bit para o shift register
if(valor & mascara){ // AND lógico do valor com a máscara (FALSE se todos os bits zero)
digitalWrite(dataPin, HIGH);
}else{
digitalWrite(dataPin, LOW);
}
// pulsa o clock
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}