Kênh Tên Miền chuyên cung cấp tên miền đẹp, giá rẻ! Hãy liên hệ kỹ thuật: 0914205579 - Kinh doanh: 0912191357 để được tư vấn, hướng dẫn miễn phí, Cảm ơn quý khách đã ủng hộ trong thời gian qua!
Saturday, December 7, 2013



Dùng bo vi điều khiển họ AT89... 16 đường ra làm bảng đèn 

quảng cáo

Bạn biết, kiến thức là luôn luôn cải biến và phát triển, do đó các bài viết của tôi ở đây cũng luôn theo tôn chỉ của RIXIN, nghĩa là Nhật Tân 日新 (Ngày mới, ngày mới, ngày ngày mới。日新,日新,日日新). Các bài viết luôn được người soạn  đọc đi đọc lại và sửa lỗi, viết thêm vào các ý tưởng mới và các bài viết luôn được làm tươi. Nó giống như một vườn cây  được người trồng  vườn chăm coi cẩn thận và khu vườn thì đang ngày ngày sinh trưởng, các bài viết sẽ luôn mới, luôn khác và mỗi ngày đều được bổ xung tu chỉnh, và thêm mới. Mong Bạn thường xuyên quay lại để xem và góp ý. Người soạn: Vương Khánh Hưng.

       


 
Phần bài viết

 Hình chụp cho thấy bo mạch dùng vi điều khiển AT89C51/52... có 16 đường ra, đã ráp hoàn chỉnh và hiện có bán ở cửa hàng điện tử Phúc Lan. Bạn có thể dùng bo này với các chương trình tự viết để điều khiển các bảng đèn quảng cáo dùng nhiều Led, hay điều khiển các thiết bị tự động trong công nghiệp.




Bo có các đặc tính sau:



* Có 16 đường ra, trên mỗi đường ra dùng transistor thúc 2SC2383, có khả năng cấp dòng lớn, nhờ vậy trên một đường ra nó có thể cấp dòng cho trên 100Led.

* Trong mạch dùng nguồn ổn áp 5V (với ic 7805), như vậy Bạn có thể tăng mức nguồn DC cấp cho các Led trên bảng đèn mà không ảnh hưởng đến hoạt động của ic vi điều khiển.

* Trên bo có mạch chỉnh tốc độ nhẩy, Bạn chỉ cần chỉnh biến trở 100K là có thể chọn được tốc độ nhấp nháy theo ý.

* Ở ngã vào có đặt diode 1N4007 tránh mắc sai cực nguồn làm hư bo.

* Bạn chỉ cần bố trí các Led trên bảng đèn, theo nhánh và tính số nhánh phải dùng cho một phần tử tđơn vị hình rên bảng đèn, rồi cho đấu vào bo, trên chân C của các transistor thúc là xong.



Sơ đồ mạch điện nguyên lý:



Trên bo có các mạch điện cơ bản như sau:


Mạch điện nguồn nuôi với ic 7805.

Nguồn vào 12V DC. Diode D0 (1N4007) dùng tránh mắc sai cực nguồn. Nếu Bạn gắn sai cực, nhờ tính ghim áp của diode, nó sẽ giữ cho mức áp nghịch ở ngả vào của bo ở mức 0.8V, mạch sẽ khi bị hư.

Tụ C1 (1000uF), tụ hóa lớn dùng làm kho chứa điện, có công dụng ổn định điện áp đường nguồn, ở đây Bạn sẽ có 12V dùng cấp nguồn cho các dãy Led. Bạn cũng có thể cấp đường nguồn này cao hơn để có thể mắc trên một nhánh được nhiều Led nối tiếp hơn (xem phần hướng dẫn ở phần sau).

Tụ C2, C4 có trị nhỏ 104pF (0.1uF) có công dụng lọc bỏ tín hiệu nhiễu tần cao nhiễm trên đường nguồn.

Tụ C3 (10uF), mắc ở ngả ra của ic ổn áp 7805 dùng tránh phát sinh hiện tượng dao động tự kích bên trong ic ổn áp 7805.

Mạch dùng ic ổn áp 3 chân họ 78xx, với ic 7805, trên ngả ra sẽ luôn có mức áp 5V với độ ổn định cao, chúng ta sẽ dùng mức áp này để cấp cho chân 40 của ic vi điều khiển AT89C51/52....


Mạch thạch anh định tần.
Để chạy các câu lệnh trong ic vi điều khiển, Bạn cần tạo ra xung nhịp. Tần số xung nhịp phụ thuộc vào thạch anh gắn trên chân 18, 19. Với thạch anh 12MHz, Bạn sẽ có xung nhịp 1MHz, như vậy chu kỳ lệnh sẽ là 1us.

Để tăng độ ổn định tần số, người ta dùng thêm 2 tụ nhỏ C6, C7 (33pF x2), tụ bù nhiệt ổn tần.

Điều này cho thấy, Bạn cũng có thể thay đổi nhịp nhấp nháy của đèn nếu dùng thạch anh có tần số khác.


* Mạch reset.
 

Với tụ C5 (10uF) và điện trở R1 (10K) trên chân số 9, ngay khi mạch được cấp nguồn 5V, tụ C5 nạp điện từ mức áp 0V, vậy nó sẽ kéo chân 9 lên mức áp cao, với mức áp cao trên chân 9, ic vi điều khiển sẽ bị reset, nó sẽ đặt ic về trạng thái khởi đầu, sau một lúc (thời hằng phụ thuộc vào R1 và C5), tụ C5 sẽ nạp đầy mức áp 5V, nó trả chân 9 về mức áp thấp và lúc này ic AT89C51/52 sẽ bắt đầu chạy các câu lệnh mà Bạn đã nạp vào bộ nhớ EEP-ROM của nó.


Mạch chỉnh tốc độ nhịp.
 
Ở đây chúng ta cho kết hợp phần mềm và phần cứng để làm thay đổi nhịp nháy. Dùng mạch nạp xả tạo bởi tụ C8 (100uF) và điện trở R2 + RV1 và điều khiển đóng mở với transistor Q1,  xung tắt mở lấy trên chân p3.6, sau đó dùng câu lệnh jb (jump bit...) để theo dõi bit 0/1 trên chân p3.7. Vậy Bạn có thể làm cho mức áp trên chân 17 lên chậm bằng cách tăng biến trở RV1, đều này sẽ giảm nhịp nháy. Tóm lại, giảm trị RV1 nhịp nhanh và tăng trị RV1 sẽ có nhịp chậm.


Mạch khuếch đại thúc, cấp dòng cho các hiển thị.

Ở đây chúng ta dùng trasistor 2SC2383 có khả năng cấp dòng Ic đến 1000mA để cấp dòng cho các Led gắn trên chân C.

Chân B qua điện trở hạn dòng 2.2K cho gắn vào một chân của các cảng p0 hay p2, vậy khi chân này ở mức áp cao (bit 1), transistor sẽ vào trạng thái bảo hòa (dẫn điện mạnh) và nó sẽ cấp dòng cho các Led gắn trên chân C phát sáng, và khi chân B  ở mức áp thấp (bit 0), transistor sẽ ngưng dẫn và tắt Led. Để hạn dòng qua các Led Bạn dùng điện trở 330.

Ghi nhận: Đây chỉ là Led gắn trên bo mạch, nó được dùng để giúp Bạn kiểm tra các câu lệnh do Bạn tự soạn. Khi sử dụng Bạn sẽ thay Led này bằng một nhóm nhiều Led (niều hánh Led). Các Led này cho mắc nối tiếp trên một nhánh, và cho ghép song song nhiều nhánh để có đủ số Led tạo ra một đơn vị  hình trên bảng đèn quảng cáo.


Sau đây là các hình chụp minh họa cho cách dùng bo vi điều khiển với AT89C51/52 kiểu bo có 16 đường ra:

Hình chụp chao thấy các thành phần mạch điện cơ bản trên bo AT89C51/52, kiểu 16 đường ra.


  
Các đường ra nối vào các port 0 và port 2:


Cách dùng nhiều Led để tạo ra một đơn vị hình trên bảng đèn quảng cáo:

Hình vẽ minh họa cách dùng nhiều Led trên một đường ra:


Cách tạo bảng đèn quảng cáo dùng nhiều Led màu:


Kiểm tra bo điều kiển 16 đường ra với AT89C51/52...

 




Hộp nạp TOP853 và các ic vi điều khiển AT89C51/52... (Bạn xem bài giới thiệu cách dụng hộp nạp này trong chuyên mục "Trao đổi học tập").






Hình dạng các ic vi điều khiển AT89C51/52...(ic có 40 chân, chân 1 nối masse và chân 40 nối nguồn).



Các thành phần của bo vi điều khiển 16 đường ra với ic AT89C51/52...


Lớp mạch in (Hình chụp cho thấy các điểm hàn bên dưới mạch).



Mạch nguồn nuôi DC 5V lấy trên ic ổn áp 7805.

  
 Mạch chỉnh tốc độ của nhịp nhấp nháy với biến trở 100K.



Phụ lục: Một gợi ý về cách làm bảng đèn quảng cáo.

Để làm bảng đèn quảng cáo, thường gồm các bước sau:

Bước 1: Làm bảng chữ, Thí dụ như bảng chữ cửa hàng điện tử Phúc Lan có hình như sau.

