Để thực hiện công việc đọc thời gian từ DS12887, trớc hết ta phải tiến hành chọn chip thông qua 74ALS138. Chân CS của DS 12887 đợc nối với chân Y1 của 74ALS138. Để chọn chân Y1, phải đặt A = 0, B = 1, C = 0.
Sau khi chọn chip, tiếp theo tiến hành đặt các thông số để đọc dữ liệu:
1. Đặt địa chỉ thanh ghi B của DS12887: đa địa chỉ của thanh ghi B là 0Bh vào R0 (của 8051). Gửi địa chỉ này đến Port 0 để gửi tới DS12887.
2. Đặt thông số cho thanh ghi B:
SET = 0 : không cho phép cập nhật thời gian bởi chơng trình. PIE = 1 : Cho phép ngắt.
AIE = 0 : Cho phép tín hiệu ngắt ở đầu ra IRQ. UIE = 1
SQWE = 0
DM = 0 : dữ liệu thông tin về thời gian đợc định dạng BCD. 12
24 = 1: Chế độ thời gian 24h.
DSE = 0 : Không sử dụng chế độ giờ mùa đông.
Ta chỉ quan tâm tới bit SET, PIE, DM, 2412, các bit còn lại của thanh ghi B trong bài toán này không cần chú ý tới.
3. Đọc thời gian :
- Địa chỉ byte giờ trong DS12887 là 04h. Đọc xong lu vào R2(của 8051). - Địa chỉ của byte phút trong DS12887 là 02h. Đọc xong lu vào thanh
ghi R3 (của 8051).
- Địa chỉ của byte giây trong DS12887 là 00h. Đọc xong lu vào thanh ghi R4( của 8051).
4. Chuyển đổi dữ liệu thời gian từ mã BCD sang mã ASCII để hiển thị ra LCD.
5. Hiển thị trên LCD.
• Chơng trình hợp ngữ
$debug
$tilte (** TEST PROGRAM for the MyBOARD **)
org 0000h
ljmp Main
org 0003h ; Điểm nhập vector ngắt ngoài 0. ;=======================================================; ; Trình xử lý ngắt ngoài ; ;=======================================================;
; đọc clr P3.1 ; xong dữ liệu. clr EX0 ; Cấm ngắt ngoài 0. reti ; Hết chơng trình xử lý ngắt. ;=======================================================; ; Main Program ; ;=======================================================; org 0030h
Main: call select_chip ;Gọi chơng trình con chọn ;chip.
setb P3.6 ; Cho phép ghi.
here: mov A,#0Bh ;Địa chỉ thanh ghi B của
;DS12887.
mov P0, A ; Đa ra cổng P0.
setb ALE ; Cho ALE = 1
clr ALE ; ALE = 0, tạo xung cao xuống
; thấp để chân DS cho phép chốt ; địa chỉ trong DS12887.
mov P0,#01010010b ; Đặt các giá trị điều khiển cho ; thanh ghi B của DS12887. setb ALE ;Tạo mức cao ở chân DS để giải
; phóng việc chốt địa chỉ.
mov A,#0FFh
mov P0,A ; Thiết lập P0 làm đầu vào. mov R0,#04h ; Địa chỉ byte giờ.
clr ALE
mov P0,@R0 ; Đọc byte giờ.
mov R4,P0 ; Lu giờ vào thanh ghi R4(của ; 8051).
setb ALE
mov R0,#02h ; Địa chỉ byte phút.
clr ALE
mov P0,@R0 ; Đọc phút.
mov R3, P0 ; Lu phút vào thanh ghi R3(của ; 8051)
setb ALE
mov R0,#00h ; Địa chỉ của byte giây.
clr ALE
mov P0,@R0 ; Đọc giây.
mov R2,P0 ; Lu giây vào thanh ghi R2 ; (của 8051)
setb ALE
setb EA ; Cho phép ngắt ngoài.
setb EX0 ; Cho phép ngắt ngoài 0.
set IT0 ; Kích cạnh âm.
call LCD_setup ; Khởi tạo LCD.
mov A,R2 ; Lấy lại byte giây từ R2. call convert ; Chuyển đổi sang mã ASCII. call display ; Hiển thị ra LCD
call Space ; Tạo dấu ‘:’ trên LCD. mov A,R3 ; Lấy lại byte phút từ R3.
call convert ; Chuyển mã.
call display ; Hiển thị ra LCD
call space
mov A,R4 ; Lấy lại byte giờ từ R4.
call convert ; Chuyển mã.
call display ; Hiển thị
simp $
;=======================================================; ; Chơng trình con CONVERT chuyển mã BCD thành ASCII ; ;=======================================================;
convert: mov R5, A ; Tạo bản sao của BCD vào R5.
anl A,#0Fh ; Xóa phần bit cao. orl A,#30h ; Tạo thành mã ASCII.
mov R6,A ; Lu lại phần thấp của byte dữ ; liệu đã đợc chuyển mã.
mov A,R5 ; Lấy lại giá trị ban đầu.
anl A,#0F0h ; Xóa phần thấp của byte dữ liệu.
swap A ; Hoán đổi bit cao ↔ bit thấp
orl A,#30h ; Tạo thành mã ASCII.
mov R5,A ; Lu phần cao của byte dữ liệu ; đã đợc chuyển đổi vào R5.
ret
;=======================================================; ; Chơng trình con setup LCD ; ;=======================================================;
LCD_setup: mov A,#38h ; Khởi tạo LCD 2 dòng ma trận
; 5x7 pixel
call ready ; Kiểm tra LCD đã sẵn sàng ;ch- a?
mov P2,A ; Xuất mã lệnh. clr P3.7 ;Đặt RS = 0, chọn thanh ghi ;lệnh của LCD. clr P3.6 ;RW = 0 cho phép truy cập ;thanh ghi lệnh. setb P3.4 ; E =1
clr P3.4 ; E= 0, tạo xung cao xuống thấp, ; để chốt dữ liệu.
ret
;========================================================; ; Chơng trình con DISPLAY ; ;========================================================;
display call ready ;Kiểm tra LCD đã sẵn sàng ;cha?
mov P2,R6 ; Đọc phần thấp của byte dữ liệu, ; trong R6.
call write ; Ghi ra LCD.
mov P2,R5 ; Đọc phần cao của byte dữ liệu, ; trong R5.
call write ; Đa ra LCD.
ret
;=======================================================; ; Chơng trình con WRITE ; ;=======================================================;
write: setb P3.7 ; RS = 1, chọn thanh ghi dữ
liệu ; của LCD.
clr P3.6 ; RW = 0, để ghi dữ liệu.
setb P3.4 ; E = 1
clr P3.4 ; E = 0, tạo xung cao xuống thấp ; để cho phép LCD.
ret
;=======================================================; ; Chơng trình kiểm tra xem LCD đã sẵn sàng cha? ; ;=======================================================;
ready: setb P2.7 ;Lấy P2.7 làm cổng vào kiểm
;tra.
clr P3.7 ; RS = 0, chọn thanh ghi lệnh. setb P3.6 ; RW = 1, đọc dữ liệu từ LCD.
back: setb P3.4 ; E =1
jb P2.7,back ; Đợi khi LCD rảnh. ret
;=======================================================; ; Chơng trình con tạo dấu “:” dùng để hiển thị thời gian theo kiểu “h:m:s” ; ;=======================================================;
space: call ready
mov A,#’:’
call write
ret
;=======================================================; ; Chơng trình con chọn chip ; ;=======================================================;
select_chip: clr P3.0 ; A = 0 (74ALS138)
setb P3.1 ; B = 1 (74ALS138), C = 0 (do ; chân này đợc nối đất.) ABC = ; 010 → Y1 = 0
ret
END ; Hết chơng trình.