sexta-feira, 5 de junho de 2020

HEF4094

Apesar de ser mais simples que o visto anteriormente, o HEF4094 também é um conversor serial/paralelo de 8 bits. A diferença é em sua ferramenta de expansão pois possui duas portas seriais implementáveis a outros circuitos.

Nele temos quatro portas principais de controle, entrada de Dados (D), sinal de Clock (CP), Strobe (STR) e Enable (OE).

Em aplicação geral, as portas CP e STR são ligadas em paralelo para entrada do Clock e caso não seja necessario o controle Enable (OE) deve ser ligado ao GND.

O Protocolo de comunicação em sua simplicidade não foge do 74HC595 que são basicamente identicos. Abaixo temos o diagrama de timing da comunicação SPI:

Os níveis lógicos de entrada para transição devem ser inferior a +1,5V para 0 (baixo) e superior a +3,5V para 1 (alto).

O que diferencia este circuito integrado também é a voltagem de operação, que pode ser de no máximo +18V e a corrente em cada saída Qs deve ser de no máximo 10mA contínuo.

Na próxima imagem temos o diagrama esquemático interno do circuito lógico empregado no HEF4094:

A imagem seguinte mostra a pinagem encontrada e aplicada ao HEF4094 de 16 pinos:


Símbolo

Pino

Descrição

STR

1

Strobe

D

2

Data

CP

3

Clock

QP0 a QP7

4 a 7, 14 a 11

Saída Paralela

VSS

8

Terra (0V)

QS1

9

Saída Serial 1

QS2

10

Saída Serial 2

OE

15

Enable

VDD

16

Fonte (+V)


Para implementarmos este integrado serial/paralelo em um circuito devemos prestar a atenção em na alimentação do circuito, pois os valores de nível lógico de entrada dependem da voltagem aplicada em VDD, pois ele é relativo. Deve ser consultada a folha de dados do componente para mais informações.

Para implementar mais circuitos em uma mesma linha de comunicação deve-se definir um CI como Controle Continuo e posteriormente os outros como escravos assumindo o diagrama seguinte.

Abaixo temos o exemplo de rotina baseada em linguagem C para microcontroladores PIC da Microchip feitos em CCS.


<main.c>

#include <18F4550.h>

#use delay(clock=20000000)

#fuses INTHS,NOWDT,NOPROTECT

 

#define DAT PIN_B0

#define CLK PIN_B1

 

unsigned int j;

unsigned int Valor;

const char Segments[1][8] = {{

   0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f

}};

 

const char Valores[1][7] = {{

   0x01,0x02,0x03,0x04,0x05,0x06,0x07

}};

 

void Escreve4094(char Dados){

   for(j = 0x40; j > 0; j = j >> 1) {

     if(Dados & j){

       output_high(DAT);

     }else{

       output_low(DAT);

     }

     output_high(CLK);

     output_low(CLK);

  }

}

 

void main() {

   setup_oscillator(OSC_8MHZ | osc_intrc);       

   delay_ms(1000);

   while(TRUE) {

      output_low(DAT);

      output_low(CLK);

      Valor = 1;

      Escreve4094(Segments[0][Valor]);

      delay_ms(1);

   }

}


Em caso de utilização de microcontroladores com portas Open-Drain é aconselhado o uso de resistores Pull-Up para fornecer as tensões de nível lógico alto (+V) para as linhas de Data, Clock, Strobe  e Enable do HEF4094.

Seguindo com o estudo do HEF4094, podemos encontrar diversas aplicações para ele, desde a controle de periféricos, displays, luminosos,etc. Sua aplicação é de importante valor para microcontroladores de baixo numero de portas I/O, onde podemos multiplicar de duas portas no micro para oito ou mais portas dependendo de quantos HEF4094 empregarmos.

Exemplo de utilização do HEF4094 para controle de um display LCD 16X2:

No esquema acima podemos implementar o codigo feito em linguagem C para microcontroladores PIC desenvolvidos na plataforma CCS.


<main.c>

#include <18F4550.h>

#use delay(clock=4000000)

#fuses INTHS


#include <3wire_lcd.c>