Bước 2: Bạn khoan các lổ để gắn Led theo chữ theo hình, hay  gắn Led theo các đường chữ (tùy theo ý của Bạn). Số Led của một đơn vị hình gắn theo từng nhánh (với Led siêu sáng, mỗi nhánh có 3 Led) và các nhánh cho mắc song song, mỗi nhánh có một điện trở hạn dòng và sau cùng một con chữ (một đơn vị hình) sẽ chỉ có 2 dây. Một dây nối vào nguồn +12V và dây còn lại Bạn nối vào chân C của các transistor thúc.


Với Bảng đèn này, chúng ta lấy 11 đơn vị hình cho chữ PHÚC LAN, 1 đơn vị hình cho chữ ĐIỆN, 1 đơn vị hình cho chữ TỬ và 1 đơn vị hình cho khung. Tổng cộng là 14 đơn vị hình.

Bước 3: Tính điện trở hạn dòng cho các nhánh Led và tính dòng cung cấp của các transistor thúc.

Trên thị trường có 2 loại Led. Loại Led thường, có mức ghim áp khoảng 2V và loại Led siêu sáng có mức ghim áp là 3V. Vậy dùng luật Ohm Bạn dễ dàng tính được trị của điện trở hạn dòng R (Bạn xem hình).

Dùng luật Ohm để tính điện trở hạn dòng trên nhánh chỉ có 1 Led.


Hình sau đây cho thấy, cách dùng luật Ohm tính điện trở hạn dòng cho nhánh có nhiều Led mắc nối tiếp. 


Sau đây là hình cho thấy các mắc song song nhiều nhánh cho một đơn vị hình trên bảng đèn quảng cáo. Trên mỗi nhánh đều có một điện trở hạn dòng riêng.
Đến đây có thể nói Bạn đã làm xong phần cứng gồm bảng đèn và bo vi điều khiển, Bây giờ hãy nói đến cách viết phần mềm cho bảng đèn quảng cáo trên.


Bước 4: Cách viết câu lệnh điều khiển bảng đèn quảng cáo.

Trước hết, Bạn hãy xem hình cho thấy cách chúng ta chọn định các chân để điều khiển bảng đèn quảng cáo:


Hình vẽ cho thấy các đơn vị hình được điều khiển bởi các chân của port 2, port 0. Chúng ta dùng:

Chân p2.0  để tắt mở cho chữ  P
Chân p2.1 để tắt mở cho chữ  H
Chân p2.2  để tắt mở cho chữ  Ú
Chân p2.3  để tắt mở cho chữ  C
Chân p2.4  để tắt mở cho chữ  L
Chân p2.5  để tắt mở cho chữ  A
Chân p2.6  để tắt mở cho chữ  N
Chân p2.7  để tắt mở cho chữ  S
Chân p0.0  để tắt mở cho chữ  H
Chân p0.1  để tắt mở cho chữ  O
Chân p0.2  để tắt mở cho chữ  P
Chân p0.3  để tắt mở cho chữ  Điện
Chân p0.4  để tắt mở cho chữ  Tử
Chân p0.5  để tắt mở cho chữ  <Khung của bảng>

Sau khi đã chọn định xong phân cứng chúng ta bắt đầu viết các chương trình con cho các kiểu nháy của bảng đèn.

Kiểu sáng chữ P với bit 1 trên chân p2.0
Kiểu tắt chữ P với bit 0 trên chân p2.0

Kiểu sáng chữ H với bit 1 trên chân p2.1
Kiểu tắt chữ H với bit 0 trên chân p2.1

Kiểu sáng chữ Ú với bit 1 trên chân p2.2
Kiểu tắt chữ Ú với bit 0 trên chân p2.2

Kiểu sáng chữ C với bit 1 trên chân p2.3
Kiểu tắt chữ C với bit 0 trên chân p2.3

Kiểu sáng chữ L với bit 1 trên chân p2.4
Kiểu tắt chữ L với bit 0 trên chân p2.4

Kiểu sáng chữ A với bit 1 trên chân p2.5
Kiểu tắt chữ A với bit 0 trên chân p2.5

Kiểu sáng chữ N với bit 1 trên chân p2.6
Kiểu tắt chữ N với bit 0 trên chân p2.6

Kiểu sáng chữ S với bit 1 trên chân p2.7
 Kiểu tắt chữ S với bit 0 trên chân p2.7

Kiểu sáng chữ H với bit 1 trên chân p0.0
Kiểu tắt chữ H với bit 0 trên chân p0.0

Kiểu sáng chữ O với bit 1 trên chân p0.1
 Kiểu tắt chữ O với bit 0 trên chân p0.1

Kiểu sáng chữ P với bit 1 trên chân p0.2
Kiểu tắt chữ P với bit 0 trên chân p0.2

Kiểu sáng chữ Điện với bit 1 trên chân p0.3
Kiểu tắt chữ Điện với bit 0 trên chân p0.3

Kiểu sáng chữ Tử với bit 1 trên chân p0.4
Kiểu tắt chữ Tử với bit 0 trên chân p0.4

Kiểu sáng [khung bảng] với bit 1 trên chân p0.5
Kiểu tắt [khung bảng] với bit 0 trên chân p0.5

Kiểu sáng từng chữ P - H - Ú - C - L - A - N - S - H - O - P - Điện - Tử - [Khung] với bit 1.
Kiểu tắt  từng chữ P - H - Ú - C - L - A - N - S - H - O - P Điện - Tử - [Khung] với bit 0

Vậy các chương trình con sẽ viết như sau:

 xoabangden:                        ; chương trình xóa, làm tắt tất cả các Led trên bảng đèn.
     mov p2, #00000000b     ; Cho port p2 về mức áp thấp để làm ngương dẫn các transistor thúc.
     mov p0, #00000000b     ; Cho port p0 về mức áp thấp để làm ngương dẫn các transistor thúc.
       ret                                      ; Quay lại sau lệnh call.

sang_het_bang_den:           ; chương trình làm sáng tất cả các Led trên bảng đèn.
    mov p2, #11111111b       ; Cho đặt các chân transistor thúc lên mức áp cao.
     mov p0, #00111111b      ; Cho đặt các chân transistor thúc lên mức áp cao.
       ret                                      ; Quay lại sau lệnh call.


phuc_sang:                             ; chương trình chỉ làm sáng chữ PHÚC
      mov p0,  #00000000b
     mov p2,  #00001111b
       ret

lan_sang:                                 ; chương trình chỉ làm sáng chữ LAN
      mov p0, #00000000b
     mov p2, #01110000b
       ret

shop_sang:                              ; chương trình chỉ làm sáng chữ SHOP
      mov p0, #00000111b
     mov p2, #10000000b
       ret

 dien_sang:                              ; chương trình chỉ làm sáng chữ Điện
     mov p0, #00000000b
     mov p2, #10000000b
     ret

tu_sang:                                   ; chương trình chỉ làm sáng chữ Tử
     mov p0, #00000001b
     mov p2, #00000000b
      ret

sang_chu_up:                          ; chương trình cho từng con chữ sáng lan lên qua bên phải
     mov p2, #00h
     mov p0, #00h
     call delay
      setb p2.0
     call delay
      setb p2.1
      call delay
      setb p2.2
     call delay
      setb p2.3
     call delay
      setb p2.4
     call delay
      setb p2.5
     call delay
      setb p2.6
     call delay
      setb p2.7
     call delay
      setb p0.0
     call delay
      setb p0.1
     call delay
      setb p0.2
     call delay
      setb p0.3
     call delay
      setb p0.4
       ret

tat_chu_down:                              ; chương trình cho từng con chữ tắt lan qua bên trái.
      mov p2, #11111111b
      mov p0, #00011111b   
      call delay
      clr p0.4
      call delay
      clr p0.3
      call delay
      clr p0.2
      call delay
      clr p0.1
      call delay
      clr p0.0
      call delay
      clr p2.7
      call delay
      clr p2.6
      call delay 
     clr p2.5
      call delay 
      clr p2.4
      call delay     
      clr p2.3
      call delay   
      clr p2.2
      call delay
      clr p2.1
      call delay
     clr p2.0
      call delay
     ret
     
* Đại thể công việc viết các kiểu nhấp nháy dùng câu lệnh đặt 1  (Set bit) để sáng hay đặt 0  (Clear bit) để tắt là như phần trình bày trên.

* Bây giờ Bạn dùng phần mềm MIDE-51 để viết chương trình nguồn và chép lại với tên file có họ là .asm và cho biên dịch (với phím F9) để có file cùng tên, nhưng họ là .hex. 

* Đến đây chỉ việc dùng một hộp nạp mà Bạn có để nạp các mã lệnh vào bộ nhớ EEP-ROM của ic vi điều khiển AT89C51/52, rồi cắm ic vào bo ứng dụng là xong chuyện, sau này muốn thay đổi kiểu nháy thì viết thêm và làm tương tự, rất đơn giản phải không?


Sau đây là các câu lệnh trong file bqc-1.asm:

