Cách dùng và code cho 74HC595

mafiaWolf

Chủ tịch Hội phụ nữ PIF
Lần đầu làm TUT không biết OK không, gần đây thấy mọi người đang cần xài con này .Bài viết được tổn hợp nhiều nguồn và có tinh chỉnh lại cho dễ hiểu ^^

1, Chức năng :
Là ic ghi dịch 8bit kết hợp chốt dữ liệu , đầu vào nối tiếp đầu ra song song .
Chức năng: Thường dùng trong các mạch quét led 7 , led matrix …để tiết kiệm số chân VDK tối đa (3 chân) . Có thể mở rộng số chân vi điều khiển bao nhiêu tùy thích mà k ic nào có thể làm dc bằng việc mắc nối tiếp đầu vào dữ liệu các ic với nhau

Giải thích ý nghĩa hoạt động của một số chân quan trọng:

(Sơ đồ chân mấy bạn tập tra datasheet xíu cho wen :1cool_byebye:)

(input)
Chân 14 : đầu vào dữ liệu nối tiếp . Tại 1 thời điểm xung clock chỉ đưa vào được 1 bit
(output)
QA=>QH : trên các chân (15,1,2,3,4,5,6,7)
Xuất dữ liệu khi chân chân 13 tích cực ở mức thấp và có một xung tích cực ở sườn âm tại chân chốt 12
(output-enable)
Chân 13 : Chân cho phép tích cực ở mức thấp (0) .Khi ở mức cao, tất cả các đầu ra của 74595 trở về trạng thái cao trở, không có đầu ra nào được cho phép.
(SQH)
Chân 9: Chân dữ liệu nối tiếp . Nếu dùng nhiều 74595 mắc nối tiếp nhau thì chân này đưa vào đầu vào của con tiếp theo khi đã dịch đủ 8bit.
(Shift clock)
Chân 11: Chân vào xung clock . Khi có 1 xung clock tích cực ở sườn dương(từ 0 lên 1) thì 1bit được dịch vào ic.
(Latch clock)
Chân 12 : xung clock chốt dữ liệu . Khi có 1 xung clock tích cực ở sườn dương thì cho phép xuất dữ liệu trên các chân output . lưu ý có thể xuất dữ liệu bất kỳ lúc nào bạn muốn ,ví dụ đầu vào chân 14 dc 2 bit khi có xung clock ở chân 12 thì dữ liệu sẽ ra ở chân Qa và Qb (chú ý chiều dịch dữ liệu từ Qa=>Qh)
(Reset)
Chân 10: khi chân này ở mức thấp(mức 0) thì dữ liệu sẽ bị xóa trên chip)
Đây là hình ví dụ cho việc ghép nối tiếp 2 con 74HC595, giúp chúng ta có thể tăng số port như mong muốn


TRƯỚC TIÊN BẠN CẦN KHAI BÁO 3 CHÂN :
CHÂN : SDI LÀ CHÂN 14 Của 595
CHÂN : CLK LÀ CHÂN 11 Của 595
CHÂN : STR LÀ CHÂN 12 CỦA 595

Đây là hàm truyền 1 byte vào 595 :
Code:
void truyen(unsigned char byte)
{
unsigned char i,Q;
Q=byte;
for(i=0;i<8;i++)
{
SDI=Q&0x80;
CLK=0;
CLK=1;
Q<<=1;
} // truyền đủ 1 byte
STR=0;
STR=1;
}
nếu ban nối 2 con như hình của mình thì bạn hãy lặp lại quá trình truyền 1 byte.
Code:
void truyen(unnigned char byte_1,unnigned char byte_2)
{
unsigned char i,Q;
Q=byte_2; for(i=0;i<8;i++) { SDI=Q&0x80;CLK=0; CLK=1;Q<<=1;}
Q=byte_1; for(i=0;i<8;i++) { SDI=Q&0x80;CLK=0; CLK=1;Q<<=1;}
STR=0;
STR=1;
// cuối cùng là xuất tất cả các byte được dịch ra ngoài.
}
Ta truyền byte 2 trước vì nguyên tắc của con 74HC595 này là dịch bit, vì thế khi truyền xong 1 byte mà ta truyền tiếp byte nữa thì byte trước sẽ được đẩy qua con sau thông qua chân Q7S

Đây là cái code dựa theo nguyên lý của cái code trên dành cho LM4F120 (chưa test :5cool_beat_plaster:)
Code mẫu cho 2 con với LATCH và CLOCK đã được định nghĩa sẵn (VD: GIPO_PIN_1..) và trong ví dụ này là đang dùng chân ở PORT E, các bạn có thể sử dụng lại và dùng hàm này để truyền :D...
Code:
void transmit (unsigned char byte1, unsigned char byte2, unsigned char pin)
// Send data to 74HC595
{
unsigned char i,data,temp;
data = byte2;//Send MSB
for(i=0;i<8;i++)
{
temp = data & 0x80;
if (temp == 0)
{
GPIOPinWrite(GPIO_PORTE_BASE, TABLE, ~pin);
}
else
{
GPIOPinWrite(GPIO_PORTE_BASE, TABLE, pin);
}
GPIOPinWrite(GPIO_PORTE_BASE, TABLE, ~CLOCK);
GPIOPinWrite(GPIO_PORTE_BASE, TABLE, CLOCK);
data <<= 1;
}
data = byte1;//Send LSB
for(i=0;i<8;i++)
{
temp = data & 0x80;
if (temp == 0)
{
GPIOPinWrite(GPIO_PORTE_BASE, TABLE, ~pin);
}
else
{
GPIOPinWrite(GPIO_PORTE_BASE, TABLE, pin);
}
GPIOPinWrite(GPIO_PORTE_BASE, TABLE, ~CLOCK);
GPIOPinWrite(GPIO_PORTE_BASE, TABLE, CLOCK);
data <<= 1;
}
GPIOPinWrite(GPIO_PORTE_BASE, TABLE, ~LATCH);
GPIOPinWrite(GPIO_PORTE_BASE, TABLE, LATCH);//Latch all data
}
Ngoài ra có một lưu ý cho các bạn là nếu các bạn muốn phát triển LED matrix hoặc cần dùng led hay là tải gì đó ở ngõ ra với số lượng lớn ==> cần tiêu thụ dòng nhiều thì 74HC595 sẽ đáp ứng không đủ ==>R.I.P:6cool_boss:

