Expansão de I/O - 74HC164
Autor: Jean Carlos | Publicado: 2012-09-12T18:32:00-07:00

&nbsp; Dando prosseguimento ao último post, venho apresentar um componente bem conhecido dos entusiastas da eletrônica digital, trata-se do circuito integrado SN74HC164, um conversor de dados serial para paralelo de 8 bits também conhecido por registrador de deslocamento ou apenas shift register, sendo este componente facilmente encontrado no mercado brasileiro.  SN74HC164 Este Ci possui um pino para entrada de dados, sendo esta entrada disponibilizada por meio de uma porta AND (entradas A e B), o que facilita o controle de entrada dos dados.  Além dos pinos de entrada de dados, A e B, podemos encontrar um pino para entrada do sinal de clock, podendo operar até 25MHz com a alimentação de 5V, um pino de /CLR que recebe a função de limpar todas as saídas do shift register além dos 8 pinos de saída, pinos estes que podem fornecer uma corrente máxima de 25mA o que já é suficiente para acender de forma eficiente um LED, porém devemos atentar para o fato da corrente máxima admissível entre VDD e VSS que é de 50mA não seja ultrapassada. Lógica de operação:   Como podemos observar, este CI não possui um pino para controle de ativação das saídas, ou seja, assim que enviarmos o conteúdo dos bits serialmente, estas informações aparecerão nos pinos de saída de forma indesejável, podendo causar danos ao hardware ou mão funcionamento do mesmo. Uma alternativa ao SN74HC164 é o circuito integrado CD4094 que abordaremos em um próximo post.    Exemplo de Uso Neste exemplo vamos utilizar o SN74HC164 para adicionar 8 LEDs à placa PK2Lab utilizando apenas 2 pinos do microcontrolador, neste caso não será utilizado o pino de reset e o mesmo deverá ser conectado ao VCC, este recurso seria interessante no caso de controlarmos displays de 7 segmentos onde teríamos a possibilidade de efetuar o apagamento de todos os dígitos simultaneamente ao aplicarmos um nível lógico baixo no pino 9.  Caso seja necessário aumentar a quantidade de saídas podemos interligar mais de um shift register em cascata, basta interligarmos o pino 13 (MSB) ao pino de entrada de dados do próximo SN74HC164, assim sucessivamente.   Um exemplo de utilização em cascata deste componente pode ser visto na placa DE-DP011, comercializada pela Sure Electronics, que consiste de um conjunto de cinco shift registers serializados para a apresentação de 40 Leds.  Abaixo podemos observar o funcionamento desta placa em uma IHM, fornecendo indicação visual sobre distância e tensão de bateria.  Esquema DE-DP011 Para nosso exemplo utilizaremos apenas um CI e 8 Leds para simular um PORT auxiliar, para isto vamos usar o primeiro esquema apresentado neste post.     Software O Software desenvolvido para este exemplo consiste basicamente de uma função que irá transmitir os dados a serem exibidos no “PORTAux” e uma rotina principal que incrementa uma variável contador a cada 100ms, mostrando o valor de forma binária nos Leds conectados ao SN74HC164. Para a utilização de mais de um CI cascateado, basta efetuar a chamada da função na mesma proporção de CIs utilizados. /****************************************************************************** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JL Audio Manutenção Eletrônica Data: 09/2012Autor: Jean CarlosProjeto: Registrador de deslocamento SN74HC164Microprocessador: PIC18F4520Clock do processador: 8MHzEstação de desenvolvimento: PK2Lab V 1.1Compilador: MikroC PRO V 4.60.0.0Versão atual: 1.0Descrição: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Demonstração do uso de shift register para expansão de saídas *******************************************************************************/// Inicializações do programa // Configuração do LCD da placa PK2Lab V.1.1 sbit LCD_RS at RB2_bit;sbit LCD_EN at RB3_bit;sbit LCD_D4 at RB4_bit;sbit LCD_D5 at RB5_bit;sbit LCD_D6 at RB6_bit;sbit LCD_D7 at RB7_bit; sbit LCD_RS_Direction at TRISB2_bit;sbit LCD_EN_Direction at TRISB3_bit;sbit LCD_D4_Direction at TRISB4_bit;sbit LCD_D5_Direction at TRISB5_bit;sbit LCD_D6_Direction at TRISB6_bit;sbit LCD_D7_Direction at TRISB7_bit; //******************************************************************************// Variáveis Globais unsigned short contador = 0; // Variavel para contagem de 0 a 255.char txt[4];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Variavel para conversão de dados. //******************************************************************************// Rotinas Auxiliares #define Clear&nbsp;&nbsp;&nbsp; PORTC.B0#define Clock&nbsp;&nbsp;&nbsp; PORTC.B1#define Ser_Out&nbsp; PORTC.B2 void SN74HC164(char SN74HC164_Value){short SN74HC164_Aux;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Variável local de controle do laço forfor(SN74HC164_Aux = 0; SN74HC164_Aux &lt; 8; SN74HC164_Aux ++)&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; if( SN74HC164_Value &amp; 0b10000000)&nbsp; Ser_Out = 1;&nbsp; // Máscara o sétimo bit…&nbsp;&nbsp;&nbsp;&nbsp; else Ser_Out = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // e verifica se é zero ou um.&nbsp;&nbsp;&nbsp;&nbsp; SN74HC164_Value = SN74HC164_Value &lt;&lt; 1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Rotaciona o próximo bit&nbsp;&nbsp;&nbsp;&nbsp; Clock = 1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Pulsa o clock para envio do bit&nbsp;&nbsp;&nbsp;&nbsp; Delay_us(1);&nbsp;&nbsp;&nbsp;&nbsp; Clock = 0;&nbsp;&nbsp;&nbsp; }Ser_Out = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Mantém a linha de dados em nível baixo} //******************************************************************************//Rotina Principal void main(){TRISA = 0b00000000;PORTA = 0b00000000;TRISB = 0b00000000;PORTB = 0b00000000;TRISC = 0b00000000;PORTC = 0b00000000;TRISD = 0b00000000;PORTD = 0b00000000;TRISE = 0b00000000;PORTE = 0b00000000;ADCON1 = 0X0F;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Entradas digitais.OSCCON.B5 = 1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Ajusta oscilador interno para 8MHzOSCCON.B4 = 1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Ajusta oscilador interno para 8MHz Lcd_Init();Lcd_Cmd(_Lcd_Cursor_Off);Lcd_Cmd(_LCD_CLEAR);Lcd_Out(1,1,"***&nbsp; PK2Lab&nbsp; ***");Lcd_Out(2,1,"Shift&nbsp; SN74HC164");Delay_ms(1000);Lcd_Out(2,1,"Contador:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "); while(1){ByteToStr(Contador, txt);&nbsp;&nbsp; // Converte o byte numa string para impressão no LCDLcd_Out(2, 11, txt);SN74HC164(Contador);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Envia os dados para o SN74HC164Delay_ms(100);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Delay entre incrementosContador ++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Incremento da variável em uma unidade}//while(1)}//main //********************************************************************************************** Abaixo podemos observar os níveis lógicos capturados através do analisador lógico da própria PK2Lab. O pino de dados está conectado ao CH1 e o pino de clock está conectado ao CH2. Nesta captura podemos observar o valor do contador igual a 1.  Na tela abaixo podemos verificar a captura do contador igual a 128, podemos notar que o formato de envio dos dados é enviando primeiro o bit menos significativo (LSB).  Bom pessoal, segue o vídeo do projeto em funcionamento, qualquer dúvida ou sugestão deixem um comentário pois será muito bem vindo!  Código do projeto