org 0000h                                       ; Khởi đầu từ thanh nhớ reset.
start:                                                ; Đặt tên nhãn start.
     call xoabangden                       ; cho gọi chương trình xóa bảng đèn. 
     call sang_het_bang_den         ; Cho bảng đèn sáng hết.
       call delay                                   ; bảng đèn tiếp tục sáng.
     call delay                                    ; bảng đèn tiếp tục sáng.
     call xoabangden                        ; Cho bảng đèn tắt hết.
      call delay                                     ; Bảng đèn đang tắt.
     call phuc_sang                           ; Cho chữ PHÚC phát sáng.
     call delay                                     ; Chờ, lúc này chỉ có chữ PHÚC sáng.
     call lan_sang                               ; Cho chữ LAN phát sáng.
     call delay                                     ; Chờ, lúc này có 2 chữ PHÚC và LAN sáng.
     call shop_sang                           ; Cho chữ SHOP phát sáng.
    call delay                                      ; Chờ, lúc này có 3 chữ sáng là PHÚC LAN SHOP
     setb p0.5                                     ; Cho chữ Điện phát sáng.
     setb p0.4                                     ; Cho chữ Tử phát sáng.
     setb p0.3                                     ; Cho khung phát sáng
     call delay                                      ; Chờ, lúc này cả bảng đèn đều phát sáng.
      call delay
      call xoabangden
      mov r1, #20                                  ; Nạp số lần 20 và thanh ghi r1.
tt_1:                                                    ; Đặt tên nhãn là tiếp tục 1.        
     call sang_chu_up                         ;  Gọi chương trình cho từng chữ trên bảng sáng lan lên
     call delay                                       ; chờ.
     call tat_chu_down                         ; Gọi chương trình cho tắt từ chữ trên bảng đèn.
      call delay                                        ; chờ
    djnz r1, tt_1                                     ; Giảm trị trong r1, chưa bằng 0? nhẩy về tên nhãn tt_1
     call delay                                         ; chờ
    jmp start                                           ; Quay lại từ đầu.

xoabangden:                                       ; Chương trình con dùng xóa hết bảng đèn.
     mov p2,  #00000000b
     mov p0,  #00000000b
       ret

sang_het_bang_den:                           ; Chương trình con dùng cho sáng hết bảng đèn   
     mov p2,  #11111111b
     mov p0,  #00111111b
       ret

phuc_sang:                                             ; Chương trình con dùng cho chữ PHÚC sáng
      mov p0, #00000000b
     mov p2, #00001111b
       ret

lan_sang:                                               ; Chương trình con dùng cho chữ LAN sáng
      mov p0, #00000000b
     mov p2, #01110000b
       ret

shop_sang:                                            ; Chương trình con dùng cho chữ SHOP sáng.
      mov p0, #00000111b
     mov p2, #10000000b
       ret

 dien_sang:                                             ; Chương trình con dùng cho chữ Điện sáng.
     mov p0, #00000000b
     mov p2, #10000000b
     ret

tu_sang:                                                    ; Chương trình con dùng cho chữ Tử sáng.
     mov p0, #00000001b
     mov p2, #00000000b
      ret

sang_chu_up:                                         ; Chương trình con dùng cho từng chữ sáng lan lên.
     mov p2, #00h
     mov p0, #00h
     call delay
      setb p2.0
     call delay
      setb p2.1
      call delay
      setb p2.2
     call delay
      setb p2.3
     call delay
      setb p2.4
     call delay
      setb p2.5
     call delay
      setb p2.6
     call delay
      setb p2.7
     call delay
      setb p0.0
     call delay
      setb p0.1
     call delay
      setb p0.2
     call delay
      setb p0.3
     call delay
      setb p0.4
       ret

tat_chu_down:                                    ; Chương trình con dùng cho từng chữ tắt dần xuống.
      mov p2, #11111111b
      mov p0, #00011111b   
      call delay
      clr p0.4
      call delay
      clr p0.3
      call delay
      clr p0.2
      call delay
      clr p0.1
      call delay
      clr p0.0
      call delay
      clr p2.7
      call delay
      clr p2.6
      call delay 
     clr p2.5
      call delay 
      clr p2.4
      call delay     
      clr p2.3
      call delay   
      clr p2.2
      call delay
      clr p2.1
      call delay
     clr p2.0
      call delay
     ret

delay:                                    ; Chương trình con dùng làm trễ
         mov r7, #20                 ; Nạp trị 20 vào thanh ghi r7
v6:    mov r6, #50                  ; Nạp trị 50 vào thanh ghi r6
v5:    mov r5, #200                ; Nạp trị 200 vào thanh ghi r5
         djnz r5, $                       ; Chờ r5 giảm theo bước -1 đến bằng 0.
         djnz r6, v5                      ; Cho trị trong r6 giảm theo bước -1, chưa bằng 0, về tên nhãn v5.
         djnz r7, v6                        ; Cho trị trong r7 giảm theo bước -1, chưa bằng 0, về tên nhãn v6.
           ret                                  ; Quay lại chạy câu lệnh sau câu lệnh call đã gọi delay trước đó. 
end                                           ; dừng biên dịch từ vi trí này.



Sau khi dịch ra mã lệnh, chúng ta có file bqc-1.hex như sau:

:1000000012004812004F12010C12010C120048128B
:10001000010C12005612010C12005D12010C1200AC
:100020006412010CD285D284D28312010C12010C0D
:10003000120048791412007912010C1200C1120149
:100040000CD9F212010C80B875A0007580002275E1
:10005000A0FF75803F2275800075A00F227580007B
:1000600075A0702275800775A0802275800075A02C
:10007000802275800175A0002275A0007580001295
:10008000010CD2A012010CD2A112010CD2A21201B9
:100090000CD2A312010CD2A412010CD2A512010C95
:1000A000D2A612010CD2A712010CD28012010CD2DE
:1000B0008112010CD28212010CD28312010CD28463
:1000C0002275A0FF75801F12010CC28412010CC2A0
:1000D0008312010CC28212010CC28112010CC28077
:1000E00012010CC2A712010CC2A612010CC2A51269
:1000F000010CC2A412010CC2A312010CC2A2120173
:100100000CC2A112010CC2A012010C227F147E327B
:090110007DC8DDFEDEFADFF622F7
:00000001FF

 
(Bạn dùng hộp nạp cho nạp các mã lệnh này vào nằm trong bộ nhớ EEP-ROM của ic vi điều khiển AT89C51/52 và dùng ic này với bo 16 đường ra để điều khiển bảng đèn quảng cáo trên).


Trên đây chỉ là một thí dụ giúp Bạn làm quen với cách viết các câu lệnh cho bảng đèn quảng cáo.  Ở đây, chúng ta chỉ dùng những câu lệnh cơ bản cũng làm được điều mình muốn. Sau này khi đã quen rồi, tự Bạn sẽ có thể viết được nhiều chương trình đa dạng hấp dẫn hơn.
    
Qua phần trình bày trên, chúng tôi mong Bạn đã hiểu cách dùng bo vi điều khiển AT89C51/89C52...hiện có bán ở cửa hàng Phúc Lan, dùng nó ráp nhanh các bảng đèn quảng cáo, hay nó còn được dùng cho các công việc điều khiển tự động khác nữa, về cách viết các chương trình điều khiển bảng đèn, sẽ được chúng tôi tiếp tục trình bày trong các bài khác, mong Bạn thường xuyên vào đọc.HI TIẾT CHỦ ĐỀ

Hướng dẫn Bạn viết 10 chương trình ứng dụng cơ bản cho ic vi điều khiển AT89C51

 
Bạn biết, kiến thức là luôn luôn cải biến và phát triển, do đó các bài viết của tôi ở đây cũng luôn theo tôn chỉ của RIXIN, nghĩa là Nhật Tân 日新 (Ngày mới, ngày mới, ngày ngày mới。日新,日新,日日新). Các bài viết luôn được người soạn  đọc đi đọc lại và sửa lỗi, viết thêm vào các ý tưởng mới và các bài viết luôn được làm tươi. Nó giống như một vườn cây  được người trồng  vườn chăm coi cẩn thận và khu vườn thì đang ngày ngày sinh trưởng, các bài viết sẽ luôn mới, luôn khác và mỗi ngày đều được bổ xung tu chỉnh, và thêm mới. Mong Bạn thường xuyên quay lại để xem và góp ý. Người soạn: Vương Khánh Hưng.


Trước hết chúng ta hãy tìm hiểu nguyên lý làm việc của ic vi điều khiển AT89C51 (Bạn xem hình).


IC AT89C51 có 40 chân. Công dụng của các chân như sau:

* Chân 40 nối vào đường nguồn 5V, chân 20 cho nối masse.

* Chân 9 nối vào mạch reset với điện trở 10K và tụ 10uF. Khi mạch vừa được cấp điện, tụ nạp và kéo chân 9 lên mức áp cao tạo tác động reset. Sau một lúc chân 9 trở lại mức áp thấp. IC AT89C51 bắt đầu hoạt động từ trạng thái khởi đầu.

* Chân 18, 19 mắc thạch anh định tần. Như vậy tần số xung nhịp sẽ là 1Mhz (hay 1us). Ngang thạch anh mắc 2 tụ nhỏ dùng để bù nhiệt ổn tần (Bạn xem hình).



* Chân 31 Bạn phải cho treo lên mức áp cao, để xác định là mạch chỉ làm việc với bộ nhớ nội (Vì mạch không dùng thêm bộ nhớ ngoài).