Lúc đó chúng ta sẽ dùng thêm 1 trong 2 con IC đệm dòng thông dụng: ULN2803 (Sink Driver) hoặc TD62783 (Source Driver) với khả năng cấp dòng lên đến 500mA
Cách mắc thì chúng ta cứ nhớ theo gợi ý sau cho dễ :3
- Source driver ta sẽ cấp ngay cực dương của tải (led)
- Sink driver sẽ cấp ngay cực âm của tải (led)

Lưu ý: số lượng led cho mỗi chân khi dùng đệm cũng không nên lớn quá. Nếu số lượng nhiều như các mạch quang báo mà ta thấy ngoài đường thì sẽ có cách khác không dùng đệm đó chính là dùng transistor công suất tiêu biểu là TIP41(npn) hoặc TIP42(pnp) mà mình sẽ đề cập ở TUT khác

:1cool_byebye: Thấy hay thì like để ủng hộ mình làm TUT khác nha
P/S: Không đổi được cái avatar "ruồi bu" này :(
 

nhok 9x

Trứng gà
Cho mình hỏi cái này xíu nha, tại sao phải lấy pin làm input của hàm transmit vậy? Và công dụng của nó là gì?
 

mafiaWolf

Chủ tịch Hội phụ nữ PIF
À...cái đó là ví dụ như bạn dùng điều khiển ma trận led nhiều màu, dùng chung CLOCK và LATCH, chỉ khác nhau cái DATA (mỗi màu thì DATA riêng) thì khi đó pin có tác dụng để chọn màu đấy bạn ^^~
Cái trên là cái ví dụ mình đưa ra thôi, bạn có thể dựa theo cách code của đoạn ở trên để phát triển theo cách riêng của mình..
Ngoài ra thì ta có thể dùng chức năng có sẵn là SPI của con MCU nữa (nhưng phải dùng các chân chức năng :( )^^
 

mafiaWolf

Chủ tịch Hội phụ nữ PIF
Tình hình là sau khi có bạn hỏi và nhìn lại mấy dòng code ví dụ mình không rõ mình viết cái gì :v
Cũng k ai phản hồi nên k rõ viết có dễ hiểu không
Giờ up lại code cho nó có vẻ dễ hiểu một tí cho các bạn tham khảo lại :3

Với giả sử dùng chung 1 Port và x là vị trí chân điều khiển

P.s: Nên copy và tab lại lệnh theo đúng cấu trúc cho dễ nhìn dễ hiểu :)

Code cho TM4C

Code:
#define MTX_SYSSYS              CTL_PERIPH_GPIOx
#define MTX_BASE                GPIO_PORTx_BASE
#define MTX_SHCP                GPIO_PIN_x
#define MTX_STCP                GPIO_PIN_x
#define MTX_DATA               GPIO_PIN_x
 
void config(void)
{
 SysCtlPeripheralEnable(MTX_SYS);
 GPIOPinTypeGPIOOutput(MTX_BASE, MTX_SHCP|MTX_STCP|MTX_DATA);
}
 
void shift(uint8_t data)
{
 uint8_t i, t;
 for(i=0; i<8; i++)
 {
  t = data & 0x01;
  if(t)
   GPIOPinWrite(MTX_BASE, MTX_DATA, MTX_DATA);
  else
   GPIOPinWrite(MTX_BASE, MTX_DATA, 0);
  clock();
  data >>= 1;
 }
 latch();
}
 
void clock(void)
{
 GPIOPinWrite(MTX_BASE, MTX_SHCP, MTX_SHCP);
 GPIOPinWrite(MTX_BASE, MTX_SHCP, 0);
}
void latch(void)
{
 GPIOPinWrite(MTX_BASE, MTX_STCP, MTX_STCP);
 GPIOPinWrite(MTX_BASE, MTX_STCP, 0);
}
Code cho MSP430

Code:
#define MTX_DIR              PxDIR
#define MTX_OUT             PxOUT
#define MTX_SHCP            BITx
#define MTX_STCP            BITx
#define MTX_DATA           BITx
 
void config(void)
{
 PxSEL &= ~(MTX_SHCP|MTX_STCP|MTX_DATA);
 PxSEL2 &= ~(MTX_SHCP|MTX_STCP|MTX_DATA);
 PxDIR |= (MTX_SHCP|MTX_STCP|MTX_DATA);
}
 
void shift(uint8_t data)
{
 uint8_t i, t;
 for(i=0; i<8; i++)
 {
 t = data & 0x01;
 if(t)
  MTX_OUT |= MTX_DATA;
 else
  MTX_OUT &= ~MTX_DATA;
 clock();
 data >>= 1;
 }
 latch();
}
 
void clock(void)
{
 MTX_OUT |= MTX_SHCP;
 MTX_OUT &= ~MTX_SHCP
}
void latch(void)
{
 MTX_OUT |= MTX_STCP;
 MTX_OUT |= MTX_STCP;
}
Code ví dụ trong main

Code:
void main(void)
{
 config();
 shift(0x20);
}
 
Top