Mạch thu thập dữ liệu số Analog 8 kênh sử dụng VXL 89C51
Saturday, 1. December 2007, 14:06:31
Mạch thu thập dữ liệu analog được sử dụng trong các thiết bị đo lường và điều khiển số để biến đổi các tín hiệu analog thành tín hiệu số, nó là mạch nối ghép giữa phần analog với phần số và máy tính. Trong các thiết bị đo lường và điều khiển số đơn giản, mạch thu thập dữ liệu analog thực hiện luôn chức năng xử lý, hiển thị và điều khiển tiếp theo, còn trong các hệ thống phức tạp hơn, các tín hiệu tương tự sau khi đã được biến đổi thành số liệu và được xử lý sơ bộ ở mạch thu thập dữ liệu sẽ được chuyển vào máy tính hoặc thiết bị số khác để tiếp tục xử lý. Trong bài viết này, chúng tôi giới thiệu với độc giả một mạch thu thập dữ liệu analog 8 kênh sử dụng bộ vi điều khiển đơn chíp 89C51 có thể nối ghép với máy tính qua cổng số liệu song song 8 bit và cổng nối tiếp.
Sơ đồ nguyên lý của mạch thu thập dữ liệu trên hình 1. Ở đây vi mạch 89C51 (U1) là bộ điều khiển trung tâm của mạch. Các mạch ngoại vi gồm có bộ hiển thị tinh thể lỏng LCD, bộ biến đổi tương tự số 8 kênh ADC0809 (U3) và cổng ra số liệu song song 8 bit 74LS373 (U2) được nối tới cổng PO của 89C51, bàn phím số HEXA (KPI) được nối đến cổng P2 của 89C51, cổng trao đổi số liệu nối tiếp MAX232 (U4) nối đến cổng P3 của 89C51. Ở đây, bàn phím KPI và LCD được sử dụng làm phương tiện giao tiếp giữa người với máy để thiết lập chế độ làm việc và hiển thị các số liệu cần thiết. Các cổng số liệu nối tiếp và song song là để chuyển số liệu cho máy tính hoặc thiết bị số khác, ngoài ra cổng nối tiếp có thể nhận các lệnh điều khiển của máy tính. Nối ghép cổng song song với máy tính hoặc thiết bị số khác được thực hiện qua giắc J2, nối ghép cổng nối tiếp với máy tính hoặc thiết bị số khác được thực hiện qua giắc J3. Các tín hiệu analog (tín hiệu tương tự) được đưa vào mạch qua giắc J1 , tất cả 8 kênh tín hiệu analog đến từ đầu ra của các mạch biến đổi tín hiệu tương tự cần phải có giá trị nằm trong khoảng từ (0 ¸5)v một chiều. Các tín hiệu analog được đưa vào xử lý ở đây có thể là dòng điện, điện áp một chiều và xoay chiều đã được biến đổi thành điện áp một chiều từ (0 ¸5)v, hoặc là các đại lượng khác như nhiệt độ, độ ẩm, áp suất, âm thanh, trọng lượng,... (nghĩa là bất kỳ đại lượng biến thiên liên tục nào) đã được biến đổi tương ứng thành giá trị điện áp một chiều từ (0 ¸5)v.

