Aumentando o número de portas digitais da FRDM-KL05Z utilizando o CI 74HC595 Deixe um comentário

Olá caro leitor, tudo bem? No último artigo sobre a Freedom Board KL05Z, apresentei a biblioteca de software que venho desenvolvendo para utilizar em conjunto com a placa FRDM-KL05Z. Esta biblioteca traz diversos drivers de acesso aos periféricos do microcontrolador da placa. Neste artigo vou mostrar como aumentar o número de portas digitais da FDRM-KL05Z utilizando o CI 74HC595 e mostrar o algoritmo para acionamento do mesmo. Para demonstrar uma possível aplicação, vamos desenvolver um circuito “expansor” de saídas digitais de 16 bits utilizando dois CIs ligados em cascata em conjunto com a biblioteca apresentada anteriormente.

Material Necessário

Como aumentar o número de portas digitais: CI 74HC595

O circuito integrado 74HC595 é um Shift Register (registrador de deslocamento), esse CI é um conversor serial-paralelo de 8 bits. Assim permitindo ser utilizado como um “expansor” de saídas digitais, possibilitando ser empregado para controlar diversos dispositivos, tais como: displays alfanuméricos, displays de sete segmentos, LEDs, relés, entre outros componentes.
Outra característica bem interessante deste CI é sua capacidade de ser ligado em cascata permitindo, assim, aumentar ainda mais o número de saída digitais, utilizando uma mesma interface de controle.

Abaixo temos o diagrama lógico do circuito integrado 74HC595. Podemos observar que internamente ele é composto por diversas portas lógicas e diversos Flip Flops.

Imagem 1 - 74HC595

Nas figuras abaixo temos os pinos do circuito integrado e a descrição e funcionamento dos pinos do 74HC595.

Imagem 2 - 74HC595

Imagem 3 - Como aumentar o número de portas digitais

Em seguida temos um exemplo de aplicação para circuito integrado 74HC595. Neste exemplo é possível observar os pinos de saídas conectados ao LED e pinos da interface de controle do CI conectados a um microcontrolador (pode ser Arduino, ESP32, Raspberry…), além dos pinos de alimentação.

Imagem 4 - Como aumentar o número de portas digitais

Na próxima figura é apresentada a tabela verdade da interface de controle do CI 74HC595, permitindo assim o melhor entendimento da lógica de funcionamento da interface de controle do CI.

Imagem 5 - Como aumentar o número de portas digitais

Como aumentar o número de portas digitais: biblioteca desenvolvida para o 74HC595

Analisando a tabela verdade apresentada na figura acima, podemos observar que a interface de controle do CI 74HC595 possui dois pinos que devem ter um valor constante ao longo do tempo. Assim é possível reduzir os números de pinos conectados ao microcontrolador. Esses pinos são: pino 10 SRCLR e pino 13 OE. Deixamos seus valores fixos, habilitando o CI para receber as instruções da placa FRDM-KL05Z. O pino 10 SRCLR deve ser ligado ao VCC (valor lógico 1) e o pino 13 OE conectado ao GND (valor lógico 0).
A interface de controle é composta por: o pino 11 SRCLK, pino 14 SER e o pino 12 RCLK serão responsáveis em gerenciar o circuito integrado. O SRCLK é por onde o CI recebe o sinal de Clock. O SER é o pino de entrada de dados. E o RCLK é o pino que dispara a conversão dos dados recebidos pela entrada SER para os pinos de saída do 74HC595.

A seguir será apresentado o código fonte da biblioteca de software para o CI.

Arquivo ci74hc595.h

/**
 * ci74hc595.c
 *
 *  Created on: 07/08/2019
 *      Author: Evandro Teixeira
 */
#include "ci74hc595.h"

#define CI74HC595_BYTE            8
#define CI74HC595_TIME_DELAY    10
#define CI74HC595_8_BIT            1
#define CI74HC595_16_BIT        2

/**
 *
 */
typedef struct
{
    GPIO_MemMapPtr io;
    uint32_t pin;
}pin_t;

/**
 *
 */
static pin_t clk, latch, data;
static bool status_init = false;

/**
 *
 */
static bool ci74hc595_transmits_data(uint16_t value, uint8_t num_byte);
static void ci74hc595_delay(uint32_t t);

/**
 *
 */
void ci74hc595_init(GPIO_MemMapPtr gpio_CLK,    uint32_t pin_CLK,    // Pin CLK
                    GPIO_MemMapPtr gpio_LATCH,    uint32_t pin_LATCH,    // Pin LATCH
                    GPIO_MemMapPtr gpio_DATA,    uint32_t pin_DATA)    // Pin DATA
{
    clk.io = gpio_CLK;
    clk.pin = pin_CLK;

    latch.io = gpio_LATCH;
    latch.pin = pin_LATCH;

    data.io = gpio_DATA;
    data.pin = pin_DATA;

    gpio_init(clk.io,clk.pin,OUTPUT);
    gpio_init(latch.io,latch.pin,OUTPUT);
    gpio_init(data.io,data.pin,OUTPUT);

    status_init = true;
}

/**
 *
 */
