http://fabianoallex.blogspot.com.br/2015/06/arduino-74hc595-e-74hc165-juntos.html
e
http://fabianoallex.blogspot.com.br/2015/05/arduino-texto-com-teclado-matricial-4x3.html
A ideia aqui é mostrar algo prático para ser usado com o 74HC595 e o 74HC165 juntos. E como eu já tinha feito um post falando de teclados matriciais, resolve utilizá-lo como exemplo.
Vídeo:
código-fonte:
/* Criado em 06/06/2015 Por: Fabiano A. Arndt http://www.youtube.com/fabianoallex http://fabianoallex.blogspot.com.br fabianoallex@gmail.com */ /******************************************************************************************** *******************CLASSE Expansor74HC595_74HC165 INICIO********************************* *********************************************************************************************/ class Expansor74HC595_74HC165 { private: int _pin_clock; int _pin_latch; int _pin_data; byte* _pins_out; byte* _pins_in; int _num_cis_out; int _num_cis_in; public: Expansor74HC595_74HC165(int pin_clock, int pin_latch, int pin_data, int num_cis_out, int num_cis_in){ _pin_clock = pin_clock; _pin_latch = pin_latch; _pin_data = pin_data; _num_cis_out = num_cis_out; _num_cis_in = num_cis_in; _pins_out = new byte[num_cis_out]; _pins_in = new byte[num_cis_in]; pinMode(_pin_clock,OUTPUT); pinMode(_pin_latch,OUTPUT); clear(); } void clear(){ for (int i=0; i<_num_cis_out; i++){ _pins_out[i] = B00000000; } update(); } void update(){ digitalWrite(_pin_clock, LOW); digitalWrite(_pin_latch, LOW); digitalWrite(_pin_latch, HIGH); for(int i=max(_num_cis_in, _num_cis_out) * 8 - 1; i>=0; i-- ) { //max -->o for vai até o que tiver mais, ou entradas, ou saidas int pos = i / 8; int pin = 7-(i % 8); if (i < _num_cis_in * 8){ pinMode(_pin_data, INPUT); if ( digitalRead(_pin_data) ){ _pins_in[pos] |= (1 << pin); //set a bit HIGH } else { _pins_in[pos] &= ~(1 << pin); //set a bit LOW } } if (i < _num_cis_out * 8){ pinMode(_pin_data, OUTPUT); digitalWrite(_pin_data, (_pins_out[pos] & (1 << pin)) != 0 ); } digitalWrite(_pin_clock, HIGH); digitalWrite(_pin_clock, LOW); } digitalWrite(_pin_latch, LOW); digitalWrite(_pin_latch, HIGH); pinMode(_pin_data, INPUT); } int read(int pin){ int pos = pin / 8; pin = 7-(pin % 8); if (pos > _num_cis_out) { pos = pos - _num_cis_out; return ( (_pins_in[pos] & (1 << pin)) != 0 ); } else { return ( (_pins_out[pos] & (1 << pin)) != 0 ); } } byte readByte(int num_ci) { if (num_ci >= _num_cis_out) { num_ci = num_ci - _num_cis_out; return _pins_in[num_ci]; } else { return _pins_out[num_ci]; } } void write(int pin, int value){ if (pin >= _num_cis_out*8) { return; } int pos = pin / 8; //pos -> indica qual ci será atualizado. pin = 7-(pin % 8); if (pos > _num_cis_out) { return; //se estiver tentando escrever um pino de entrada, apenas retorna, sem fazer nada. } else { if (value){ _pins_out[pos] |= (1 << pin); //set a bit HIGH } else { _pins_out[pos] &= ~(1 << pin); //set a bit LOW } } } void writeByte(int num_ci, byte b, int first = MSBFIRST) { if (num_ci > _num_cis_out) { return; //se estiver tentando escrever um pino de entrada, apenas retorna, sem fazer nada. } if (first == LSBFIRST) { byte r=0; for(int i=0;i<8;i++) { r |= ((b>>i) & 0b1)<<(7-i); } b = r; } _pins_out[num_ci] = b; } ; }; /******************************************************************************************** *******************CLASSE Expansor74HC595_74HC165 FIM *********************************** *********************************************************************************************/ const int PIN_CLOCK = 4; const int PIN_LATCH = 7; const int PIN_DATA = 12; Expansor74HC595_74HC165 * exp1; /**************************************************************** *********funcao pra ler teclado matricial com 595 e 165********** *****************************************************************/ #define GET_PIN(num_ci, pos) num_ci*8+pos #define col1 GET_PIN(3, 7) //pino do CI 3 (QUARTO CI) 165 - 31 #define col2 GET_PIN(3, 6) //pino do CI 3 (QUARTO CI) 165 - 30 #define col3 GET_PIN(3, 5) //pino do CI 3 (QUARTO CI) 165 - 29 #define lin1 GET_PIN(1, 4) //pino do CI 1 (SEGUNDO CI) 595 - 12 #define lin2 GET_PIN(1, 3) //pino do CI 1 (SEGUNDO CI) 595 - 11 #define lin3 GET_PIN(1, 2) //pino do CI 1 (SEGUNDO CI) 595 - 10 #define lin4 GET_PIN(1, 1) //pino do CI 1 (SEGUNDO CI) 595 - 9 char get_tecla(){ int l[]={lin1, lin2, lin3, lin4}; // Array de 4 posições contendo os 4 pinos de linhas int i = 0, k = 0, t = 0; for (i=0; i<4; i++) { exp1->write(lin1, LOW); exp1->write(lin2, LOW); exp1->write(lin3, LOW); exp1->write(lin4, LOW); exp1->write(l[i],HIGH); exp1->update(); exp1->update(); if(exp1->read(col1)) { t = i*3+1; break; } if(exp1->read(col2)) { t = i*3+2; break; } if(exp1->read(col3)) { t = i*3+3; break; } } if (t > 0 ){ if (t >= 1 && t<=9){ return char(t+48); } //48--> ASCII: o charactere '1' na tabela ascii é 49º item, o '2' é o 50º item e assim por diante if (t==10) { return '*'; } if (t==11) { return '0'; } if (t==12) { return '#'; } } return '\0'; } /**************************************************************** *********fim da funcao pra ler teclado matricial com 595 e 165*** *****************************************************************/ /**************************************************************** ********************************setup e loop********************** *****************************************************************/ void setup() { exp1 = new Expansor74HC595_74HC165(PIN_CLOCK, PIN_LATCH, PIN_DATA, 2, 2); Serial.begin(9600); } unsigned long millis_alt = 0; void loop() { if ( (millis() - millis_alt) > 1000 ){ exp1->write(15, !exp1->read(15)); exp1->update(); millis_alt = millis(); } if (get_tecla() != '\0'){ Serial.println( get_tecla() ); } } /**************************************************************** ********************************fim setup e loop****************** *****************************************************************/