* Bạn chú ý, ic có 4 cảng, đó là port 0 (p0), port 1 (p1),  port 2  (p2) và port 3 (p3). Mỗi cảng có 8 chân. Mọi hoạt động của ic vi điều khiển đều được thực hiện trên các cảng này.

Ghi nhận: Bạn thấy ic AT89C51 chỉ cần một ít linh kiện bên ngoài là đã có thể chấp hành các câu lệnh đã có trong bộ nhớ EEP-ROMBạn dùng các câu lệnh này để xác định trạng thái điện áp cao thấp trên các cảng và dùng các mức áp cao thấp này cho việc điều khiển các dạng mạch điện, hay các thiết bị.


Bài 1: Viết chương trình để Led trên chân số 1 (p1.0) luôn nhấp nháy.

ORG  0000h                                                ; Khởi đầu từ thanh ghi có địa chỉ là 0000h

START:               CLR P1.0                         ; Đặt chân p1.0 xuống mức áp thấp, Led sẽ sáng.

                            LCALL DELAY                 ; Cho gọi trình làm trễ (có tên nhãn là delay).

                            SETB P1.0                       ; Đặt chân p1.0 lên mức áp cao, Led sẽ tắt

                            LCALL DELAY                  ; Lại cho gọi trình làm trễ (có tên nhãn là delay).    

                            LJMP START                    ; Cho nhẩy về dòng lệnh với tên nhãn là start, công việc sẽ lập lại.

DELAY:              MOV R5,#20                      ; Nạp trị 50 vào thanh nhớ r5.                
D1:                      MOV R6,#20                     ; Nạp trị 20 vào thanh nhớ r6.

D2:                      MOV R7,#248                   ; Nạp trị 248 vào thanh nhớ r7.

                            DJNZ R7,$                        ; Cho giảm r7 theo bước -1 cho đến 0.

                            DJNZ R6,D2                      ; Cho giảm r6 theo bước -1, chưa bằng 0 thì nhẩy về D2.

                            DJNZ R5,D1                      ; Cho giảm r5  theo bước -1, chưa bằng 0 thì nhẩy về D1.

                            RET                                   ; Quay lại dòng lệnh sau lệnh lcall.

                            END                                   ; dừng biên dịch.

Phân tích cách viết các câu lệnh:

Bạn thấy khởi đầu luôn dùng câu khai báo giả lệnh:  org 0000h

Nghĩa là mọi việc sẽ bắt đầu từ thanh nhớ có địa chỉ là 0000h. Đây cũng là thanh mà chương trình sẽ nhấy đến mỗi khi Bạn nhấn nút Reset.

và kết thúc với khai báo giả lệnh: end

Các câu lệnh sau khai báo bởi giả lệnh "end" sẽ không được biên dịch.

Nói rõ hơn về cách tính thời gian trễ của đoạn chương trình con delay:

Trong hình trên do dùng thạch anh 12MHz nên một chu kỳ máy sẽ là 1us. 


Vậy câu lệnh:  mov r6,#20    sẽ thực hiện 2 lần. Bạn phải cho nhân 2. Từ đó cách tính như sau:
             MOV R6,#20                       2lần          2

