IC mở rộng ngõ ra 74HC595

74HC595 là IC dịch bit mở rộng ngõ ra rất phổ biến và quen thuộc. 74HC595 có nguyên lý hoạt động đơn giản, dễ sử dụng, tốc độ cao, tuy nhiên mình cảm thấy phần layout cho IC này khá khó.

Cấu tạo và nguyên lý hoạt động

Cấu tạo và nguyên lý hoạt động của 74HC595 đã được trình bày rất nhiều lần trên nhiều trang và diễn đàn khác nhau, nên mình không trình bày lại quá sâu. Hiểu đơn giản thì quy trình dịch bit ra Output của 74HC595 gồm: đưa tín hiệu (high/low) vào chân DS => tạo xung dịch dữ liệu vào => khi đủ dữ liệu thì tạo xung chốt để xuất dữ liệu ra Output.

Code mẫu sử dụng IC 74HC595 để mở rộng ngõ ra cho Tiva C TM4C123GH6PM

Bên dưới là code mẫu dùng 74HC595 với Tiva C được viết trên Code Composer Studio. Hàm void HC595_Out(void) có chức năng xuất 8 bit trong biến uint8_t data ra 74HC595, đây là hàm khá đơn sơ, bạn có thế viết lại hàm thành dạng khác tối ưu hơn, ví dụ như boolean HC595_Out(uint8_t data) để trả về kết quả xuất dữ liệu ra 74HC595 có thành công hay không.

74HC595 còn có chân OE (Output Enable) để cho phép/ngắt ngõ ra, có thể mặc định nối chân này xuống mass để luôn cho phép hoặc sử dụng một IO của Tiva để điều khiển.

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.c"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.c"
#include "driverlib/gpio.h"

#define HC_DS    GPIO_PIN_1
#define HC_CLK   GPIO_PIN_2
#define HC_Latch GPIO_PIN_3

uint8_t data;

void delayMS(int ms)
{
    SysCtlDelay( (SysCtlClockGet()/(3000))*ms ) ;
}

void HC595_Out(void)
{
    uint8_t i, temp;
    for(i = 0; i < 8; i++) // i < 8 nếu chỉ có 1 IC 595, nếu 2 thì i < 16, tương tự khi nối tiếp thêm nhiều 595
    {
        temp = data & (0x80>>i); //xet xem bit 0 hay 1
        if (temp == 0)
            GPIOPinWrite(GPIO_PORTF_BASE, HC_DS, 0x00);
        else
            GPIOPinWrite(GPIO_PORTF_BASE, HC_DS, 0xff);
        // tao xung dich du lieu
        GPIOPinWrite(GPIO_PORTF_BASE, HC_CLK, 0x00);
        delayMS(1);
        GPIOPinWrite(GPIO_PORTF_BASE, HC_CLK, 0xff);
    }
    // tao xung chot du lieu
    GPIOPinWrite(GPIO_PORTF_BASE, HC_Latch, 0x00);
    delayMS(1);
    GPIOPinWrite(GPIO_PORTF_BASE, HC_Latch, 0xff);
}
int main(void)
{
    SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    SysCtlDelay(3);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    GPIOPinWrite(GPIO_PORTF_BASE, HC_DS, 0x00);
    GPIOPinWrite(GPIO_PORTF_BASE, HC_CLK|HC_Latch, 0xff);

  while (1)
  {
      data = 0x00;
      HC595_Out();
      delayMS(1000);
      data = 0xff;
      HC595_Out();
      delayMS(1000);
  }
}

Updating…