74HC595 Interface com display de 7 segmentos e microcontrolador Pic

Tempo de leitura: 7 minutes

Aprenda a fazer a interface 74HC595 com um display de 7 segmentos e microcontrolador Pic. Usando um registrador de deslocamento 74HC595 para acionar displays de 7 segmentos com o microcontrolador PIC16F877A, podemos salvar os pinos GPIO do microcontrolador PIC. Neste tutorial, aprendemos a interface de um dígito e 7 segmentos de 4 dígitos com o microcontrolador PIC16F877A usando um IC de registro de deslocamento de entrada serial e saída paralela.

 

Por que precisamos usar 74HC595?

No último tutorial sobre interface de display de 7 segmentos com PIC16F87A, vimos que se conectarmos um dispositivo de 7 segmentos diretamente com o microcontrolador Pic, precisaremos de 8 pinos GPIO de MCU. Da mesma forma, se usarmos displays de sete segmentos de dois dígitos, três dígitos e quatro dígitos, precisaremos de mais pinos GPIO, mesmo se usarmos as técnicas de multiplexação para salvar os pinos do microcontrolador.

Portanto, usando um registrador de deslocamento serial 74HC595, podemos salvar os pinos MCU GPIO e usá-los para outros fins. Por exemplo, se usarmos este IC registrador de deslocamento serial, podemos fazer interface de 7 segmentos com PIC16F877A usando apenas três pinos, em vez de usar 8 pinos GPIO.

 

Pré-requisitos

Para entender completamente este tutorial, você deve conhecer estes conceitos:

  • Primeiro, você deve saber como usar os pinos de saída digital do PIC16F877A

Em segundo lugar, você deve entender o funcionamento e a pinagem deste IC:

  • 74HC595 Trabalho de Pinagem e Aplicações

No último tutorial, vimos como fazer a interface do 74HC595 com um microcontrolador pic. Nesse post, controlamos 8 LEDs com este CI de registrador de deslocamento e usando apenas três pinos de saída digital do microcontrolador PIC16F877A.

 

74HC595 Interface com 7 segmentos

Para demonstração, tomaremos dois exemplos. Em primeiro lugar, faremos a interface de um dispositivo de um dígito. Em segundo lugar, aprenderemos a interface do display de sete segmentos de 4 dígitos usando 74HC595.

Diagrama esquemático de interface de 7 segmentos de um dígito
Este diagrama esquemático mostra a conexão entre o registrador de deslocamento IC, PIC16F877A e o ânodo comum de um dígito de sete segmentos.

Se você já tiver os posts mencionados acima e especialmente a interface do registrador de deslocamento com o PIC16F877A, você deve entender este diagrama esquemático facilmente, exceto para conexões de 7 segmentos.

Como você pode ver no diagrama esquemático, conectamos o 74HC595 com a unidade de exibição na ordem inversa dos pinos de saída (Q0-Q7) de acordo com esta tabela.

74HC595Pinos do 7-Segment
Q7A
Q6B
Q5C
Q4D
Q3E
Q2F
Q1G
Q0DP

Isso ocorre porque o registrador de deslocamento emite primeiro o bit MSB e o LSB no final. Portanto, conectamos Q7 a a, Q6 a b e assim por diante. A saída Q0 não é usada porque será usada para acionar o pino dp do dispositivo de 7 segmentos. Se o seu dispositivo também tiver pino dp, conecte o pino Q0 ao pino dp.

Visor de um dígito do código Mikroc

Este código é escrito usando o compilador MikroC for Pic. Crie um novo projeto com o compilador MikroC selecionando o microcontrolador PIC16F877A e defina a frequência para 8MHz. Se você não sabe como criar um novo projeto no mikroC, sugerimos que leia este post:

  • Escreva seu primeiro programa em MikroC para PIC Compiler
sbit DATA_pin at  PORTC.B1;
sbit LATCH_pin at PORTC.B2;
sbit CLCOK_pin at PORTC.B0;