Trong mạch thu thập dữ liệu analog này, bộ vi điều khiển 89C51 được thiết lập để làm việc trong chế độ không dùng bộ nhớ ngoài, vì thế chân /EA (31) của 89C51 được nối với nguồn +5v. Ở chế độ này, tất cả 4 cổng P0 đến P3 của 89C51 đều được sử dụng làm cổng vào ra và chúng được nốt tới các thiết bị ngoại vi như đã nói ở trên (xem sơ đồ hình 1). Mạch RESET cứng của 89C51 được thực hiện trên các điện trở R1 , R2, tụ điện C3 và phím ấn RESET. Khi bật nguồn, ban đầu tụ C3 coi như bị ngắn mạch nên chân RESET (9) của 89C51 được giữ ở mức cao (>1,8v) trong khoảng thời gian đủ cho 89C51 RESET mạch nội bộ, nghĩa là nó khởi tạo giá trị ban đầu cho các thanh ghi chức năng đặc biệt SFR và đặt bộ đếm chương trình PC trỏ đến địa chỉ 00h của bộ nhớ chương trình EEPROM bên trong 89C51. Do tụ C3 được nạp với hằng số thời gian t = c3.R1 = 0,1ms nên điện áp trên chân RESET (9) của 89C51 giảm dần, khi điện áp trên chân 9 nhỏ hơn 0,5v thì quá trình RESET kết thúc, CPU của 89C51 gọi lệnh chứa ở địa chỉ 00h của bộ nhớ chương trình vào nó để thực hiện, 89C51 bắt đầu hoạt động theo chương trình chứa ở EEPROM bên trong nó. Phím ấn RESET là để làm cho mạch chạy lại từ đầu giống như khi bật nguồn mà không cần ngắt, bật nguồn.
Khi ấn phím RESET, tụ C3 bị ngắn mạch và phóng điện qua điện trở R2, do đó khi nhả phím RESET trong mạch diễn ra quá trình giống như khi bật nguồn. Bàn phím số KP1 có16 phím, được tổ chức thành 4 hàng và 4 cột, nên mạch ra của nó có 4 tín hiệu cột và 4 tín hiệu hàng. Cổng P2 của 89C51 được sử dụng để quét bàn phím nhằm phát hiện phím được ấn và đọc mã phím đó vào 89C51, các chân cổng P2.0 đến P2.3 (21 ¸24) để quét các cột, còn các chân cổng P2.4 đến P2.7 (25 ¸28) để quét các hàng của bàn phím KP1. Việc quét bàn phím và đọc mã của phím ấn được thực hiện bởi một chương trình con của phần mềm ở EEPROM của 89C51. Cổng P0 của 89C51 vừa là cổng vào để nhận số liệu của ADC0809, vừa là cổng ra để nạp số liệu cho LCD và cổng song song U2, ở mỗi thời điểm, phần mềm điều khiển sẽ quyết định P0 chỉ phục vụ một trong các mạch ngoại vi trên. Do P0 được sử dụng làm cổng ra nên cần treo các chân của nó lên mức cao bằng điện trở băng R3 (8x10k) có một đầu chung được nối với nguồn +5v. Cổng P1 của 89C51 được sử dụng để chọn mạch ngoại vi nối tới P0 và để điều khiển bộ hiển thị tinh thể lỏng LCD và bộ biến đốt tương tự SỐADC0809.Chân cổng P1.5 (6) của 89C51 là tín hiệu ra LPA tích cực mức cao được đa tới đầu vào IE của 74LS373 để cho phép nó chốt số liệu do 89C51 đa ra trên cổng P0 để gửi tới máy tính hoặc thiết bị số khác. Chân cổng P1.6 (7) của 89C51 là tín hiệu ra ELCD tích cực mức cao được đưa tới đầu vào EN của LCD để cho phép LCD nhận các số liệu trên cổng P0 do 89C51 đưa ra để hiển thị trên LCD . Chân cổng P1.7 (8) của 89C51 là tín hiệu ra RLCD tích cực mức cao được đưa tới đầu vào RS của LCD để xóa số liệu đang đợc hiển thị trên LCD. Các chân cổng P1.0, P1.1, P1.2 (1, 2, 3) của 89C51 là các tín hiệu ra SA0, SA1, SA2 được đưa tới các chân A0, Ai , A2 của ADC0809 để chọn một trong tám kênh analog trên đầu vào của ADC0809 được trích mẫu. Chân cổng P1.3 (4) của 89C51 là tín hiệu ra STAR tích cực theo sườn xuống được đưa tới các đầu vào START và ALE của ADC0809 để chốt các tín hiệu chọn kênh analog và bắt đầu quá trình trích mẫu tín hiệu tương tự của kênh analog được chọn. Sau xườn xuống của tín hiệu STAR, ADC0809 sẽ điều khiển tín hiệu ra EOC của nó xuống mức thấp để báo bắt đầu quá trình trích mẫu, sau khoảng 100μs quá trình trích mẫu kết thúc, ADC0809 điều khiển tín hiệu EOC lên mức cao để báo số liệu trên đầu ra của nó đã sẵn sàng, tín hiệu này được đa tới chân cổng INT1 (13) của 89C51. Sau khi nhận được tín hiệu EOC ở mức cao, 89C51 sẽ đưa ra tín hiệu OUT mức cao ở chân cổng P1.5 (6) để cho phép ADC0809 mở cổng số liệu ra của nó, số liệu này được 89C51 đọc vào ở cổng P0. Như vậy, tại mỗi thời điểm, ADC0809 chỉ cho phép trích mẫu một kênh tín hiệu analog do 89C51 chọn và bằng cách thay đổi các tín hiệu ra SA0, SA2, SA3 từ giá trị 00h đến 07h, 89C51 điều khiển ADC0809 lần lượt trích mẫu cả 8 kênh tín hiệu tương tự. Thời gian trích mẫu của mỗi kênh là khoảng 125μs, do đó nếu tất cả 8 kênh analog đều làm việc thì chu kỳ trích mẫu nhỏ nhất của mỗi kênh analog là khoảng 1ms, tương ứng tần số trích mẫu 1KHz. Để ADC0809 làm việc cần phải đặt điện áp chuẩn Uref = +5v đến chân REF+ và nối đất chân REF-, đồng thời phải đưa xung nhịp tới chân CLK của nó. Xung nhịp cho ADC0809 được lấy từ chân ALE (30) của 89C51 rồi được chia 2 bởi bộ đếm 74LS93 (U5), nên nếu tần số thạch anh của 89C51 là 12MHz thì xung trên đầu ra ALE là 2MHz và xung nhịp của ADC0809 là 1MHz. Các số liệu trích mẫu của 8 kênh analog được lưu giữ ở bộ nhớ RAM trong của 89C51 và có thể lập trình cho 89C51 xử lý các số liệu đó theo tính chất của từng loại tín hiệu tương tự và theo một số thuật toán xử lý số tín hiệu đơn giản rồi hiển thị chúng lên LCD hoặc gửi tới máy tính hay thiết bị số khác qua cổng ra số liệu song song hoặc cổng nối tiếp. Việc chuyển số liệu qua cổng song song U2 đến máy tính có thể được thực hiện theo phương pháp hỏi đáp hoặc dùng ngắt nhờ các tín hiệu báo số liệu ra đã sẵn sàng DR do 89C51 tạo ra trên chân cổng P3.5 và tín hiệu báo đã nhận xong số liệu ACK do máy tính đưa tới chân cổng INT0 (12) của 89C51 . Để nhận 1 byte số liệu từ cổng ra số liệu song song U2, máy tính hoặc thiết bị số khác phải đưa tín hiệu /RP tới chân OC của 74LS373 để điều khiển mở cổng U2 cho số liệu đến chúng. Việc trao đổi sổ liệu nối tiếp với máy tính được thực hiện theo chuẩn RS-232 qua vi mạch MAX232 và giắc J3. Ở đây, các chân ra của J3 được thiết kế để đảm bảo có thể nối thẳng các dây tương ứng đến giắc 9 chân của cổng COM1 máy tính.
Phần mềm của mạch thu thập dữ liệu này có thể viết trên ngôn ngữ C hoặc Assembler (mã ngữ), để tiếp nối các bài báo trước, chúng tôi trình bầy chương trình mã ngữ. Trong phạm vi của một bài báo không thể in ra toàn bộ chương trình, để giúp độc giả nắm được cấu trúc của chương trình mã ngữ, chúng tôi giới thiệu phần mở đầu của chương trình chính có lệnh gọi chương trình con để điều khiển việc trích mẫu 8 kênh tín hiệu tương tự rồi cất số liệu vào bộ nhớ RAM của 89C51 thành 8 mảng riêng biệt cho 8 kênh, mỗi mảng dài 5 số liệu. Phần mở đầu của chương trình mã ngữ thường phải khai báo các biến và cổng số liệu được sử dụng trong chơng trình, sau đó là khởi tạo điểm bắt đầu của chương trình khi RESET và các vector ngắt bằng các chỉ dẫn ORG và các lệnh nhảy đến chương trình chính và các chương trình con phục vụ ngắt. Chương trình chính bắt đầu từ địa chỉ 30h của bộ nhớ chương trình EEPROM. Đoạn đầu của chương trình chính là khởi tạo đỉnh ngăn xếp, thiết lập các ngắt được sử dụng và mức ưu tiên cho các ngắt đó. Việc trích mẫu và tạo các mảng số liệu của 8 kênh analog ở RAM trong được thực hiện bởi chương trình con CONV do chương trình chính gọi bằng lệnh ACALL.
Dưới đây là đoạn mở đầu của chương trình chính và chương trình con CONV.
;* * * * ** * * * * * * * ** **.* ** ** *** * ** * *
; Chương trình điều khiển ADC0809 trích mẫu 8 kênh analog và cất số liệu vào RAM trong ;
;* * * * * * * *** * * * ** ** ** * ** ** * ** ** **
; Khai báo tên và địa chỉ của các biến byte
BUFFEQU30h; Địa chỉ đầu vùng đệm cất số liệu ở RAM trong
TOP-SPEQU6fh; Đỉnh ngăn xếp khi khởi động
; Khai báo giá trị của các hằng số liệu tức thời
LENGEQU5; độ dài mỗi mảng sổ liệu của một kênh
NUMBEQU 8; số kênh analog cần trích mẫu
; Khai báo tên và địa chỉ của các biến bít
SA0 BITP1.0; AO chọn cổng analog của ADC0809
SA1 BITP1.1; Ai chọn cổng analog của ADC0809
SA2BITP1.2; A2 chọn cổng analog của ADC0809
STARTBIT P1.3 ; Sườn xuống của START bắt đầu trích mẫu
OUT BIT P1.4 ; OUT="1" , Mở đệm ra của ADC0809 đến cổng P0
LATCH BIT P1.5 ; LATCH="1" , Chốt số liệu của cổng P0 vào U2
E-LCD BIT P1.6 ; E_LCD="1" , Chốt số liệu của cổng P0 vào LCD
C-LCDBIT P1.7 ; C_LCD="1" , Xóa bộ hiển thị LCD
EOC BIT P3.3 ; EOC="1" , Báo kết thúc trích mẫu (là ngắt INT1)
; Mã chương trình bắt đầu từ đây. Khởi tạo các vector ngắt INT0 và cổng nối tiếp
ORG 00h ; Địa chỉ bắt đầu chương trình khi RESET
AJMP MAIN ; Nhảy đến điể bắt đầu chương trình chính
ORG 03h ; Địa chỉ vector ngắt ngoài INT0
AJMP S_INTO ; Nhảy đến chương trình con xử lý ngắt INT0
ORG 23h ; Địa chỉ vector ngắt cổng nổi tiếp.
AJMP S_PORT ; Nhẩy đến chương trình con xử lý ngắt cổng nối tiếp
;* ** * * * * * * * *** * * *** * * * * * * * *** * *
; Bắt đầu chương trình chính ;
;* * * * *** * * ** * * * * * * * *** * *** * * * * *
ORG 30h ; Điểm nhập của chương trình chính
MAIN:MOV SP,#TOP_SP ; Nạp đỉnh ngăn xếp là địa chỉ TOP_ SP ở RAM
MOV IE,#92h ; Cho phép các ngắt INT0 và cổng nối tiếp
MOV IP,#02h : Ngắt INT0 ở mức ưu tiên cao
MOV TCON,#01h ; Đặt INT0 tác động theo sườn xuống
MOV P2,#08h ; Xóa các bít cổng P2 bằng 0, riêng START= 1
REL0:ACALL CONV ; Gọi chương trình con trích mẫu 8 kênh analog
;........
; Tiếp theo là các lệnh xử lý và trao đổi số liệu
;......
NOP
AJMP REL0 ; Nhẩy về RELO để trích mẫu lấy số liệu
;......
; Hết chương trình chính, bắt đầu các chương trình con
;** * * *** * ** * * **** * * * * *** **** ** ** * * * *** *
; CONV: Chương trình con trích mẫu tín hiệu của 8 kênh analog và cất số liệu thành 8 mảng ;
; Cho 8 kênh, mỗi mảng dài 5 byte bắt đầu từ địa chỉ BUFF ở RAM trong của 89C51 ;
; Sử dụng các thanh ghi: R0, R6, R7, B và thanh chứa A
;****** ******* ************ *** * ********* ** *
CONV:MOV R6,LENG ; Dùng R6 làm con đếm chỉ số mảng số liệu
MOV B,BUFF ; B chứa địa chỉ cất số liệu của kênh 0 (mảng 0)
MOV R7,#0 ; R7 giữ địa chỉ chọn kênh analog, từ kênh 0
CONI: MOV R0,B ; R0 là con trỏ để cất số liệu vào RAM trong
CON2: CLR SA0 ; Xoá SA0 = 0
CLR SA1 ; Xoá SA1 = 0
CLR SA2 ; Xoá SA2 = 0
MOV A,R7 ; Nạp địa chỉ chọn kênh analog vào A
ORL P1,A ; Gởi địa chỉ chọn kênh analog đến ADC0809
NOP ; Giữ chậm để địa chỉ ổn định
CLR START ; Sườn xuống của START kích bắt đầu trích mẫu
JB EOC,$ ; Đợi ADC0809 hạ EOC="0" báo bắt đầu trích mẫu
SETB START ; Trả START về mức cao: START="1
JNB EOC,$ ; Đợi EOC="1" báo kết thúc trích mẫu
SETB OUT ; OUT = 1, mở mạch ra ADC0809 tới cổng P0
NOP ; Giữ chậm cho số liệu ổn định trên BUS
MOV @R0,P0 ; Cất số liệu trích mẫu vào ô nhớ trỏ bởi R0
MOV A,R0 ; Gửi giá trị của R0 vào A:(A)="(R0)
ADD A,#LENG ; (A)="(A)+LENG" , địa chỉ cất số liệu của kênh sau
MOV R0,A ; R0 trỏ đến ô nhớ cất số liệu của kênh tiếp theo
INCR7 ; Tâng địa chỉ chọn kênh analog đến kênh tiếp theo
CJNER7,#NUMB, CON2 ; (R7)<8, chia hết 8 kênh, về CONV2 làm tiếp
INCB ; (R7)="8," Tăng B đến ô nhớ tiếp theo của kênh 0
DJNZ R6,CON1 ; (R6)-1 ="(R6)>O," nhẩy về CONV1 lấy số liệu tiếp
RET (R6)="0," đã lấy đủ 8 mảng số liệu của 8 kênh
; Còn các chương trình con khác nữa.
END ; Kết thúc chương trình
Sau khi điều khiển ADC0809 trích mẫu, chương trình này không sử dụng ngắt mà quay vòng tại chỗ đợi tín hiệu báo kết thúc trích mẫu EOC của ADC0809 lên cao thì đọc số liệu, chương trình như vậy đơn giản và dễ viết, nhưng có nhược điểm lớn là không tận dụng được thời gian ADC trích mẫu để làm việc khác. Thời gian ADC0809 trích một mẫu tín hiệu tương tự là 1 100μs, nếu dùng ngắt thì thời gian đó 89C51 có thể xử lý các số liệu đã nhận được trước đó hoặc thực hiện trao đổi số liệu với máy tính.








