Chế tạo đồng hồ nghe thú vị quá phải không? Hãy thử tưởng tượng một chiếc đồng hồ quả lắc bự kiểu cổ, với hộp gỗ được chạm khắc tinh xảo cùng một cánh cửa kính mà nhìn qua đó sẽ thấy được quả lắc nặng nề đang đong đưa. Đằng sau mặt số kim loại trang trí công phu là hệ thống bánh răng phức tạp giúp đo thời gian bằng cách sử dụng một cơ chế nhỏ nhắn thông minh gọi là bộ hồi (escapement), tiếng tích tắc của nó vang vọng khắp nhà và phát ra những tiếng chuông uy nghiêm cứ mỗi một giờ.
Nhưng không. Đó chẳng phải là kiểu đồng hồ mà chúng ta sẽ làm trong chương này đâu mà sẽ là đồng hồ điện tử, hiển thị giờ, phút và giây bằng các con số chứ không phải bằng kim quay trên mặt số. Thật ra thì phiên bản đầu tiên của chiếc đồng hồ này thậm chí chẳng hiển thị các chữ số thập phân thông thường mà thay vào đó là dùng các đèn nhấp nháy để chỉ thời gian theo hệ nhị phân.
Tôi biết, biết lắm chứ: Hiển thị thời gian bằng hệ nhị phân nghe ghê thật! Nhưng đó là bước đầu tiên cần thiết để tiến tới biểu diễn thời gian bằng số thập phân. Hơn nữa, những số nhị phân mà chúng ta sắp dùng thực ra lại là một dạng lai giữa nhị phân thuần túy và thập phân.
Trước tiên, hãy cùng xem xét các con số cấu thành thời gian. Nếu tính cả giây và phút, một màn hình hiển thị thời gian sẽ cần sáu chữ số thập phân—ví dụ như:
12:30:47
Đó là 12 giờ, 30 phút, 47 giây, khoảng nửa tiếng sau nửa đêm hoặc giữa trưa. Thêm một ký hiệu AM hoặc PM sẽ giúp thông tin rõ ràng hơn.
Trong hệ nhị phân, mốc thời gian này có thể được biểu diễn bằng các số nhị phân tương đương của 12, 30 và 47:
1100 : 11110 : 101111
Không biết bạn sao chứ tôi thì thà không xem giờ ở dạng này còn hơn. Chờ tới lúc nhẩm đổi xong mấy số đó ra thập phân có khi mất một phút bà nó rồi.
Thế nên mình đừng theo cách này. Thay vì vậy hãy biểu diễn từng chữ số thập phân một cách riêng biệt bằng hệ nhị phân, như vậy 12:30:47 sẽ được hiển thị bằng số nhị phân tương đương của 1, 2, 3, 0, 4 và 7 là:
0001 0010 : 0011 0000 : 0100 0111
Giờ bạn có tới 6 số nhị phân 4 chữ số để đổi trong đầu, nhưng vì giá trị thập phân đều từ 0 tới 9 nên việc đổi cũng nhẹ nhàng hơn. Hơn nữa, chỉ bằng việc xem giây nhảy trên đồng hồ này bạn sẽ học được cách đọc và dịch số nhị phân nhanh thôi.
Kiểu biểu diễn này cũng có tên gọi đấy. Đó là số thập phân mã hóa nhị phân (binary-coded decimal), hay BCD. Với BCD, mỗi chữ số của một số thập phân được mã hóa thành một số nhị phân bốn chữ số, như trong bảng sau:
Bạn đã từng thấy những bảng giống này rồi, nhưng chúng thường chạy tiếp qua mức 1001 (số 9 thập phân) để hiển thị 1010, 1011, 1100, 1101, 1110 và 1111—các giá trị nhị phân tương đương của 10 đến 15. Nhưng với BCD, những số nhị phân bổ sung này không hợp lệ. BCD chỉ đi đến 1001, và các tổ hợp bit khác không được sử dụng.
Đây lại là một ví dụ nữa cho thấy bản thân các bit không tự nói lên điều gì về chúng cả. Nếu bạn bắt gặp con số 10011001, bạn sẽ chẳng thể biết nó là gì nếu không biết ngữ cảnh. Dưới dạng số nguyên không dấu, nó là số 153 thập phân, nhưng dưới dạng số nguyên có dấu bù hai (mà bạn đã học ở Chương 16), nó là –103. Còn nếu nó là BCD, thì lại là 99.
BCD không được sử dụng nhiều trong nhân máy tính vì nó làm phức tạp hóa các phép toán số học cơ bản như cộng và trừ. Nhưng khi cần hiển thị các số thập phân, BCD thường là một bước trung gian.
Chiếc đồng hồ đầu tiên mà tôi sẽ chỉ cho bạn trong chương này không chắc là chạy đúng giờ, nhưng nó sẽ cho thấy số giây tăng dần từ 00 đến 59, rồi số phút từ 00 đến 59, và cuối cùng là số giờ. Quyết định hiển thị thời gian bằng BCD ngụ ý rằng mỗi chữ số trong sáu chữ số thập phân của thời gian có thể được tính toán một cách riêng biệt, bắt đầu từ số giây. Dưới đây là sáu chữ số cấu thành thời gian, cùng với phạm vi giá trị hợp lệ của chúng:
Giây, chữ số hàng đơn vị, dao động từ 0 đến 9.
Giây, chữ số hàng chục, dao động từ 0 đến 5.
Phút, chữ số hàng đơn vị, dao động từ 0 đến 9.
Phút, chữ số hàng chục, dao động từ 0 đến 5.
Giờ, chữ số hàng đơn vị, dao động từ 0 đến 9.
Giờ, chữ số hàng chục, là 0 hoặc 1.
Chữ số hàng đơn vị của giây tăng đều đặn từ 0 đến 9. Mỗi khi chữ số này đạt đến 9, nó sẽ quay ngược (hay đặt lại) về 0, và chữ số hàng chục của giây được tăng lên (incremented) 1 đơn vị: từ 0 lên 1, rồi lên 2, 3, 4, và cuối cùng là 5. Khi số giây chạm mức 59, giá trị tiếp theo là 00, và số phút tăng thêm 1.
Mỗi một trong sáu chữ số thời gian cần một mạch riêng, và mỗi mạch này sẽ tác động đến mạch kế tiếp.
Hãy khởi động với chữ số hàng đơn vị của giây. Bạn có thể bắt đầu bằng cách nối bốn flip-flop kích cạnh theo hàng, tương tự như cách các flip-flop được mắc ở Chương 17 để tạo ra một bộ đếm sóng (ripple counter). Mỗi đầu ra Q của các flip-flop được nối với một bóng đèn:
Nối 4 flip-flop kích cạnh theo hàng
Trong Chương 17, các flip-flop được nối từ trái sang phải; ở đây chúng được nối từ phải sang trái. Như bạn sẽ sớm thấy, cách này giúp các bóng đèn hiện số nhị phân dễ đọc hơn.
Đầu vào ở ngoài cùng bên phải là một bộ dao động tuỳ ý với tần số 1 Hertz, hay một chu kỳ mỗi giây. Chu kỳ của bộ dao động này—thời gian cần thiết cho một chu trình—là 1 chia cho tần số, tức là 1 giây. Cứ mỗi giây, bộ dao động một-giây đó đi từ 0 lên 1 và rồi quay lại 0.
Các đầu ra của mỗi flip-flop là Q và Q̄, mang giá trị đối lập nhau. Nếu Q là 0, thì Q̄ là 1. Mỗi flip-flop có đầu ra Q̄ được nối với đầu vào D (tức Data) của chính nó. Khi đầu vào Clock chuyển từ 0 sang 1, đầu vào D đó trở thành đầu ra Q. Khi đầu ra Q chuyển từ 0 sang 1, nó cũng làm thay đổi trạng thái của flip-flop tiếp theo nằm bên trái.
Đối với flip-flop đầu tiên bên phải, đầu ra Q sẽ là 0 trong một giây và là 1 trong giây tiếp theo, làm tắt đèn trong một giây rồi lại bật đèn trong một giây. Chu kỳ là hai giây, và tần số đã bị chia làm đôi. Flip-flop thứ hai từ bên phải tiếp tục chia đôi tần số đó thêm lần nữa, bật đèn của nó trong hai giây rồi tắt trong hai giây. Và cứ thế tiếp tục.
Kết quả là bốn bóng đèn nhấp nháy sẽ đếm giây bằng hệ nhị phân:
Đèn sẽ đếm từ 0000 đến 1111 rồi trở về 0000, hoàn thành một chu trình mỗi 16 giây.
Nhưng đây đâu phải là điều chúng ta muốn! Ta muốn đèn đếm từ 0000 đến 1001 mỗi 10 giây. Sau khi nó đến 1001 (số 9 thập phân), chúng ta muốn nó quay về 0.
May mắn thay, ta đã sử dụng các flip-flop có một đầu vào Clear (xóa) được dán nhãn Clr ở phía dưới. Khi đầu vào Clear này được đặt thành 1, đầu ra Q của flip-flop trở thành 0 bất chấp các đầu vào khác. Hơn nữa, tất cả các đầu vào Clear đó có thể được đặt thành 1 cùng một lúc, khiến con số đang hiển thị quay ngoắt về 0000.
Thế khi nào các đầu vào Clear này nên đặt thành 1? Giá trị hiển thị 1001 (số 9) là hợp lệ, nhưng giá trị tiếp theo 1010 (số 10) thì không. Do đó, khi đầu ra của bốn flip-flop là 1010 — tức là 10 ở hệ thập phân — chúng ta muốn toàn bộ các flip-flop bị xóa về 0.
Việc này có thể được hoàn thành bằng một cổng AND nối với hai trong số các đầu ra Q của flip-flop:
Nối cổng AND với 2 đầu ra Q
Ngoài đời thực, các transistor cấu tạo nên flip-flop sẽ chạy nhanh đến mức bạn không thể nhìn thấy sự chuyển đổi từ 1010 sang 0000 đâu. Ngay khi đầu ra Q của bốn flip-flop trở thành 1010, đầu ra của cổng AND sẽ là 1, các flip-flop bị xóa, và chúng lập tức biến hết thành 0. Về mặt thị giác, nó sẽ là một quá trình chuyển đổi mượt mà từ 1001 sang 0000:
Nếu bạn cảm thấy hơi cấn cấn khi sử dụng chính đầu ra của flip-flop để xóa flip-flop, thì sự lo lắng của bạn không phải là hoàn toàn vô căn cứ. Có những cách xịn hơn để làm việc này, nhưng chúng lại khá phức tạp. Nếu bạn đang tự ráp một chiếc đồng hồ nhị phân ngoài đời thực, bạn cũng nên biết rằng có những mạch tích hợp được gọi là bộ đếm thập phân (decade counters) đếm từ 0000 đến 1001 và sau đó chuyển mượt mà về 0000.
Giờ đây chúng ta đang đếm số giây từ 0 đến 9, và rất nhanh thôi, bạn sẽ thấy một mạch khác dành cho chữ số hàng chục của giây đếm từ 0 đến 5. Khi bốn đèn của chữ số hàng đơn vị đi từ 1001 quay lại 0000, chữ số hàng chục sẽ tăng thêm 1, có nghĩa là chúng ta cần một tín hiệu chuyển từ 0 lên 1 vào chính khoảnh khắc đó.
Đầu ra của cổng AND có thể được dùng cho mục đích này, nhưng hãy thử một cách tiếp cận hơi khác một chút bằng việc thêm một cổng NAND vào mạch này xem sao:
Thêm một cổng NAND
Nhớ là đầu ra của cổng NAND ngược lại với cổng AND. Bình thường đầu ra là 1, ngoại trừ khi cả hai đầu vào đều là 1 thì đầu ra sẽ là 0. Cổng NAND này được mắc sao cho hai đầu vào là 1 khi số được hiển thị là 1001 (số 9 thập phân). Đầu ra của cổng NAND sẽ trở thành 0 khi số được hiển thị là 1001 và sau đó quay lại thành 1. Điều này sẽ xảy ra cứ mỗi 10 giây một lần, và sự chuyển đổi từ 0 lên 1 đó có thể đóng vai trò làm đầu vào cho một flip-flop kích cạnh khác.
Biểu đồ định thời (timing diagram) này cho thấy tín hiệu với chu kỳ 1 giây, các đầu ra Q từ mỗi flip-flop trong số bốn flip-flop (từ phải sang trái), và tín hiệu có chu kỳ 10 giây:
Nếu bạn xoay biểu đồ 90 độ theo chiều kim đồng hồ, bạn có thể thấy rằng bốn flip-flop đếm từ 0000 đến 1001 rồi quay lại từ đầu.
Đầu ra của cổng NAND đó là đầu vào cho giai đoạn tiếp theo của đồng hồ nhị phân, bộ phận đếm chữ số hàng chục của giây: 0, 1, 2, 3, 4, và 5. Giai đoạn này chỉ cần ba flip-flop, nhưng khi nó đạt đến 110 (số 6 thập phân), tất cả các flip-flop cần phải được xóa sạch:
Mạch cho số hàng chục của giây
Đầu ra của cổng NAND trong mạch này trở thành 0 khi số được hiển thị là 101 (số 5 thập phân). Kết hợp với bốn flip-flop trước đó, lúc này đồng hồ đang đếm từ 000 0000 đến 101 1001 (số 59 thập phân), và tại đây tất cả bảy flip-flop quay về 0. Đây là biểu đồ định thời cho ba flip-flop này:
Một lần nữa, hãy xoay biểu đồ 90 độ theo chiều kim đồng hồ để thấy cách các flip-flop đếm từ 000 đến 101, và sau đó quay lại từ đầu.
Giờ đã có tín hiệu với chu kỳ 1 phút. Chúng ta có thể đếm phút được rồi. Bốn flip-flop nữa được cấu hình hệt như bốn cái trước đó để đếm phút từ 0 đến 9:
Bộ đếm phút từ 0 tới 9
Đầu ra với chu kỳ 10 phút đó bây giờ có thể là đầu vào cho một cụm ba flip-flop khác dành cho chữ số hàng chục của phút, giống y chang chữ số hàng chục của giây:
Bộ đếm hàng chục của số phút
Và giờ đây, ngay khi có vẻ như đang ở chặng cuối con đường hoàn thành toàn bộ đồng hồ nhị phân, bạn có thể thấy hơi hơi nản lòng một chút.
Với đồng hồ 24 giờ, giờ bắt đầu từ 0 và chạy đến 23, nhưng các nước nói tiếng Anh lại thường dùng đồng hồ 12 giờ, và đó chính là vấn đế. Giờ có hai chữ số, giống như giây và phút, nhưng giờ lại không bắt đầu từ số không. Theo quy ước, giữa trưa hoặc nửa đêm là 12 giờ, và sau đó giờ tiếp theo là 1.
Hãy tạm thời gác vấn đề đó sang một bên. Giả sử với đồng hồ 12 giờ, giờ chạy từ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, và sau đó quay lại 0, và khoảng thời gian 00:00:00 là cái mà chúng ta gọi là nửa đêm hoặc giữa trưa.
Nhưng lại có một điểm kỳ quặc khác với số giờ: Với giây và phút, việc xóa chữ số hàng đơn vị và xóa chữ số hàng chục hoàn toàn độc lập với nhau. Chữ số hàng đơn vị phải bị xóa khi nó đạt tới 1010 (số 10), và chữ số hàng chục phải bị xóa khi nó đạt tới 110 (số 6). Với số giờ, chữ số hàng đơn vị cũng phải bị xóa khi nó chạm mức 1010. Đó là lúc chuyển giao từ 9:59:59 sang 10:00:00. Nhưng cả hai chữ số đều phải bị xóa khi chữ số hàng chục là 1 và chữ số hàng đơn vị là 0010 (tức là số 12). Đó là lúc chuyển giao từ 11:59:59 sang nửa đêm hoặc giữa trưa, mà chúng ta đang tạm coi là 00:00:00.
Điều này có nghĩa là các chữ số hàng đơn vị và hàng chục của giờ phải được xem xét cùng nhau. Năm flip-flop ở đây cho thấy cách hai chữ số này có thể bị xóa dưới hai điều kiện khác nhau:
Bộ đếm 2 chữ số của giờ cùng nhau
Bốn flip-flop bên phải được mắc rất giống với chữ số hàng đơn vị của giây và phút. Một cổng AND sẽ xóa các flip-flop khi con số trở thành 1010, và một cổng NAND xuất ra một tín hiệu chuyển từ 0 sang 1 cùng lúc.
Nhưng một cổng AND ba-đầu-vào khác ở tít bên trái phía trên sẽ xác định khi chữ số hàng chục của giờ là 1 và các chữ số hàng đơn vị là 0010 (số 2 thập phân), tạo ra một giá trị BCD kết hợp là 12. Bạn có thể nghĩ rằng mình muốn hiển thị số 12 lúc này, nhưng rồi bạn sẽ bị kẹt với việc làm sao hiển thị giá trị tiếp theo là 1. Thay vào đó, cổng AND ba-đầu-vào này xóa sạch cả năm flip-flop để số giờ hiển thị là 0.
Mạch này hiển thị thành công số giờ theo trình tự từ 0 đến 11. Giờ thì chúng ta chỉ cần sửa một vấn đề: Khi tất cả đầu ra Q của các flip-flop đều là 0, chúng ta muốn số giờ phải là 12, tức là 1 0010.
Để đạt được điều đó ta cần một cổng NOR năm-đầu-vào, được hiển thị ở ngoài cùng bên phải trong hình sau:
Thêm một cổng NOR 5-đầu-vào
Nhớ lại xem, đầu ra của một cổng NOR thì ngược lại với cổng OR. Đầu ra của cổng NOR là 1 chỉ khi tất cả năm đầu vào đều là 0. Đầu ra của cổng NOR sau đó lại là đầu vào cho hai cổng OR tại vị trí của hai chữ số tương ứng. Vì vậy, khi đầu ra của năm flip-flop là 0 0000, đèn sẽ hiển thị 1 0010, tức là số 12 thập phân.
Tôi vẫn chưa nhắc tới cổng NAND ở ngoài cùng bên trái. Đầu ra của cổng này lúc bình thường là 1, ngoại trừ khi số giờ là 1 0001 (số 11 thập phân). Lúc đó, đầu ra của cổng NAND trở thành 0. Khi số giờ không còn là 11 nữa, đầu ra lại về 1. Đầu ra này có thể được dùng làm đầu vào cho một flip-flop khác đóng vai trò làm đèn báo AM/PM:
Đèn báo AM/PM
Chiếc đồng hồ nhị phân hoàn chỉnh kết hợp tất cả các linh kiện mà bạn vừa thấy đã có mặt trên trang web CodeHiddenLanguage.com.
Như bạn đã thấy, mỗi một số trong sáu chữ số của chiếc đồng hồ này dùng một cổng NAND để tạo tín hiệu xung cho chữ số tiếp theo. Đầu ra của cổng NAND này bình thường là 1, trừ khi cả hai đầu vào đều là 0. Điều này dẫn đến một điểm đặc biệt khi đồng hồ mới khởi động. Khi ấy, mỗi cổng NAND sẽ có đầu ra là 1, từ đó kích hoạt đầu vào Clock của flip-flop đầu tiên trong giai đoạn tiếp theo. Do đó khi đồng hồ bật lên, thời gian ban đầu sẽ được đặt thành:
1:11:10
Nếu bạn bật đồng hồ này lên đúng với thời gian đó thì ngon nhưng nếu không thì bạn chắc là muốn có thể tự chỉnh giờ đúng với thời gian hiện tại.
Một vài loại đồng hồ điện tử lấy thời gian thông qua internet, vệ tinh GPS hoặc từ các tín hiệu vô tuyến được thiết kế cho mục đích đó. Nhưng với những đồng hồ đòi hỏi chỉnh giờ bằng tay, bạn có thể đã từng thấy những chiếc với chi chít nút bấm cần phải thao tác theo đủ kiểu, có khi phức tạp đến mức phải nổ não đọc kỹ hướng dẫn sử dụng mới làm được.
Giao diện người dùng lúc nào cũng khó, nên hãy thiết kế sao cho đơn giản nhất ha.
Giây, giờ và phút của đồng hồ nhị phân được nối từ phải sang trái, như trong sơ đồ khối sau:
┌───────┐ chu kỳ ┌─────────┐ chu kỳ ┌─────────┐ chu kỳ
│ Giờ │ <──────────────── │ Phút │ <──────────────── │ Giây │ <────────────────
└───────┘ 1 giờ └─────────┘ 1 phút └─────────┘ 1 giây
Hãy thêm hai công tắc vào mạch này. Nhấn công tắc đầu tiên sẽ tự tăng số phút, và nhấn công tắc thứ hai sẽ tự tăng số giờ. Cách làm này không phải giải pháp tối ưu: Nếu thời gian hiển thị là 2:55 và cần đặt nó thành 1:50, bạn sẽ phải nhấn nút phút 55 lần và nút giờ 11 lần. Nhưng đổi lại ưu điểm của nó là cực kỳ đơn giản. Bạn sẽ chẳng cần hướng dẫn chi tiết để đặt giờ.
Số phút thường tăng khi số giây chạm mốc 59 và sau đó quay lại 00. Tín hiệu đó, được gắn nhãn là "1 minute period" (chu kỳ 1 phút), bình thường sẽ là 1, nhưng nó sẽ bằng 0 khi chữ số hàng chục của giây là 5. Tương tự, tín hiệu được gắn nhãn "1 hour period" (chu kỳ 1 giờ) cũng thường là 1, nhưng nó sẽ bằng 0 khi chữ số hàng chục của phút là 5.
Chúng ta muốn thay đổi hai tín hiệu đó khi bấm các công tắc cài đặt thời gian. Ví dụ, nếu tín hiệu "chu kỳ 1 phút" đang là 1 (đa phần như thế), thì việc nhấn công tắc sẽ làm nó thành 0, và khi nhả công tắc ra nó sẽ quay về 1. Tương tự, nếu tín hiệu là 0 (điều này sẽ xảy ra nếu số giây nằm trong khoảng từ 50 đến 59), thì việc nhấn công tắc này sẽ khiến tín hiệu đổi thành 1, và nhả công tắc ra cho phép nó quay về 0.
Nói cách khác, các công tắc để chỉnh giờ thủ công sẽ làm cho các tín hiệu "chu kỳ 1 phút" và "chu kỳ 1 giờ" bị đảo ngược so với trạng thái bình thường của chúng.
Đây là một trong những ứng dụng của cổng Exclusive OR, hay cổng XOR, thứ mà chúng ta đã sử dụng trong Chương 14 để cộng hai số lại với nhau. Đầu ra của cổng XOR giống với cổng OR, ngoại trừ khi cả hai đầu vào đều là 1:
XOR | 0 | 1
----+---+---
0 | 0 | 1
1 | 1 | 0
Ngoài vai trò trọng yếu trong phép cộng, cổng XOR cũng có thể đảo ngược tín hiệu. Khi một đầu vào là 0, thì đầu ra của cổng XOR giống hệt đầu vào còn lại. Nhưng khi một trong các đầu vào là 1, đầu ra sẽ ngược lại với đầu vào kia.
Bằng cách dùng các cổng XOR, việc thêm các công tắc để chỉnh thời gian thủ công trở nên khá đơn giản:
Thêm 2 công tắc + 2 cổng XOR
Khi số giây và phút trôi qua trên một chiếc đồng hồ nhị phân, hiệu ứng mang lại có thể khá lôi cuốn đấy. Bắt đầu từ những năm 1970, các loại đồng hồ nhị phân với đèn nhấp nháy đã được sản xuất và bán như những món đồ chơi mới lạ, thường đi kèm với cái giá chát chúa chẳng hề phản ánh sự đơn giản của các mạch điện bên dưới. Nhưng đối với những người muốn học số nhị phân — hoặc ít nhất là các số thập phân được mã hóa nhị phân (BCD) — thì chúng cũng có chút giá trị giáo dục nhất định.
Đối với những người chuộng hiển thị các chữ số thập phân truyền thống, có những lựa chọn thay thế khác. Một trong những loại đẹp nhất (xét theo nghĩa hoài cổ về mặt công nghệ) được gọi là màn hình hiển thị mã cực âm (code cathode display), đó là một ống thủy tinh được bơm khí neon là chính. Bên trong là các sợi dây kim loại chồng lên nhau được uốn thành hình các con số, mỗi dây được nối với một trong mười chân cắm ở phía dưới, bắt đầu từ số 0 ở tận cùng bên trái:
Code cathode display
Không lộ ra ngoài là một chân cắm khác để nối đất. Cũng không được bày ra là một lớp lưới thép kết nối với chân nối đất đó bao quanh tất cả các sợi dây này.
Khi có điện áp chạy qua một trong các chân cắm, khí neon bao quanh con số đó sẽ phát sáng:
Số 3
Tập đoàn Burroughs đã giới thiệu loại ống hiển thị này vào năm 1955 và đặt cho nó cái tên của một thủy thần trong thần thoại. Họ gọi nó là ống Nixie.
Bạn sẽ cần một ống như này cho mỗi một trong sáu chữ số của màn hình hiển thị thời gian. Về mặt khái niệm, sử dụng ống Nixie khá dễ dàng: Bạn chỉ cần thiết kế mạch điện cung cấp năng lượng cho một trong mười chân cắm để làm sáng con số đó. Nhưng trong thực tế, nó lại khó khăn hơn một chút vì cần nhiều năng lượng hơn so với mức mà các transistor trong các vi mạch thông thường có thể cung cấp. Có sẵn những mạch đặc biệt gọi là bộ điều khiển (driver) dành cho ống Nixie để cung cấp dòng điện cần thiết.
Mạch điện tử của một ống Nixie phải chuyển đổi các số thập phân được mã hóa nhị phân từ các flip-flop thành các tín hiệu riêng biệt cho mỗi một trong mười chân cắm. Khi con số là 0000, bạn cần một tín hiệu cho chân cắm đầu tiên đại diện cho số 0. Khi con số là 0001, đó sẽ là chân cắm cho số 1, và khi con số là 1001, đó là chân cắm cuối cùng cho số 9.
Bạn đã từng thấy một mạch tương tự như vậy ở cuối Chương 10 trang 114. Một số bát phân đã được chuyển đổi thành các tín hiệu để làm sáng một trong tám đèn. Một mạch như vậy được gọi là bộ giải mã (decoder), và ở đây nó được mở rộng một tí để chứa các số BCD. Mạch này do đó được gọi là bộ giải mã BCD (BCD decoder):
Bộ giải mã BCD
Tôi biết mạch này nhìn ghê thật, nhưng nó lại siêu hệ thống đấy. Số BCD đến từ bốn flip-flop nằm ở phía dưới. Các sợi dây màu đỏ trong hình biểu thị rằng số này hiện tại đang là 0101, tức số nhị phân của số 5. Mỗi một tín hiệu trong bốn tín hiệu đó sẽ được đảo ngược lại bằng bộ đảo (inverter), và các tổ hợp khác nhau của những tín hiệu gốc và tín hiệu đã bị đảo này đều đi vào mười cổng AND bốn-đầu-vào. Đối với cổng AND tương ứng với số 5 — cổng AND nằm ngay bên phải của trung tâm — bốn đầu vào là:
Bit BCD ít quan trọng nhất (bên phải cùng)
Bit BCD quan trọng tiếp theo, bị đảo
Bit BCD quan trọng tiếp theo
Bit BCD quan trọng nhất (bên trái cùng), bị đảo ngược
Bốn đầu vào này đều là 1 chỉ dành cho số BCD 0101.
Một cách tiếp cận phổ biến hơn để hiển thị các số thập phân là màn hình bảy-thanh (seven-segment display). Màn hình này bao gồm bảy dải đèn thuôn dài được xếp thành một mẫu hình đơn giản:
Màn hình bảy-thanh
Khi được sản xuất, các màn hình này thường có bảy chân cắm ở mặt sau, mỗi chân cho một trong bảy dải đèn. Một chân cắm thứ tám dùng để nối đất. Điện áp vào các tổ hợp của bảy chân cắm đó sẽ thắp sáng các dải tương ứng để hiển thị một chữ số thập phân cụ thể:
Hiển thị từ 0 tới 9
Để dễ dàng đấu dây cho màn hình hiển thị bảy thanh, mỗi thanh sáng sẽ được gán một chữ cái nhận dạng riêng:
Đặt tên cho mỗi thanh
Bảng sau đây cho biết những thanh nào phải được thắp sáng đối với từng chữ số thập phân từ 0 đến 9:
Các tín hiệu tương ứng với các chữ số thập phân đã có sẵn. Chúng chính là đầu ra của các cổng AND trong bộ giải mã BCD mà vừa được dùng để thắp sáng ống Nixie.
Hãy nhìn vào thanh "a" trước. Thanh này phải sáng cho số thập phân 0, 2, 3, 5, 6, 7, 8, hoặc 9. Điều này có nghĩa là đầu ra của tám cổng AND tương ứng với những con số đó có thể làm đầu vào cho một cổng OR tám-đầu-vào:
Cổng OR 8-đầu-vào cho thanh "a"
Bạn cũng có thể làm như vậy cho các thanh từ "b" đến "g".
Hoặc bạn có thể tìm cách khác đơn giản hơn một chút.
Thanh "a" sáng cho các số 0, 2, 3, 5, 6, 7, 8, hoặc 9, đồng nghĩa với việc nó không phát sáng cho số 1 và 4. Do đó, bạn có thể dùng đầu ra của hai cổng AND tương ứng với 1 và 4 làm đầu vào cho một cổng NOR hai-đầu-vào thông thường:
Cổng NOR 2-đầu-vào cho thanh "a"
Đầu ra của cổng NOR này là 1 trừ khi các đầu vào là tín hiệu 1 hoặc 4. Đối với hai số này, thanh trên cùng sẽ không được chiếu sáng.
Thực ra hai cách tiếp cận này không hoàn toàn giống nhau. Đôi khi bạn sẽ muốn màn hình hiển thị bảy thanh hoàn toàn trống trơn thay vì hiển thị một chữ số thập phân. Có thể đạt được điều này nếu không có tín hiệu nào trong số mười tín hiệu từ các cổng AND của bộ giải mã BCD là 1. Cổng OR tám-đầu-vào sẽ hoạt động chuẩn xác trong tình huống đó, nhưng cổng NOR hai-đầu-vào lại tiếp tục rọi sáng thanh trên cùng.
Nếu màn hình bảy thanh của bạn sẽ luôn luôn hiện một chữ số, thì một bộ giải mã bảy thanh (seven-segment decoder) có thể được tạo từ một bộ giải mã BCD như hình sau:
Bộ giải mã bảy thanh
Để ý rằng cổng NOR được dùng cho năm thanh, nhưng cổng OR và bộ đảo lại được dùng cho hai thanh còn lại.
Cũng hãy để ý rằng cổng AND ở tận cùng bên phải không được nối với thứ gì cả! Cổng AND này gắn liền với việc hiển thị chữ số 9, và mọi thanh sáng cho chữ số đó đều được chiếu sáng bởi các cổng NOR và bộ đảo rồi.
Màn hình hiển thị bảy thanh cũng có thể được nối để hiển thị các chữ số bổ sung của hệ thập lục phân, nhưng bạn sẽ cần một vài cách để phân biệt chữ B hex với số 8, và chữ D hex với số 0. Một giải pháp đòi hỏi phải trộn lẫn cả chữ hoa và chữ thường. Đây là các chữ cái A, b, C, d, E, và F:
A, b, C, d, E, F
Để biểu diễn được toàn bộ 26 chữ cái, bạn sẽ cần thêm vài thanh nữa, bao gồm cả những thanh nằm chéo. Giải pháp phổ biến là màn hình hiển thị 14 thanh và màn hình hiển thị 16 thanh.
Bạn có thể sẽ tự hỏi liệu mình có cần mạch giải mã cho mọi chữ số cần hiển thị hay không. Bạn hoàn toàn có thể làm vậy nếu thích, nhưng để tiết kiệm lượng mạch, còn có những cách khác nữa. Một kỹ thuật có tên gọi là dồn kênh (multiplexing) cho phép các mạch giải mã được dùng chung giữa nhiều chữ số khác nhau. Đầu vào của bộ giải mã có thể được chuyển đổi rất nhanh qua lại giữa các nguồn dữ liệu, và đầu ra của bộ giải mã có thể đi đến tất cả các màn hình hiển thị cùng một lúc. Tuy nhiên, đồng bộ với việc chuyển đổi bộ giải mã giữa các nguồn, sẽ chỉ có một màn hình hiển thị được nối đất. Tại bất kỳ thời điểm nào, chỉ có duy nhất một chữ số được chiếu sáng, nhưng quá trình luân phiên qua lại giữa các màn hình xảy ra nhanh đến mức mắt thường không thể nhận ra.
Lại còn một cách tiếp cận khác nữa để hiển thị số và chữ cái được gọi là ma trận điểm (dot matrix), đó là một tập hợp các bóng đèn tròn được xếp thành một lưới ngang và dọc. Kích thước lưới nhỏ nhất có thể xử lý được mọi con số, dấu câu, và chữ cái không dấu của bảng chữ cái Latin là loại rộng năm điểm và cao bảy điểm, được gọi là ma trận điểm 5x7 (5-by-7 dot matrix), được hiển thị dưới đây cho số 3:
3
Bạn có thể nghĩ rằng những chiếc đèn nhỏ xíu này có thể được điều khiển độc lập bằng cách dùng kỹ thuật đã trình bày ở màn hình hiển thị bảy thanh khi nãy. Nhưng cách đó không còn hiệu quả đâu. Có tới 35 bóng đèn nhỏ như này, và việc bật tắt từng cái một đòi hỏi một lượng mạch điện khổng lồ. Thay vào đó, người ta dùng một cách tiếp cận khác.
35 chiếc đèn đó là các diode phát quang (light-emitting diodes), hay đèn LED. Diode là các linh kiện điện tử nhỏ được ký hiệu như thế này:
Kí hiệu diode
Diode chỉ cho phép dòng điện chạy theo một chiều duy nhất — trong trường hợp này, là từ trái sang phải. Đường thẳng đứng ở bên phải tượng trưng cho việc diode chặn dòng điện vốn có thể chạy ngược từ phải sang trái.
Diode phát quang là một diode bắn ra các hạt photon (hạt ánh sáng) khi có dòng điện chạy qua. Những photon này được mắt chúng ta ghi nhận như là ánh sáng. Đèn LED thường được ký hiệu hệt như các diode nhưng có thêm các mũi tên nhỏ tượng trưng cho các tia sáng:
Kí hiệu đèn LED
Qua những thập kỷ gần đây, khi đèn LED ngày càng trở nên sáng hơn và rẻ hơn, giờ chúng đã là loại đèn phổ biến thắp sáng cho ngôi nhà của chúng ta mà lại tiêu thụ ít điện năng hơn và tỏa ít nhiệt hơn so với các loại bóng đèn khác.
35 đèn LED tạo nên một màn hình ma trận điểm 5x7 được mắc như thế này:
Mạch ma trận điểm 5x7
Mỗi đèn LED nằm ở một điểm giao giữa một hàng và một cột. Trong mỗi hàng của các đèn LED, các đầu vào của diode được nối với nhau, và trong mỗi cột, các đầu ra được nối lại. (Một sơ đồ thay thế là đầu vào kết nối theo cột còn đầu ra theo hàng, nhưng nhìn chung thì chẳng có khác biệt đáng kể nào trong cách nó hoạt động cả.)
Cách tổ chức này làm giảm số lượng kết nối từ 35 xuống chỉ còn 12 cho 7 hàng và 5 cột.
Điểm trừ là bạn chỉ có thể chiếu sáng một hàng hoặc một cột đèn trong cùng một thời điểm. Mới nghe thì có vẻ cực kỳ gò bó, nhưng có một mẹo thế này: Nếu các hàng và cột của ma trận điểm được hiển thị tuần tự chớp nhoáng, trông nó sẽ như thể toàn bộ màn hình đang sáng lên cùng một lúc vậy.
Hãy xem lại cách số 3 được hiển thị bằng ma trận điểm. Ở cột ngoài cùng bên trái, hai bóng đèn được chiếu sáng: bóng đèn trên cùng, và bóng đèn thứ hai từ dưới lên. Điều này có thể đạt được bằng cách cung cấp điện áp cho hai hàng đó, và cấp dây nối đất cho cột đầu, giống thế này:
Cột đầu tiên của số 3
Nếu bạn dò theo tất cả các đường kết nối có thể có từ điện áp đi đến điểm nối đất, bạn sẽ thấy rằng các diode cấm tiệt tất cả những lối đi khác ngoại trừ con đường dành cho hai bóng đèn đang phát sáng.
Đối với cột đèn thứ hai của số 3, bóng đèn trên cùng và bóng đèn dưới cùng sẽ phát sáng. Để làm được, hãy áp điện áp vào hai hàng đó và cung cấp một dây nối đất cho cột thứ hai:
Cột đèn thứ 2 của số 3
Các cột khác cũng hoạt động tương tự. Đối với cột ngoài cùng bên phải của số 3, ba bóng đèn phải được thắp sáng. Hãy cung cấp điện áp cho những hàng này, và cấp một dây nối đất cho cột:
Cột cuối cùng của số 3
Bây giờ chúng ta cần tìm một cách để tự động hóa quá trình cung cấp điện áp cho các hàng của ma trận điểm và cấp một dây nối đất cho một trong các cột.
Cứu tinh của ta lại là diode — nhưng chỉ là các diode thông thường chứ không phải cái loại phát quang kia. Đây là cách nối dây một vài diode sao cho giống số 3:
Nối diode để tự động hoá số 3
Bạn có nhìn ra số 3 ở đây không? Các diode tương ứng chính xác với các bóng đèn được chiếu sáng trước đó để hiển thị số 3. Nhưng tôi nhắc lại nhé, đây không phải đèn LED đâu. Chúng chỉ là những diode bình thường. Số 3 thực chất đã được mã hóa bên trong tập hợp diode đã nối này.
Cách cấu hình các diode này được gọi là ma trận diode (diode matrix). Nó đang lưu trữ thông tin, cụ thể là vị trí của các bóng đèn phải được phát sáng để hiển thị số 3. Chính vì lẽ đó, ma trận diode này cũng được xem là một loại bộ nhớ. Bởi vì nội dung của ma trận diode này không thể thay đổi mà không mắc lại các diode, nó được gọi một cách chính xác hơn là một loại bộ nhớ chỉ-đọc (read-only memory), hay ROM.
Ma trận diode ROM này có thể giúp hiển thị số 3 trên một màn hình LED ma trận điểm. Để ý các sợi dây tương ứng với mỗi cột vắt ngang qua phần trên cùng. Chúng tương ứng với năm cột của màn hình hiển thị ma trận điểm. Sơ đồ sau đây cho thấy một điện áp được cung cấp cho sợi dây dọc đầu tiên bên trái:
Cấp điện cho dây dọc bên trái
Chính nhờ cách sắp xếp của các diode, sẽ có hai điện áp ở bên phải. Chúng tương ứng với các bóng đèn cần phải được phát sáng ở cột đầu tiên của màn hình LED cho số 3.
Bằng cách cấp điện áp liên tiếp (và cực nhanh) vào các cột còn lại, mọi tổ hợp điện áp dành cho màn hình hiển thị LED ma trận điểm đều có thể được tạo ra.
Sơ đồ sau đây cho thấy ma trận diode ROM và màn hình hiển thị ma trận điểm được nối dây với nhau thông qua một số mạch phụ trợ. Ma trận diode ROM đã được xoay lại một chút so với hình bạn vừa thấy, nhưng về chức năng thì nó hoàn toàn như nhau:
Ma trận diode ROM hoàn chỉnh
Hãy bắt đầu phân tích mạch này từ góc dưới bên trái: Chúng ta cần một bộ dao động siêu tốc, đủ nhanh để bật tắt đèn thiệt lẹ tới mức hệ thống thị giác của con người thậm chí chẳng nhận ra. Bộ dao động này là đầu vào cho một bộ đếm được lắp từ ba flip-flop. Bạn đã thấy những mạch điện kiểu này trước đây rồi:
Bộ đếm 3 flip-flop
Nó tương tự như các bộ đếm được dùng trong đồng hồ, ngoại trừ việc nó chỉ đếm từ 0 đến 4, hay trong hệ nhị phân là 000, 001, 010, 011, và 100. Khi nó chạm đến 101, cổng AND sẽ xóa cả ba flip-flop về lại 0.
Những số nhị phân đó là đầu vào cho bộ giải mã 3-sang-5 hiển thị ở bên trái. Đây là một phiên bản được cắt gọt từ bộ giải mã 3-sang-8 mà ta đã thấy ở trang 114 trong Chương 10, và cũng giống với bộ giải mã BCD được chỉ ra trước đó trong chương này. Nó được cắt gọt là bởi nó chỉ cần giải mã các số nhị phân có ba chữ số từ 000 đến 100 thành một trong năm tín hiệu:
Bộ giải mã 3-sang-5
Khi số nhị phân ba chữ số đếm từ 000 đến 100, các đầu ra của bộ giải mã sẽ lần lượt là 0, 1, 2, 3, 4, và sau đó quay lại 0 cho chu kỳ tiếp theo. Lưu ý rằng đầu ra được dán nhãn "4" không yêu cầu một cổng AND, bởi vì Q2 bằng 1 chỉ khi số nhị phân là 100, tức là số 4.
Năm đầu ra này, từ 0 đến 4, tương ứng với năm cột của ma trận diode ROM ở bên trái của sơ đồ lớn, sau đó chúng cung cấp điện áp cho bảy hàng của màn hình hiển thị ma trận điểm ở bên phải. Ngoài đời thực, các điện trở sẽ được chèn vào giữa ma trận diode và màn hình hiển thị ma trận điểm để hạn chế dòng điện và tránh làm cháy đèn LED.
Các điện áp sau đó đi xuống một chiếc hộp được dán nhãn bí ẩn là "3-to-5 Sinker" (Bộ chìm dòng 3-sang-5), đây là linh kiện mới duy nhất trong mạch này.
Chúng ta cần một thứ gì đó hơi lạ một chút cho mạch này. Đồng bộ với năm tín hiệu đi ngược lên thông qua ma trận diode, chúng ta cần một cách nào đó để kết nối một trong năm cột của màn hình ma trận điểm với dây nối đất. Từ đầu sách tới giờ chúng ta toàn chế tạo các mạch điện và cổng logic cung cấp điện áp. Một mạch điện như vậy có thể được mô tả như là một nguồn dòng (current source). Nhưng giờ ta cần một thứ ngược lại. Chúng ta cần thứ gì đó có thể chìm dòng (sink a current) — một thứ nối nó với nối đất một cách tự động.
Hãy sử dụng các transistor mà chúng ta đã tìm hiểu trong Chương 15. Đây là một cái (ít nhất là dạng ký hiệu của nó):
Transistor
Ba chữ cái đại diện cho base (cực gốc), collector (cực thu), và emitter (cực phát). Một dòng điện áp vào base sẽ cho phép dòng điện chảy từ collector đến emitter, đồng nghĩa với việc ta có thể nối emitter với dây nối đất.
Phần "3-to-5 Sinker" ở phía dưới của sơ đồ lớn cực kỳ giống với bộ giải mã 3-sang-5. Thật ra, có thể dùng chung một mạch cho cả hai. Sự khác biệt duy nhất là đầu ra của các cổng AND ở trên cùng (và cả đầu vào Q2) được kết nối với các đầu vào base của năm transistor:
3-to-5 Sinker
Các dòng điện đi xuống qua năm cột của màn hình hiển thị ma trận điểm sau đó sẽ lần lượt được kết nối với dây nối đất thông qua những transistor này.
Và giờ chúng ta đã có một mạch hoàn chỉnh hiển thị số 3 trên màn hình hiển thị ma trận điểm. Tất nhiên, đây chưa hẳn là những gì chúng ta muốn. Giống như với ống Nixie và màn hình bảy thanh, chúng ta muốn mạch này hiển thị được các chữ số từ 0 đến 9 lấy từ đồng hồ cơ. Việc này đòi hỏi phải mở rộng ma trận diode bằng cách nạp thêm chín chữ số kia và sau đó triển khai thêm một tầng lựa chọn nữa bằng cách sử dụng bộ giải mã BCD.
Một phiên bản ảnh động của mạch này hiển thị các chữ số từ 0 đến 9 đã có mặt trên trang web CodeHiddenLanguage.com.
Nhưng dù cho ta có đang phấn khích cỡ nào với việc hiển thị các chữ số sinh động tương ứng với số nhị phân, thì mục tiêu của cuốn sách này không phải là tạo ra một chiếc đồng hồ.
16
Open to Work
Looking for a Fullstack Ruby on Rails developer?
I am open to new remote/hybrid opportunities and contract work.