unsigned char binary_pattern[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
unsigned int counter=0;

void clock_signal(void){
   CLCOK_pin = 1;
    delay_us(500);
   CLCOK_pin = 0;
    delay_us(500);
}

void latch_enable(void)
   {
    LATCH_pin = 1;
    delay_us(500);
    LATCH_pin = 0;
    }

void send_data(unsigned int data_out)
{
    int i;
    unsigned hold;
    for (i=0 ; i<8 ; i++)
    {
        DATA_pin = (data_out >> i) & (0x01);
        clock_signal();
    }
    latch_enable(); // Data finally submitted
}

void main()
{
  TRISC.B0 = 0; // Set  DATA_pin as output pin
  TRISC.B1 = 0; // Set  CLCOK_pin as output pin
  TRISC.B2 = 0; // Set LATCH_pin as output pin
  while(1)
      {
         send_data(binary_pattern[counter]);
         counter++;
         if(counter>9)
         counter =0;
         delay_ms(1000);
      }
}

 

Como o Código funciona?

Este código funciona de forma semelhante ao código do 74HC595 fazendo interface com o microcontrolador PIC16F877A, exceto pela parte do loop “enquanto”. Primeiro, inicializamos os códigos de exibição para exibição de sete segmentos do tipo ânodo comum usando uma matriz.

unsigned char binary_pattern[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

Dentro do loop while, passamos os valores dos códigos de exibição para a função send_data() com a ajuda de uma variável de contador. A variável do contador é incrementada a cada segundo e usada para exibir o valor atualizado. Quando o valor do contador se torna igual a 9, redefinimos o valor do contador para zero.

send_data(binary_pattern[counter]);
        counter++;
        if(counter>9)
        counter =0;
        delay_ms(1000);

 

Visor de um dígito com código MPLAB XC8

Este código é para o compilador MPLAB XC8. Se você não sabe como usar o compilador MPLAB e XC8, você pode ler este guia completo e detalhado:

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = ON         // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
#include <xc.h>
#define DATA_pin PORTCbits.RC1
#define LATCH_pin  PORTCbits.RC2
#define CLCOK_pin  PORTCbits.RC0
#define _XTAL_FREQ 8000000 //Crystal Frequency, used in delay

unsigned char binary_pattern[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
unsigned int counter=0;

void clock_signal(void){
   CLCOK_pin = 1;
    __delay_us(500);
   CLCOK_pin = 0;
    __delay_us(500);
}

void latch_enable(void)
   {
    LATCH_pin = 1;
    __delay_us(500);
    LATCH_pin = 0;
    }

void send_data(unsigned int data_out)
{
    int i;
    for (i=0 ; i<8 ; i++)
    {
        DATA_pin = (data_out >> i) & (0x01);
        clock_signal();
    }
    latch_enable(); // Data finally submitted
}

void main(void)
{
  TRISC0 = 0; // Set  DATA_pin as output pin
  TRISC1 = 0; // Set  CLCOK_pin as output pin
  TRISC2 = 0; // Set LATCH_pin as output pin
    while(1)
      {
       send_data(binary_pattern[counter]);
         counter++;
         if(counter>9)
         counter =0;
         __delay_ms(1000);
      
      }
  return;
}

Esquema de interface de exibição de 4 dígitos e 7 segmentos

Este esquema mostra a interface de um display de 7 segmentos de 4 dígitos com um registrador de deslocamento 74HC595 e microcontrolador PIC16F877A. Como você pode ver neste diagrama esquemático, usando 74HC595, salvamos 5 pinos GPIO do microcontrolador PIC16F877A que é usado para acionar o display de sete segmentos de 4 dígitos. Shift register IC usado para enviar o código de exibição de dígitos para o dispositivo de 7 segmentos e 4 pinos GPIO (RB0-RB3) controlam cada exibição de dígito.

 

MikroC Code

sbit digit1 at PORTB.B0;
sbit digit2 at PORTB.B1;
sbit digit3 at PORTB.B2;
sbit digit4 at PORTB.B3;
sbit DATA_pin at  PORTC.B1;
sbit LATCH_pin at PORTC.B2;
sbit CLCOK_pin at PORTC.B0;

unsigned char binary_pattern[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
unsigned int counter=0;
unsigned int a1,a2,a3,a4; // temporary variables to store data of adc

void clock_signal(void){
   CLCOK_pin = 1;
    delay_us(500);
   CLCOK_pin = 0;
    delay_us(500);
}

void latch_enable(void)
   {
    LATCH_pin = 1;
    delay_us(500);
    LATCH_pin = 0;
    }

void send_data(unsigned int data_out)
{
    int i;
    unsigned hold;
    for (i=0 ; i<8 ; i++)
    {
        DATA_pin = (data_out >> i) & (0x01);
        clock_signal();
    }
    latch_enable(); // Data finally submitted
}

void main()
{
  TRISC.B0 = 0; // Set  DATA_pin as output pin
  TRISC.B1 = 0; // Set  CLCOK_pin as output pin
  TRISC.B2 = 0; // Set LATCH_pin as output pin
  TRISB=0x00;
  PORTB = 0X00;
  digit1 = 0;
  digit2 = 0;
  digit3 = 0;
  digit4 = 0;
  while(1)
      {
         a1 = counter / 1000;   // holds 1000's digit
         a2 = ((counter/100)%10); // holds 100's digit
         a3 = ((counter/10)%10);  // holds 10th digit
         a4 = (counter%10);  // holds unit digit value
         send_data(binary_pattern[a1]); // send 1000's place data to fourth digit
        digit1=1;   //  turn on forth display unit
        delay_ms(3);
        digit1=0;   //  turn off forth display unit
        send_data(binary_pattern[a2]);  // send 100's place data to 3rd digit
        digit2=1;    //  turn on 3rd display unit
        delay_ms(3);
        digit2=0;  //  turn off 3rd display unit
        send_data(binary_pattern[a3]);  // send 10th place data to 2nd digit
        digit3 = 1;  //  turn on 2nd display unit
        delay_ms(3);
       digit3 = 0;   //  turn off 2nd display unit
       send_data(binary_pattern[a4]);  // send unit place data to 1st digit
       digit4 = 1;  //  turn on 1st display unit
       delay_ms(3);
       digit4 = 0;  //  turn off 1st display unit
         counter++;
         if(counter>9999)
         counter =0;
         //delay_ms(1000);
      }
}

MPLAB XC8 Code

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = ON        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#include <xc.h>

#define DATA_pin PORTCbits.RC1
#define LATCH_pin  PORTCbits.RC2
#define CLCOK_pin  PORTCbits.RC0
#define digit1 PORTBbits.RB0
#define digit2 PORTBbits.RB1
#define digit3 PORTBbits.RB2
#define digit4 PORTBbits.RB3
#define _XTAL_FREQ 2000000 //Crystal Frequency, used in delay

unsigned char binary_pattern[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
unsigned int counter=0;
unsigned int a,b,c,d;

void clock_signal(void){
   CLCOK_pin = 1;
    __delay_us(500);
   CLCOK_pin = 0;
    __delay_us(500);
}

void latch_enable(void)
   {
    LATCH_pin = 1;
    __delay_us(500);
    LATCH_pin = 0;
    }

void send_data(unsigned int data_out)
{
    int i;
    for (i=0 ; i<8 ; i++)
    {
        DATA_pin = (data_out >> i) & (0x01);
        clock_signal();
    }
    latch_enable(); // Data finally submitted
}

void main(void)
{
  TRISC0 = 0; // Set  DATA_pin as output pin
  TRISC1 = 0; // Set  CLCOK_pin as output pin
  TRISC2 = 0; // Set LATCH_pin as output pin
  TRISB=0X00;
  digit1 = 0;
  digit2 = 0; 
  digit3 = 0;
  digit4 = 0;
    while(1)
      {
        
         a = counter / 1000;   // holds 1000's digit
         b = ((counter/100)%10); // holds 100's digit
         c = ((counter/10)%10);  // holds 10th digit
         d = (counter%10);  // holds unit digit value
         send_data(binary_pattern[a]); // send 1000's place data to fourth digit
        digit1=1;   //  turn on forth display unit
        __delay_ms(10);
        digit1=0;   //  turn off forth display unit
        send_data(binary_pattern[b]);  // send 100's place data to 3rd digit
        digit2=1;    //  turn on 3rd display unit
        __delay_ms(10);
        digit2=0;  //  turn off 3rd display unit
         send_data(binary_pattern[c]);  // send 10th place data to 2nd digit
         digit3 = 1;  //  turn on 2nd display unit
         __delay_ms(10);
        digit3 = 0;   //  turn off 2nd display unit
       send_data(binary_pattern[d]);  // send unit place data to 1st digit
       digit4 = 1;  //  turn on 1st display unit
       __delay_ms(10);
       digit4 = 0;  //  turn off 1st display unit

     if(counter>=9999) //wait till flag reaches 100
         {
         counter=0; //only if flag is hundred "i" will be incremented 
         }
         counter++; //increment flag for each flag
     }
      
  return;
}

Funcionamento do código

Uma função de atraso foi declarada no início do código que é usada para retardar as mudanças abruptas no contador de um segmento, que também é efetiva para o segmento de dezenas. Além de char ‘i’ e ‘j’, um array ‘ar’ também foi declarado. Os valores definidos entre colchetes correspondem a dígitos de 0 a 9. Mas estes não são os valores hexadecimais dos dígitos reais de 0 a 9.