bool ci74hc595_transmits_8_bits(uint8_t data)
{
    uint16_t value = (uint16_t)( data );
    return ci74hc595_transmits_data(value, CI74HC595_8_BIT );
}

/**
 *
 */
bool ci74hc595_transmits_16_bits(uint16_t data)
{
    return ci74hc595_transmits_data(data, CI74HC595_16_BIT );
}

/**
 *
 */
static bool ci74hc595_transmits_data(uint16_t value, uint8_t num_byte)
{
    uint8_t i = 0;

    if((status_init == true) && ((num_byte == 1 || num_byte == 2)))
    {
        for(i=0;i<(CI74HC595_BYTE*num_byte);i++)
        {
            if(value & 1)
            {
                gpio_write(data.io,data.pin,HIGH);
            }
            else
            {
                gpio_write(data.io,data.pin,LOW);
            }

            gpio_write(clk.io,clk.pin,LOW);
            ci74hc595_delay(CI74HC595_TIME_DELAY);
            gpio_write(clk.io,clk.pin,HIGH);
            value >>= 1;
        }

        gpio_write(latch.io,latch.pin,LOW);
        ci74hc595_delay(CI74HC595_TIME_DELAY);
        gpio_write(latch.io,latch.pin,HIGH);
        gpio_write(latch.io,latch.pin,LOW);

        return true;
    }
    else
    {
        return false;
    }
}

/**
 *
 */
static void ci74hc595_delay(uint32_t t)
{
    while(t--)
    {
        __NOP();
    }
}

Como aumentar o número de portas digitais: aplicação 

Para demonstrar a utilização do CI 74HC595 em conjunto com a biblioteca de software desenvolvida, optei em apresentar um circuito “expansor” de 16 bits, onde são utilizados dois CIs ligados em cascata, conforme a figura abaixo.

Imagem 5 - Como aumentar o número de portas digitais

Aplicação por si só é bem simples, ela aciona uma saída por vez, sendo que no primeiro CI 74HC595 o período de acionamento é de 1 segundo. Já para o acionamento do segundo CI o período é de 8 segundos. A seguir é apresentado o código fonte da aplicação de demonstração.

Arquivo demo_74hc595.c

/**
 * demo_74hc595.c
 *
 *  Created on: 07/08/2019
 *      Author: Evandro Teixeira
 */
#include "MKL05Z4.h"
#include "../ThirdpartKL05Z/CI74HC595/ci74hc595.h"
#include "../KL05Z_Libraries/board_frdm_kl05z.h"

/* Declara variaveis globais */
uint16_t data = 0;
uint8_t  data_CI_1 = 0, data_CI_2 = 0;
uint8_t  shift_CI_1 = 0, shift_CI_2 = 0;
bool     flag_CI_2 = false;

int main(void)
{
    /* Inicializa o timer systick */
    systick_init();

    /* Inicializa pinos da interface de controle do CI 74HC595 */
    ci74hc595_init(D2 /* CLK */,D3 /* LATCH */,D4 /* DATA */);

    /* Transmite Zero iniciar com apagados todos os LED */
    ci74hc595_transmits_16_bits(data);

    for (;;)
    {
        /**
         * Algoritmo de controle para o primeiro CI_1
         */
        data_CI_1 = 1 << shift_CI_1++;    /* Desloca bit para esquerda */
        if(shift_CI_1 > 8)            /* Checa se a variavel chegou ao 8 */
        {
            shift_CI_1 = 0;                /* Zera a variavel shift_CI_1 */
            flag_CI_2 = true;            /* Ativa Flag_CI_2 */
        }

        /**
         * Algoritmo de controle para o primeiro CI_2
         */
        if(flag_CI_2 == true)                /* Checa flag_CI_2 */
        {
            flag_CI_2 = false;            /* Reset flag_CI_2 */

            data_CI_2 = 1 << shift_CI_2++;    /* Zera a variavel shift_CI_2 */
            if(shift_CI_2 > 8)        /* Checa se a variável chegou ao 8 */
            {
                shift_CI_2 = 0;        /* Zera a variavel shift_CI_2 */
            }
        }

        /**
         * Prepara dados para ser transmitido
         */
        data  = (uint16_t)data_CI_1 << 8;
        data |= (uint16_t)data_CI_2;

        /**
         * Transmite dados 74HC595
         */
        ci74hc595_transmits_16_bits(data);

        /**
         * Aguarda 1 segundos
         */
        systick_delay(1000);
    }
    /* Never leave main */
    return 0;
}

Conclusão

O circuito integrado 74HC595 é uma ótima opção ser utilizado como expansor de saídas digitais. A implementação é bem simples, não necessita de nenhum protocolo de comunicação mais específico como SPI ou I2C.
A biblioteca de software apresentada neste artigo está no meu Github disponível para que todos. Além de utilizar, você também pode contribuir  com o projeto, ajudando no seu desenvolvimento. Pode fazer isso testando, avaliando, corrigindo falhas e implementando novas funcionalidades.

O que você achou? Você já utilizou esse CI em seus projetos? Deixe o seu comentário a abaixo.

Faça seu comentário

Acesse sua conta e participe