D1:       MOV R7,#248                     2 lần         2       2+2×248=498 20×

              DJNZ R7,$                          2 lần         2×248             (498
              DJNZ R6,D1                       2 lần   2×20=40           10002

Qua các nhân thời gian trễ của đoạn chương trình delay này là 10.002ms.
Nếu Bạn mov vào r6=10 thì thời gian trễ sẽ là 5ms.
Nếu Bạn mov vào r6=20 thì thời gian trễ sẽ là 10ms.

Và để có thời gian trễ là 200ms. Bạn dùng thêm thanh nhớ r5. Mov vào r5=20. Và như vậy đoạn chương trình trễ delay 200ms như sau:


DELAY:     MOV R5,#20     ; chuyển vào thanh ghi r5 số thập phân 20.

D1:             MOV R6,#20     
; chuyển vào thanh ghi r6 số thập phân 20.

D2:             MOV R7,#248   
; chuyển vào thanh ghi r7 số thập phân 248.

                   DJNZ R7,$         ; cho số trong r7 giảm theo bước -1, ở tại chổ và chờ đến khi bằng 0.

                   DJNZ R6,D2      
; cho số trong r6 giảm theo bước -1, và nhẩy về D2 nếu chưa bằng 0.

                   DJNZ R5,D1     
; cho số trong r5 giảm theo bước -1, và nhẩy về D1 nếu chưa bằng 0.

                   RET                   ; quay trở lại thực hiện dóng lệnh sau lệnh call.


 
Bài 2: Viết chương trình dùng Led trên chân 1 (p1.0) theo dõi khóa điện K1 trên chân 10 (p3.0).

* K1 đóng lại Led sáng.
* K1 bỏ ra Led tắt.
ORG 0000H                                      ; Khởi đầu từ thanh ghi 0000h

START:               JB P3.0, LIG         ; Lệnh nhẩy. Nếu chân p3.0 ở bit 1 thì nhẩy đến tên nhãn LIG, Led tắt

                            CLR P1.0             ; Đặt p1.0 về bit 0, chân p1.0 ở mức áp thấp. Led sẽ sáng

                           SJMP START        ; Nhảy về tên nhãn START.

LIG:                    SETB P1.0             ; Đặt p1.0 về bit 1, chân p1.0 ở mức áp cao, Led tắt.

                            SJMP START       
; Nhảy về tên nhãn START.

                           END                       ; Dừng biên dịch ở đây.

Phân tích cách viết các câu lệnh:

Ở đây, Bạn dùng lệnh nhẩy theo điều kiện bit, tức lệnh jb (jump bit) hay jnb (jump no bit).

JB P3.0, LIG

Lệnh này có nghĩa là sẽ nhẩy theo trạng thái bit trên chân p3.0.

Nếu xét chân p3.0 ở mức áp cao (nút nhấn K1 hở) thì nhẩy đến tên nhãn LIG, và
Nếu xét chân p3.0 ở mức áp thấp (nút nhấn K1 kín) thì thực hiện câu lệnh kế tiếp bên dưới.

Bạn nhớ, khi chân p3.0 ở mức áp cao thì Led tắt và khi chân p3.0 ở mức áp thấp thì Led sẽ sáng.



Bài 3: Viết chương trình dùng 4 led trên các chân 1 (p0.0), 2 (p0.1), 3 (p0.2), 4 (p0.3) để cho biết trạng thái của 4 khóa điện trên các chân 5 (p0.4), 6 (p0.5), 7(p0.6), 8 (p0.7).

* Khi khóa điện đóng lại Led tương ứng sáng.
* Khi khóa điện nhã ra, Led tương tứng tắt.
ORG 0000H                                               ; Bắt đầu từ thanh ghi 0000h

START:                        MOV A,P1             ; Lấy trang thái trên cảng port 1 nạp vào thanh ghi tích lũy a.

                                      ANL A,#0F0H       ; dùng logic AND để che 4 bit thấp, giữ nguyên trạng thái 4 bit cao.

                                      RR A                    ; cho nội dung trong thanh ghi a quay qua phải 1 bit. 

                                      RR A                    
; cho nội dung trong thanh ghi a quay qua phải 2 bit. 

                                      RR A                    
; cho nội dung trong thanh ghi a quay qua phải 3 bit. 

                                      RR A                    
; cho nội dung trong thanh ghi a quay qua phải 4 bit. 

                                      XOR A,#0F0H      ; dùng logic Ex-OR để phát hiện sự khác bit trên 4 bit thấp.
                                                                   ; như vậy Led ứng với vị trí có bit 0 sẽ phát sáng.

                                      MOV P1,A            ; Chuyển trạng thái của thanh ghi a ra trên port 1 để làm sáng Led. 

                                      SJMP START      ; nhẩy về tên nhãn start để tiếp tục làm như trên.

                                      END                     ; ngừng biên dịch ở dòng lệnh này.

Phân tích cách viết các câu lệnh:

a- Dùng 4 phím để tắt mở 4 Led trên port 1
Bạn cho chuyển trạng thái của port 1 vào thanh ghi tích lũy a, chú ý trạng thái của 4 bit cao. Nó phản ảnh nút nhấn K1, K2, K3, K4.


 b- Dùng logic And với hằng 11110000b để cho che 4 bit thấp.
Bạn lấy logic AND giữa thanh a và hằng 0f0h (hay là 11110000b), cách làm này là để bảo toàn trạng thái của 4 bit cao, còn 4 bit thấp đều hóa ra bit 0. Người ta quen gọi là cho che 4 bit thấp.



c- Dùng lệnh quay phải 4 lần để dời 4 bit cao xuống 4 bit thấp.
Dùng lệnh rr a cho quay bit qua phải, nếu cho quay 4 lần thì 4 bit thấp sẽ lên nằm ở vùng 4 bit cao và 4 bit cao sẽ xuống nằm ở vùng 4 bit thấp. Chúng ta nói cho chuyển trạng thái của 4 bit cao xuống vùng 4 bit thấp. Cũng có thể dùng lệnh swap.



d- Dùng logic Ex-Or để phát hiện các bit khác nhau.
Lấy logic Dị-OR để phát hiện các bit giống nhau hay khác nhau:

Nếu các bit giống nhau, kết quả sẽ là bit 0.
Nếu các bit khác nhau, kết quả sẽ là bit 1.

Từ ngả ra, Bạn sẽ thấy Led nằm trên bit 0 sẽ phát sáng. Các Led nằm trên bit 1 sẽ tắt.



Bài 4: Viết chương trình cho 8 Led trên port 1 lần lượt nhấp nháy,  nhẩy qua trái rồi nhẩy qua phải.

ORG  0000h
START:      MOV R2,#8            ; Đặt trị 8 (số lần đếm) vào thanh ghi r2
                   MOV A,#0FEH        ; Đặt trị 0feh tức 11111110b và thanh ghi a.
                   SETB C                  ; Đặt bit Cary lên mức 1.
LOOP:       MOV P1,A               ; Chuyển nội dung trong thanh ghi a vào cảng port 1.
                   LCALL DELAY        ; Cho gọi chương trình làm trễ
                   RLC A                     ; Cho nội dung trong thanh ghi a quay qua trái có cho quay qua bit cờ C.
                   DJNZ R2,LOOP      ; Đếm lùi trị trong thanh ghi r2. Nếu chưa bằng 0 thì làm tiếp lệnh ở LOOP. 
                   MOV R2,#8             ; Nạp lại trị 8 vào thanh ghi r2.
LOOP1:      MOV P1,A               
 ; Chuyển nội dung trong thanh ghi a vào cảng port 1. 
                   LCALL DELAY         
; Cho gọi chương trình làm trễ   
                   RRC A                     
; Cho nội dung trong thanh ghi a quay qua phải có cho quay qua bit cờ C.
                   DJNZ R2,LOOP1     ; Đếm lùi trị trong thanh ghi r2. Nếu chưa bằng 0 thì làm tiếp lệnh ở LOOP1. 
                   LJMP START           ; Nhẩy không điều kiện về tên nhãn start để lại tiếp tục.
DELAY:      MOV R5,#20             ; Chương trình dùng làm trễ (xem lại phần thí dụ 1) 
D1:             MOV R6,#20 
D2:             MOV R7,#248 
                   DJNZ R7,$ 
                   DJNZ R6,D2 
                   DJNZ R5,D1 
                   RET 
                   END                         ; Dừng biên dịch.

Phân tích cách viết các câu lệnh:

Bài này dùng lệnh quay bit qua phải và rồi cho quay bit qua trái để dời bit 0 lần lượt đi qua 8 chân của port 1, chúng ta biết bit 0 sẽ làm sáng Led. Như vậy Bạn sẽ thấy các Led trên port 1 sẽ lần lượt sáng và nhẩy qua phải rồi đổi chiều nhẩy qua trái. Để bit 0 có thể đi đủ trên 8 chân của port 1, chúng ta dùng lệnh quay có  quay qua bit cờ C (rrl và rlc), dĩ nhiên trước đó phài nhờ set bit cờ C lên mức 1.

Trình bày lệnh quay rrc và rlc bằng hình minh họa (Bạn xem hình):

a- Bạn dùng lệnh quay có qua cờ C, vậy qua 8 nhịp bit 0 sẽ vào nằm trong cờ C, lúc này 8 bit ở port 1 đều ở mức 1 và như vậy 8 Led trên port 1 đều sẽ tắt. Với lệnh rlc a (rotate left Carry). Bạn sẽ thấy từng Led sáng lên và nhẩy qua bên trái.



b- Bạn dùng lệnh quay có qua cờ C, vậy qua 8 nhịp bit 0 sẽ vào nằm trong cờ C, lúc này 8 bit ở port 1 đều ở mức 1 và như vậy 8 Led trên port 1 đều sẽ tắt. Với lệnh rrc a (rotate right Carry). Bạn sẽ thấy từng Led sáng lên và nhẩy qua bên phải.


c- Lệnh quay (rotate) chỉ có tác dụng với thanh ghi a, do đó Bạn muốn thể hiện kết quả ra 8 Led trên port 1, Bạn phải chuyển nội dung có trong a ra port 1. Bạn dùng lệnh mov p1, a.

Tóm lại, trong bài này Bạn đã làm quen với cách dùng lệnh quay có cho qua cờ C. Với cách viết này, Bạn  thấy chúng ta dùng rất ít câu lệnh mà vẫn khiến cho các Led sáng nhẩy (nhẩy qua nhẩy lại) trên port 1.


Bài 5: Viết chương trình để mạch phát ra tiếng cảnh báo.
Tín hiệu 1KHz và 500Hz phát ra trên chân 1 (p1.0), thời gian phát tín hiệu 1KHz là 100ms và thời gian phát tín hiệu 500Hz là 200ms.

Khóa điện trên chân 8 (p1.7) dùng tắt mở tín hiệu cảnh báo.

FLAG                           BIT 00h                       ; Định nghĩ Flag dùng làm bit cờ, hiện có trị là 0.
ORG 0000H 
START:                        JB P1.7,START         ; Chờ đặt nút K1 đặt xuống mức 0.
                                      JNB FLAG,NEXT      ; Nếu bit cờ Flag là 0 thì nhẩy đến tên nhãn NEXT. 
                                      MOV R2,#200           ; Nạp số thập phân 200 vào thanh ghi r2.
DV:                               CPL P1.0                   ; Lấy bù chân p1.0, lệnh bù bit có chức năng tự đảo. 
                                      LCALL DELY500      ; Cho gọi chương trình làm trễ 500us.
                                      LCALL DELY500      ; gọi lần nữa chương trình dely500.
                                      DJNZ R2,DV             ; Cho đếm lùi và thực hiện lệnh bù cpl p1.0 đến 200 lần.
                                      CPL FLAG                ; Đảo bit trong cờ Flag.
NEXT:                         MOV R2,#200             
 ; Nạp lại số thập phân 200 vào thanh ghi r2. 
DV1:                            CPL P1.0                    
; Lấy bù chân p1.0, có chức năng tự đảo. 
                                      LCALL DELY500      ; Cho gọi chương trình làm trễ 500us.
                                      DJNZ R2,DV1           ; Cho đếm lùi và thực hiện bù cpl p1.0 đến 200 lần.
                                      CPL FLAG                ; Lại cho đảo bit trong cờ Flag.
                                      SJMP START           ; Lập lại lệnh từ tên nhãn START. 
DELY500:                   MOV R7,#250             ; Viết chương trình con làm trễ 500us. Nạp số 250 và thanh ghi r7.
LOOP:                         NOP                            ; Lệnh trống, dùng nó làm tăng thời gian trễ lên gấp đôi.
                                      DJNZ R7,LOOP        ; Đếm lùi r7 để làm trễ.
                                      RET                           ; Cho quay lại thực hiện dòng lệnh sau lệnh call.
END                                                                 ; Dừng biên dịch

Phân tích cách viết các câu lệnh:

Trong bài nầy, Bạn thấy dùng khai báo bit để định nghĩa tên tự đặt của Bạn, như:

flag  BIT 0    ; Chữ flag do Bạn tự đặt là một BIT, hiện có giá trị là bit 0.

Bạn dùng lệnh nhẩy theo bit để kiểm tra khóa điện K1.

start: jb p1.7, start     ; Lệnh này sẽ chờ chân p1.7 xuống bit 0, nếu không nó sẽ luôn dừng lại ở đây.

cpl p1.0     ; Lệnh lấy bù trên chân p1.0, nghĩa là nó đang ở mức 0 thì cho chuyển lên 1 và ngước lại.

Phân tích các câu lệnh trên Bạn thấy:

Loa sẽ hú với tín hiệu 1000us  (do 2 lần gọi dely500) và kéo dài 200 lần rồi chuyển qua hú với tín hiệu 500us  (do chỉ gọi dely500 có 1 lần) cũng thức hiện 200 lần. Với cách tạo ra tín hiệu hú 2 nhịp này, Bạn sẽ nghe  tiếng hú từ Loa phát ra, tín hiệu nghe như tiếng còi hụ cảnh báo..



Bài 6: Viết chương trình dùng cách lấy dữ liệu khai báo trong bảng, để tắt mở 8 Led trên port 1.

* Nháy nhẩy qua trái 2 lần. 
* Nháy nhẩy qua phải 2 lần.
* Toàn phần nhấp nháy 2 lần.
(Thời gian trễ 0.2 giấy).

ORG    0000h 
START:               MOV DPTR,#TABLE     ; Lệnh cho đặt địa chỉ bảng vào thanh ghi con trỏ.                         
LOOP:                CLR A                            ; cho xóa nội dung trong thanh ghi a, lúc này a = 00000000b
                            MOVC A,@A+DPTR     ; Cho lấy nội dung trong bảng theo trị trong a, và cho cất kết quả vào a.
                            CJNE A,#01H,LOOP1   ; Nếu a chưa bằng 01h thì nhẩy qua tên nhãn LOOP1.
                            JMP START                   ; Nếu trong a đã bằng 01h thì nhẩy về tên nhãn START.
LOOP1:              MOV P1,A                       ; Chuyển nội dung trong a ra trên cảng port 1.
                           MOV R3,#20                   ; Nạp số thập phân 20 vào thanh ghi r3.
                            LCALL DELAY               ; Gọi chương trình làm trễ, tên nhãn là delay.
                            INC DPTR                      ; cho tăng địa chỉ bảng lên +1. 
                           JMP LOOP                      ; Nhẩy về tên nhãn LOOP.
DELAY:              MOV R4,#20                    ; Viết chương trình con dùng làm trễ, tên nhãn là delay
D1:                     MOV R5,#248                  ; Nạp trị thập phân 248 vào r5.
                            DJNZ R5,$                      ; Cho giảm theo bước -1, chờ r5 bằng 0.
                            DJNZ R4,D1                   ; Cho r4 giảm theo bước -1, chưa bằng 0, nhẩy về D1.
                           DJNZ R3,DELAY              ; Cho r3 giảm theo bước -1, chưa bằng 0, nhẩy về DELAY. 
                            RET                                ; Quay lại chạy câu lệnh nằm sau lệnh call.

TABLE:              DB 0FEH,0FDH,0FBH,0F7H   ; Khai báo các dữ liệu đặt trong bảng, tên bảng là TABLE.
                            DB 0EFH,0DFH,0BFH,07FH  ; các dữ liệu lần lượt sắp trong bảng.
                           DB 0FEH,0FDH,0FBH,0F7H   
; các dữ liệu lần lượt sắp trong bảng.
                            DB 0EFH,0DFH,0BFH,07FH   ; các dữ liệu lần lượt sắp trong bảng.              
                           DB 07FH,0BFH,0DFH,0EFH    
; các dữ liệu lần lượt sắp trong bảng.
                            DB 0F7H,0FBH,0FDH,0FEH   ; các dữ liệu lần lượt sắp trong bảng.
                            DB 07FH,0BFH,0DFH,0EFH   ; các dữ liệu lần lượt sắp trong bảng.
                            DB 0F7H,0FBH,0FDH,0FEH   ; các dữ liệu lần lượt sắp trong bảng.
                            DB 00H, 0FFH,00H, 0FFH       ; các dữ liệu lần lượt sắp trong bảng.
                            DB 01H                                    ; Dữ liệu dùng soa sánh để nhẩy (Xem câu lệnh trên).
  END                                                                   ; Dừng biên dịch tại đây.


Phân tích cách viết các câu lệnh:

Trong bài này, chúng ta cho lấy dữ liệu liệt kê trong bảng để làm sáng các Led trên port 1. Trình tự làm như sau:

Trước hết Bạn chọn cách làm sáng tắt cho 8 Led trên port 1 với mã 0/1. Chúng ta nhớ bit 0 làm Led sáng và bit 1 sẽ làm Led tắt. Thí dụ: Muốn Led sáng nhẩy qua trái, chúng ta sẽ chọn mã điều khiển như sau:

11111110b   đổi ra dạng mã hệ 16 sẽ là 0FEH.

11111101b   đổi ra dạng mã hệ 16 sẽ là 0FDH.
11111011b   đổi ra dạng mã hệ 16 sẽ là 0FBH.
11110111b   đổi ra dạng mã hệ 16 sẽ là 0F7H.
11101111b   đổi ra dạng mã hệ 16 sẽ là 0EFH.

11011111b   đổi ra dạng mã hệ 16 sẽ là 0DFH.
10111111b   đổi ra dạng mã hệ 16 sẽ là 0BFH.
01111111b   đổi ra dạng mã hệ 16 sẽ là 07FH.

Bạn cứ liệt kê ra trong bảng. Sau này sẽ dùng lệnh: movc a, @a + dptr. Để lấy các mã này cất vào a. Ý nghĩa của câu lệnh này như sau:

Nếu khởi đầu a=0 thì nó sẽ lấy mã dữ liệu đầu trong bảng và rồi cất vào thanh ghia.
Bạn dùng lệnh inc dptr dể cho trị trong a tăng lên +1.
Vậy khi dùng câu lệnh: movc a, @a +dptr, Bạn sẽ cho lấy mã dữ liệu tiếp theo...

Sau mỗi lần lấy dữ liệu từ bảng ra, Bạn dùng câu lệnh nhẩy theo phép so sánh: cjne a, #01h, loop1 để xem đã lấy đến mã dữ liệu cuối cùng chưa, vì Bạn đặt mả 01H ở cuối bảng.

Ghi nhận: Dùng cách viết này, Bạn rất dễ chọn các kiểu nhấp nháy cho các Led trên port 1. Bạn chỉ cần khai báo các mã điều khiển trong bảng là được. bạn có thể khai báo theo dạng mã nhị phân cho dễ nhìn thấy sự sáng tắt của các Led.


 
Bài 7: Viết chương trình để trên đèn số dùng Led 7 đoạn lần lượt xuất hiện các con số 0, 1, 2, 3...Thời gian thay đổi số là 0.2s.

Chú ý: Dùng loại đèn số Led 7 đoạn có Cathode chung, vậy Led sáng với mức 1.

Phân tích cách viết các câu lệnh:

Để hiện các số thập lúc phân trên đèn số 7 đoạn với chân cathode (K) mã các số sẽ như sau:

“0”    hay   3 FH
“1”    hay   06H
“2”    hay   5BH   
“3”    hay   4FH
“4”    hay   66H         
“5”     hay   6DH
“6”    hay   7DH
“7”    hay   07H
“8”    hay   7FH
“9”    hay    6FH           
“A”    hay    77H            
“b”    hay    7CH             
“C”    hay    39H         
“d”    hay    5EH            
“E”    hay   79H              
“F”    hay   71H    

Do vậy để tạo ra bảng hiển thị các số thập phân, chúng ta sẽ viết như sau:
TABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH

ORG 0000h 
START:               MOV R1,#00H             ; Đặt trị khởi đầu 0 cho thanh ghi r1
NEXT:                 MOV A,R1                    ; Cho chuyển nội dung trong r1 vào a.
                            MOV DPTR,#TABLE   ; Đặt địa chỉ của bảng vào thanh ghi con trỏ dptr.
                            MOVC A,@A+DPTR   ; Lấy các mã dữ liệu trong bảng theo trị của a và dữ liệu cất vào a.
                            MOV P2,A                    ; Xuất dữ liệu trong a ra port 2 để cho hiện số.
                            LCALL DELAY             ; Cho gọi chương trình làm trễ, tên nhãn là delay.
                            INC R1                         ; Cho tăng trị trong r1 theo kiểu +1.
                            CJNE R1,#10,NEXT    ; So sánh trị trong r1, xem bằng 10 chưa? chưa, nhẩy về NEXT.
                            LJMP START               ; Lệnh nhảy không điều kiện về câu lệnh có tên nhãn là START.
DELAY:              MOV R5,#20                  ; Viết chương trình làm trễ. Bạn xem lại các phần thí dụ trên.
D2:                      MOV R6,#20 
D1:                      MOV R7,#248 
                            DJNZ R7,$ 
                            DJNZ R6,D1 
                            DJNZ R5,D2 
                            RET 
TABLE:              DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH 
 ; Bảng mã cho hiện các số thập phân.
END                                                            ; Dừng biên dịch.


Nói rõ hơn về loại đèn hiện số dùng Led 7 đoạn (Bạn xem hình):

Khi chân trên port 2 ở mức áp cao, thì Led tương ứng sẽ phát sáng. Vậy chúng ta có thể đặt mã để trên đèn Led 7 đoạn lần lượt hiện ra các con số thập phân.


Hình cho thấy các mã tương ứng với các con số thập phân hiện trên bảng đèn số dùng Led 7 đoạn.


Bài 8: Viết mạch đếm số hiển thi theo hệ cơ 2 với 4 Led trên các chân 1 (p1.0), 2 (p1.1), 3 (p1.2), 4 (p1.3). Mỗi lần nhấn khóa điện SP1 trên chân 17 (p3.7) thì sẽ tăng lên +1.

ORG   0000h 
START:                        MOV R1,#00H             ; Cho khởi đầu với trị 0 trong thanh ghi r1.                  
                                     MOV A,R1                   ; chuyển nội dung trong r1 vào a.                    
                                     CPL A                         ; Lấy bù 8 bit trong thanh ghi a.                       
                                     MOV P1,A                   ; Xuất nội dung trong a ra cảng port 1.                    
REL:                            JNB P3.7,REL             ; Chờ buôn phím nhấn ở chân p3.7.                    
                                     LCALL DELAY10MS   ; Gọi chương trình con làm trễ 10ms.       
                                     JNB P3.7,REL             ; Tránh ảnh hưởng của rung phím.                  
                                     INC R1                        ; Cho tăng trị trong thanh ghi r1                  
                                     MOV A,R1                   
; Cho chuyển nội dung trong r1 vào a.                 
                                     CPL A                         
 ; Lấy bù 8 bit trong thanh ghi a                 
                                     MOV P1,A                    
; Xuất nội dung trong a ra cảng port 1.              
                                     JNB P3.7,$                   ; Chở buông phím SP1                 
                                     SJMP REL                    ; Nhẩy không điều kiện về dòng lênh ở tên nhãn là REL                
DELAY10MS:             MOV R6,#20                   ; Viết chương trình làm trễ 10ms               
L1:                                MOV R7,#248 
                                     DJNZ R7,$ 
                                     DJNZ R6,L1 
                                     RET 
END                                                                   ; Dừng biên dịch tại dòng này.

Phân tích cách viết các câu lệnh:

Nội dung bài viết là cứ nhấn một lần phím SP1, mạch đếm số hệ cơ 2 sẽ nhẩy lên 1 số (Bạn xem hình).
Ở đây có 2 câu hỏi, tôi hỏi Bạn:

(1) Vấn đề rung phím là gì?
(2) Tại sao phải lấy bù a rồi mới cho xuất trên cảng port1?

Vấn đề rung phím là do phần tiếp xúc xấu, khi Bạn nhấn xuống, phím sẽ bị rung, nó ngắt mở nhiều lần và tạo ra kết quả sai. Do vậy Bạn phải viết đoạn chương trình chờ 10ms rồi mới xác lập trạng hái của phím, điều này sẽ tăng độ ổn định khi dùng loại phím cơ khí. Cách viết như sau:

REL:  JNB P3.7,REL             
; Khi bạn nhấn xuống, nếu phím tốt, nó sẽ ở bit 0 và sẽ ở trạng thái chờ buông phím. Nếu có rung phím, nó sẽ nhẩy xuống câu lệnh dưới là cho gọi chương trình trễ 10ms.                   

LCALL DELAY10MS   ; Gọi chương trình con làm trễ 10ms.       
; Sau chương trình trễ nó sẽ quay lại để lại kiểm tra phím với câu lệnh: JNB P3.7,REL 
Nếu nó ở bit 0 thì quay lại REL và lại chờ buông phím. Chỉ khi nó đã ở Bit 1 thì mới cho tăng trị trong r1.
                 
.....  
.              

JNB P3.7,$  
; Câu lệnh này là nhẩy tai chổ khi Bạn chưa bỏ phím nhấn SP1 ra.             

Trả lời câu hỏi thứ 2: Tại sao phải lấy bù a (cpl a) rồi mới cho xuất ra trên cảng port1.

Ở đây chúng ta kích Led bằng mức áp thấp, do đó khi tăng 1, nó sẽ là:

00000000b    --> 00000001b  Vậy phải lấy bù của nó sẽ là 11111110b Điều này sẽ chỉ có Led ở p1.0 sáng mà thôi nó ứng với 1 lần nhấn phím.

Nếu 2 lần nhấn phím kết quả là:

00000010b   --> lấy bù là 11111101b. Vậy Led ở p1.1 sẽ sáng. Bạn cứ lý luận tiếp tục sẽ thấy mạch  này dùng đếm hệ cơ 2kết quả cho hiển thị trên các Led của port 1.

và nếu Bạn thấy thích, Bạn có thể gắn đủ 8 Led trên port 1 và sẽ thấy hiện tượng tràng số. Thanh ghi 8 bit chỉ đếm được 256 nhịp sẽ trang số, quay về 0 và bắt đầu đếm tiếp...




Bài 9Viết chương trình để, mỗi lần nhấn khóa điện SP1 trên chân 17 (p3.7) thì Led D1  trên chân 1 (p1.0), nhấp nháy. Khi nhấn SP1 lần nữa đến Led D2 trên chân 2 nhấp nháy, nhấn SP1 lần nữa đến Led D3 trên chân 3 nhấp nháy và nhấn SP1 lần nữa thì đến Led D4 trên chân 4 nhấp nháy, và qui trình tiếp tục lập lại như trên.

 

ID                                 EQU 30H                   ; Lấy thanh nhớ có địa chỉ 30h định nghĩa là thanh ID.
K1                              BIT P3.7                    ; Chân p3.7 định nghĩa với tên là K1
L1                                 BIT P1.0                    ; Chân p1.0 định nghĩa với tên là L1.
L2                                 BIT P1.1                    
; Chân p1.1 định nghĩa với tên là L2.
L3                                 BIT P1.2                    ; Chân p1.2 định nghĩa với tên là L3.
L4                                 BIT P1.3                    ; Chân p1.3 định nghĩa với tên là L4.
ORG 0000h 
                                     MOV ID,#00H            ; Trị khởi đầu của ID là 0.
START:                        JB K1,REL                ; Chưa nhấn phím thì nhẩy đến tên nhãn REL.
                                     LCALL DELAY10MS ; Gọi chương trình làm trễ 10ms (tránh rung phím).
                                     JB K1,REL                ; Chưa nhấn phím thì nhẩy đến tên nhãn REL.
                                     INC ID                        ; Tăng trị trong ID.
                                     MOV A,ID                   ; Cho chuyển nội dung trong ID và thanh ghi a.
                                     CJNE A,#04,REL       ; Cho so sánh a với #04 để phát hiện số lần nhấn K1
                                     MOV ID,#00H             ; Trả trị trong ID về trị o.  
REL:                           JNB K1,$                      ; Chờ buông phím K1
                                     MOV A,ID                    
 ; Cho chuyển nội dung trong ID và thanh ghi a. 
                                     CJNE A,#00H,IS0        
; Cho so sánh a với #00 để phát hiện số lần nhấn K1
                                     CPL L1                        ; Lấy bù L1 để tắt/mở Led D1
                                     LCALL DELAY             ; Gọi chương trình làm trễ với tên nhãn là delay.
                                     SJMP START              ; Nhẩy không điều kiện về tên nhãn START
IS0:                               CJNE A,#01H,IS1       
; Cho so sánh a với #01 để phát hiện số lần nhấn K1
                                     CPL L2                        ; Lấy bù L2 để tắt/mở Led D2
                                     LCALL DELAY             ; Gọi chương trình làm trễ với tên nhãn là delay.
                                     SJMP START              ; Nhẩy không điều kiện về tên nhãn START
IS1:                               CJNE A,#02H,IS2        ; Cho so sánh a với #02 để phát hiện số lần nhấn K1
                                     CPL L3                         ; Lấy bù L3 để tắt/mở Led D3
                                     LCALL DELAY             ; Gọi chương trình làm trễ với tên nhãn là delay.
                                     SJMP START              ; Nhẩy không điều kiện về tên nhãn START                                        
IS2:                               CJNE A,#03H,IS3        ; Cho so sánh a với #03 để phát hiện số lần nhấn K1
                                     CPL L4                         ; Lấy bù L4 để tắt/mở Led D4
                                     LCALL DELAY             ; Gọi chương trình làm trễ với tên nhãn là delay.
                                     SJMP START               ; Nhẩy không điều kiện về tên nhãn START 
IS3:                               LJMP START                ; Nhẩy không điều kiện về tên nhãn START

DELAY10MS:              MOV R6,#20                  ; Chương trình làm trễ
LOOP1:                        MOV R7,#248 
                                     DJNZ R7,$ 
                                     DJNZ R6,LOOP1 
                                     RET 
DELAY:                        MOV R5,#20 
LOOP2:                        LCALL DELAY10MS 
                                     DJNZ R5,LOOP2 
                                     RET 
 END                                                                      ; Dừng biên dịch tại đây.

Phân tích cách viết các câu lệnh:

Bạn hãy chú ý đến lệnh so sánh có điều kiện, dùng để phát hiện các mã trùng nhau hay khác nhau và từ đó đưa ra hướng sử lý vấn đề. Thí dụ:

CJNE A,#00H,IS0       

; Cho so sánh a với số #00, nếu khác thì nhẩy đến tên nhãn IS0, nếu đúng thì xuống thi hành dòng lệnh bên dưới.

CPL L1                        ; Lấy bù L1 để tắt/mở Led D1.

LCALL DELAY             ; Gọi chương trình làm trễ với tên nhãn là delay.

SJMP START              ; Nhẩy không điều kiện về tên nhãn START.




Bài 10: Viết chương trình để mạch đếm số lần nhấn phím SP1 trên chân 17 (p3.7), kết quả hiển thị trên đèn số dùng Led 7 đoạn. Số đếm bắt đầu từ 00, 01, 02,...99.


Count                  EQU 30H                           ; Đặt tên thanh ghi 8 bit 30h là Count.
SP1                     BIT P3.7                            ; Đặt tên bit p3.7 là SP1.
ORG  0000h                                                  ; Bắt đầu từ thanh ghi Reset 0000h 
START:               MOV Count,#00H               ; Đặt Count về mức khởi đầu là số 0.
NEXT:                MOV A,Count                       ; Cho chuyển nội dung trong Count vào thanh ghi a.
                            MOV B,#10                          ; Đặt số 10 vào thanh ghi b.
                           DIV AB                                  ; Cho số trong a chia cho 10 (số trong b).
                            MOV DPTR,#TABLE          ; Đặt địa chỉ của bảng có tên là Table vào thanh ghi con trỏ.
                           MOVC A,@A+DPTR            ; Lấy số từ bảng theo trị có trong a và kết quả giữ trong a.
                            MOV P1,A                            ; Cho xuất nội dung trong a ra ở port 1. 
                            MOV A,B                              ; Bây giờ cho chuyển nội dung trong thanh ghi b vào a.
                           MOVC A,@A+DPTR            
; Lại lấy số từ bảng theo trị có trong a và kết quả giữ trong a.    
                            MOV P2,A                            
; Cho xuất nội dung trong a ra ở port 2. 
WT:                     JNB SP1,WT                        ; Chờ buông phím SP1. 
WAIT:                 JB SP1,WAIT                        ; Chờ nhấn phím SP1.
                            LCALL DELY10MS               ; Gọi chương trình trễ 10ms, tránh hiện tượng rung phím.
                           JB SP1,WAIT                         ; Kiểm tra buông phím
                            INC Count                             ; Tăng nội dung trong Count lên theo bước +1.
                            MOV A,Count                        ; Cho chuyển nội dung trong Count vào thanh ghi a.
                           CJNE A,#100,NEXT               ; So sánh trị trong a bằng 100 chưa? Nếu chưa thì tiếp tục. 
                            LJMP START                        ; Quay lại tù đầu.
DELY10MS:       MOV R6,#20                           ; Làm trễ 10ms để tránh ảnh hưởng của rung phím.
D1:                      MOV R7,#248 
                            DJNZ R7,$ 
                           DJNZ R6,D1 
                            RET 
TABLE:              DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH  ; Bảng mã số dùng cho Led 7 đoạn.
END                                                                    ; Dừng biên dịch tại dòng này.


Phân tích cách viết các câu lệnh:

Trong đoạn chương trình trên, chúng ta có dùng đến lệnh làm phép toán chia: div ab

Bạn lấy số có trong a chia cho b. Kết qua số chia có trong a và số dư có trong b. Để chia a cho 10, Bạn phải nạp vào thanh ghi b trị 10 với câu lệnh: mov b, #10.

Bạn chú ý đến trình làm trễ 10ms, ở đây dùng để tránh ảnh hưởng  đóc sai do rung phím, vì mỗi khi Bạn nhấn phím, trong khoảng thời gian ngắn phím bị rung và tạo ra sự ghi nhận sai.

Dùng câu lệnh so sánh (cjne: Compare Jump điều kiện Non-Zero) để kiểm tra trị trong thanh ghi a. Đây là một câu lệnh rất thường dùng.

Bạn thích tự lập trình với IC họ 89Cxxxx

Bạn biết các IC vi điều khiển họ AT89C51/AT89C2051 là các IC vi điểu khiển của hãng ATMEL, các cảng (tạo từ một nhóm chân) trên các IC này vận hành theo các câu lệnh do chính Bạn soạn và đã cất vào bộ nhớ của nó. Như vậy với các câu lệnh do Bạn soạn đã tạo ra các chương-trình-điều-khiển, và nó thông qua các các cảng trên các nhóm chân của IC Bạn có thể dùng nó để điều khiển các thiết bị khác. Đơn giản hơn cả là dùng câu lệnh cho mức volt trên các chân lúc lên cao lúc xuống thấp để tắt mở các Led gắn trên các bảng đèn quảng cáo. Đó là phạm vi mà chúng ta sẽ nói đến trong bài viết khởi đầu này. Bạn xem hình ảnh được tạo ra từ các Led nhiều màu, sự tắt mở của các Led sẽ tạo ra hiệu ứng cho các bảng đèn quảng cáo.


Bạn dùng nhiều Led màu ráp thành chữ, và dùng IC vi điều khiển để làm cho các Led này nhấp nháy, hay tạo ra chữ biết chạy, chữ đổi màu, chữ sáng lan tỏa ra, thu hẹp vào... nhờ vậy gây ra được hiệu ứng độc đáo cho các bảng đèn quảng cáo của các cửa hàng. Theo tôi biết, đề tài này vốn rất được nhiều Bạn ưa thích, phải không?

Hình chụp cho thấy chữ Open được tạo ra từ các Led màu. Bảng đèn dùng một IC vi điều khiển khiến với các transistor thúc làm cho các Led có nhiều dạng nhấp nháy, trông rất khoái mắt, Bạn có thích không?

Hình này cho thấy các loại đèn Led được dùng cho các bảng đèn quảng cáo.

Một thí dụ: Với IC AT89C51 có 40 chân, chúng ta có 4 cảng, đó là các cảng P0, P1, P2 và P3. Và với IC AT89C2015 có 20 chân,  có 2 cảng P1, P3 (Bạn xemm hình).


Tìm hiểu IC 89C51 (họ 89Cxxxx)

Chúng ta thử tìm hiểu công dụng của IC sẽ dùng trong bài viết này, AT89C51.

 * Chân 20 cho nối masse, chân 40 cho nối vào đường nguồn 5V (nguồn 5V phải có độ ổn định tốt).
* Chân 18 và chân 19 nối vào thạch anh định tần cho xung nhịp (Xung nhịp được như trái tim của IC vi điều khiển).
* Chân 9 nhận tác động Reset, nó đặt IC về trạng thái khởi đầu.
* Chân 31 (khi đặt ở mức áp cao) dùng để xác nhận là cho sử dụng bộ nhớ trong.
* Chân 29, 30 có thể bỏ trống nếu Bạn không thêm các bộ nhớ ngoài.
* Nhóm 8 chân 32, 34, 35, 36, 37, 38, 39 tạo thành cảng xuất nhập dữ liệu, đặt tên là cảng 0 (Port 0).
* Nhóm 8 chân 1, 2, 3, 4, 5, 6, 7, 8 tạo thành cảng xuất nhập dữ liệu, đặt tên là cảng 1 (Port 1).
* Nhóm 8 chân 21, 22, 23, 24, 25, 26, 27, 28 tạo thành cảng xuất nhập dữ liệu, đặt tên là cảng 2 (Port 2).
* Nhóm 8 chân 10, 11, 12, 13, 14, 15, 16, 17 tạo thành cảng xuất nhập dữ liệu, đặt tên là cảng 3 (Port 3).

Tìm hiểu các khối chức năng của IC AT89C51 (Bạn xem hình):
Trong IC, có:

* Khối dao động (OSC) dùng để tạo ra xung nhịp, xung nhịp cần dùng để vận hành các hoạt động của IC vi điều khiển. Tần số xung nhịp lấy theo thạch anh (gắn trên chân 18-19). Ở đây, chúng ta thường dùng thạch anh 12MHz.
* Khối điều khiển trung ương (CPU), nó chạy các câu lệnh có trong bộ nhớ EEPROM và điều khiển tất cả các hoạt động của IC.
* Trong IC có các đường truyền tải dữ liệu và địa chỉ dạng BIT, nó được điều khiển với các khối BUS CONTROL.
* Trong IC có 2 mạch điện đồng hồ TIMER0 và TIMER1. Ở đây cũng có thể cho nhận xung đếm vào từ chân T0, T1
* Bạn có thể dùng các ngắt ngoài (INTERRUPT) để dừng các chương trình và cho chạy các chương trình ngắt.
* IC có 2 bộ nhớ cơ hữu, đó là bộ nhớ EEPROM (dung lượng 4Kbyte) và bộ nhớ SRAM (dung lượng 128byte).

+ Bộ nhớ EEPROM dùng nhớ các câu lệnh do Bạn đã soạn và nạp vào IC (có thể xóa và nạp lại nhiều lần).
+ Bộ nhớ SRAM dùng làm bộ nhớ trung gian, nó còn có các thanh nhớ chuyên dùng dùng cho phần cứng của IC.

Mạch điện thực hành:

Để sử dụng IC này, Bạn chỉ cần ráp thêm bên ngoài một ít phụ kiện cơ bản như sau:
 Trong mạch:
* Trên chân 18-19, Bạn gắn thạch anh định tần X1 (12MHz), dùng tụ bù nhiệt C2, C3 (33pF).
* Trên chân 9 gắn mạch Reset với điện trở R9 (8.2K) và tụ C1 (10uF). S1 và R8 (220), làm nút nhấn Reset.
* Trên 8 chân của cảng P0 gắn thanh 8 điện trở RB1 (10Kx8) dùng để treo áp.
* Chân 31 cho nối vào đường nguồn 5V (xác nhận cho dùng bộ nhớ trong).
* Bạn có thể viết một chu7o7g trình cho xuất tín hiệu dạng xung trên chân P1.0. 

Mạch điện board nguồn nuôi  dùng cho loại đèn quảng cáo với tầng thúc là các transistor (Bạn xem hình):  


* Dùng 4 diode (1N4007x4) làm cầu nắn dòng, đổi dòng xoay chiều ra dòng điện 1 chiều.
* Dùng tụ hóa lớn C1 (1000uF) để ổn định đường nguồn DC (khoảng 15V, lúc không tải).
* Dùng IC ổn áp 3 chân học 78xx (7805) để có đường nguồn 5V có độ ổn định cao, cấp cho IC AT89C51.
* Dùng tụ hóa C2 (10uF) để dập tắt hiện tượng dao động tự kích có thể phát sinh trong IC 7805.

Ở đây, đường nguồn 15V (có thể dùng cấp điện cho các Led ở bảng đèn quảng cáo, với loại mạch có dùng transistor thúc), nó tạo ra đường nguồn 5V ổn định dùng để cấp điện cho IC AT89C51.

Phân tích các mạch điện thực hành:



 

 Giới thiệu bo nạp:


Sơ đồ mạch điện board nạp chương trình vào bộ nhớ EEPROM trong AT89C51:









Mạch thực hành 1:


Mạch thực hành 2:

Mạch thực hành 3:

 Mạch thực hành 4:

Mạch thực hành 5:
  Mạch thực hành 6:


0 comments:

Post a Comment

domain, domain name, premium domain name for sales

Popular Posts