void main(void){

   lcd_initialize();

   lcd_cmd(LCD_CLEAR);

   delay_ms(2000);

   while( true ){  

      lcd_cmd(LCD_CLEAR);

      lcd_goto(1, 1); 

      printf(lcd_out, "EletroGB!");

      delay_ms(1000);

   }

}


<3wire_lcd.c>

#define LCD_DATA_PIN        PIN_b0
#define LCD_CLOCK_PIN        PIN_b1
#define LCD_EN_PIN        PIN_b2
#define LCD_FIRST_ROW          0x80
#define LCD_SECOND_ROW         0xC0
#define LCD_THIRD_ROW          0x94
#define LCD_FOURTH_ROW         0xD4
#define LCD_CLEAR              0x01
#define LCD_RETURN_HOME        0x02
#define LCD_CURSOR_OFF         0x0C
#define LCD_UNDERLINE_ON       0x0E
#define LCD_BLINK_CURSOR_ON    0x0F
#define LCD_MOVE_CURSOR_LEFT   0x10
#define LCD_MOVE_CURSOR_RIGHT  0x14
#define LCD_TURN_ON            0x0C
#define LCD_TURN_OFF           0x08
#define LCD_SHIFT_LEFT         0x18
#define LCD_SHIFT_RIGHT        0x1E
short RS;

void lcd_write_nibble(unsigned int8 n){
   unsigned int8 i;
   output_low(LCD_CLOCK_PIN);
   output_low(LCD_EN_PIN);
   for( i = 8; i > 0; i = i >> 1){
     if(n & i){
        output_high(LCD_DATA_PIN);
     }else{
        output_low(LCD_DATA_PIN); }
     Delay_us(10);
     output_high(LCD_clock_PIN);
     Delay_us(10);
     output_low(LCD_clock_PIN);
   }
   if(RS){
      output_high(LCD_DATA_PIN);
   }else{
      output_low(LCD_DATA_PIN); }
   for(i = 0; i < 2; i++){
      Delay_us(10);
      output_high(LCD_clock_PIN);
      Delay_us(10);
      output_low(LCD_clock_PIN);
   }
   output_high(LCD_EN_PIN);
   delay_us(2);
   output_low(LCD_EN_PIN);
}

void LCD_Cmd(unsigned int8 Command){
  RS = 0;
  lcd_write_nibble(Command >> 4);
  lcd_write_nibble(Command & 0x0F);
  if((Command == 0x0C) || 
     (Command == 0x01) || 
     (Command == 0x0E) || 
     (Command == 0x0F) || 
     (Command == 0x10) || 
     (Command == 0x1E) || 
     (Command == 0x18) || 
     (Command == 0x08) || 
     (Command == 0x14) || 
     (Command == 0x02))
    Delay_ms(50);
}

void LCD_GOTO(unsigned int8 col, unsigned int8 row){switch(row){
      case 1: LCD_Cmd(0x80 + col-1); break;
      case 2: LCD_Cmd(0xC0 + col-1); break;
      case 3: LCD_Cmd(0x94 + col-1); break;
      case 4: LCD_Cmd(0xD4 + col-1); break;
   }
}

void LCD_Out(unsigned int8 LCD_Char){
   RS = 1;  
   lcd_write_nibble(LCD_Char >> 4);
   delay_us(10);
   lcd_write_nibble(LCD_Char & 0x0F);
   break;
}

void LCD_Initialize(){
   RS = 0;
   output_low(LCD_DATA_PIN);
   output_low(LCD_CLOCK_PIN);
   output_low(LCD_EN_PIN);
   output_drive(LCD_DATA_PIN);
   output_drive(LCD_CLOCK_PIN);
   output_drive(LCD_EN_PIN); 
   delay_ms(40);
   lcd_Cmd(3); delay_ms(5);
   lcd_Cmd(3); delay_ms(5);
   lcd_Cmd(3); delay_ms(5);
   lcd_Cmd(2); delay_ms(5);
   lcd_Cmd(0x28); delay_ms(50);
   lcd_Cmd(0x0C); delay_ms(50);
   lcd_Cmd(0x06); delay_ms(50);
   lcd_Cmd(0x0C); delay_ms(50);
}


Nenhum comentário:

Postar um comentário