Tính Toán Vòng Lặp Tạo Trễ Cho Vi điều Khiển Họ 8051 Bằng Code ...

Labels

  • FUN
  • Lập Trình
  • TRIẾT HỌC
  • Điện Tử
  • Công Nghệ
  • TỰ SỰ
  • CÔNG NGHỆ - KỸ THUẬT
  • TRUYỆN NGẮN
  • Đọc Báo
  • Bài Dịch
  • Phần Mềm
  • GAME
  • LUẬT HỌC
  • Máy Tính
  • Viễn Thông

1/03/2018

Tính toán vòng lặp tạo trễ cho vi điều khiển họ 8051 bằng code Assembly

Vòng lặp tạo trễ là một đoạn mã thường xuyên xuất hiện trong các chương trình hợp ngữ Assembly dùng trong các hệ thống nhúng vận hành theo thời gian thực. Ví dụ: khi cần xuất điện áp dương ở chân P1.0 trong khoảng thời gian là 1s sau đó ngắt thì cần thời gian duy trì 1s ấy vi điều khiển giữ mức điện áp dương trước khi ngắt. Có hai cách để tạo trễ: 1. Lập trình các đoạn mã chạy đi chạy lại để "câu" thời gian. 2. Sử dụng bộ định thời. Để dễ hiểu ta xét đề bài: Tạo xung dao động tần số 1Hz xuất ra tại chân P1.0 bằng vi điều khiển 8051, lập trình bằng hợp ngữ Assembly với tần số thạch anh là 11,0592 MHz. - Với dao động có tần số là 1Hz tức là ta sẽ lập trình xuất xung 1 lần trong 1 giây, theo yêu cầu đề bài tạm định xung sẽ được duy trì theo 1 lệnh tức 1 chu kỳ máy, thời gian nghỉ giữa hai xung sẽ là 1s. Vậy ta cần thời gian trễ 1s. - 1 chu kỳ máy bằng 1/12 chu kỳ dao động của thạch anh. Với tần số thạch anh theo như đề bài là 11,0592MHz ta có tần số máy là 11,0592/12 = 0,9216MHz, chu kỳ máy là 1/0.9216 ≈ 1,085μs. Vậy để trễ 1s ta cần khoảng 1 triệu chu kỳ máy. - Mỗi lệnh cần số chu kỳ máy khác nhau để thực thi, để biết số chu kỳ máy tương ứng với mỗi lệnh ta có thể tra ở đây. - Sở dĩ tần số thạch anh hay được chọn là 11,0592MHz do để 8051 tương thích với cổng nối tiếp của IBM PC. 1. Sử dụng hàm tạo trễ thông qua vòng lặp Các bước thực hiện chương trình: khai báo địa chỉ bắt đầu chương trình → nạp giá trị 01H vào thanh ghi A → gán giá trị thanh ghi A vào ngăn nhớ P1 (xuất giá trị ra cổng P1, bật chân P1.0) → nạp giái trị 00H vào thanh ghi A → gán giá trị thanh ghi A vào ngăn nhớ P1 (xuất giá trị ra cổng P1, tắt chân P1.0) → gọi hàm DELAY → nhẩy tới đầu chương trình, lặp lại chu kỳ. Hàm DELAY: nạp giá trị 7H vào thanh ghi R0 → nạp giá trị FFH vào thanh ghi R1 (1) → nạp giá trị FFH vào thanh ghi R2 (2) → dùng lệnh DJNZ giảm giá trị R2 tới 0 thoát khỏi vòng lặp → dùng lệnh DJNZ giảm giá trị thanh ghi R1, nhẩy tới (2) → dùng lệnh DJNZ giảm giá trị R0, nhẩy tới (1) → thoát khỏi vòng lặp. Code: ORG 00H ; đặt địa chỉ bộ nhớ chương trình LOOP: MOV A, #01H ; đặt giá trị 01H vào thanh ghi A MOV P1, A ; đưa A vào thanh ghi P1, cổng P1 sẽ được bật MOV A, #00H ; đặt giá trị 00H vào thanh ghi A MOV P1, A ; đưa A vào thanh ghi P1, cổng P1 sẽ được tắt ACALL DELAY ; gọi hàm DELAY SJMP LOOP ; nhẩy tới nhãn LOOP lặp lại chương trình RET ; thoát khỏi vòng lặp DELAY: ; hàm DELAY MOV R0, #06H ; nạp giá trị 07H vào thanh ghi R0 AGAIN1: MOV R1, #FFH ; nạp 256 (FFh) vào thanh ghi R1 AGAIN: MOV R2, #FFH ; nạp 256 vào thanh ghi R2 HERE: DJNZ R2, HERE ; giảm dần R2, mỗi lần giảm nhẩy tới HERE DJNZ R1, AGAIN ; giảm dần R1, mỗi lần giảm nhẩy tới AGAIN DJNZ R0, AGAIN1 ; giảm dần R2, mỗi lần nhẩy tới AGAIN1 RET ; thoát khỏi vòng lặp END ; kếp thúc chương trình Giải thích hàm DELAY: - Như trên đã nói ta có thể tra bảng để tìm số chu kỳ máy các lệnh cần để thực thì, trong hàm DELAY thì lệnh MOV tốn 1 chu kỳ máy, hàm DJNZ tốn 2 chu kỳ máy. - Xét câu lệnh: HERE: DJNZ R2, HERE Lệnh này có nghĩa là giảm giá trị thanh ghi R2 sau đó nhẩy tới nhãn HERE, vì trước đó ta đã nhập R2 giá trị FFH ở câu lệnh: "MOV R2, #FFH". Nên câu lệnh trên lặp lại 256 lần, tổng cộng 256 x 2 = 512 chu kỳ máy. - Xét câu lệnh: DJNZ R1, AGAIN Tương tự như câu lệnh trên ta có 512 lần chu kỳ máy. Nhãn AGAIN được đặt ở câu lệnh: "AGAIN: MOV R2, #FFH" tức là mỗi lần lặp lại nạp cho R2 giá trị FFh vì R1 được nạp giá trị FFh ở trên ta có 256 x 1 = 256 chu kỳ máy. Tiếp đó chương trình thực hiện câu lệnh ngay sau là: "DJNZ R2, HERE", lệnh này được lặp 256 mỗi lần tốn 512 chu kỳ máy như trên, tổng cộng là 512 x 216 = 131.072 chu kỳ máy - Tương tự như vậy với câu lệnh: DJNZ R2, AGAIN1 Ta có thêm 6 (giá trị nạp cho R0) là 12 chu kỳ máy + cụm lệnh trên được lặp lại 7 lần nữa. - Tổng cộng: 3 (từ khai báo ban đầu) + 512 (lặp đầu tiên chỗ R0) + 256(2+1+512)(lặp chỗ R1) + 6(2+1+1+512+256(2+1+512))(lặp chỗ R2) = 926.491 chu kỳ - Vậy: 926.491 x 1.085 = 1.005.242,735 μs ≈ 1s *Ai muốn tìm kết quả chính xác hơn thì chịu khó thay đổi giá trị nạp vào các thanh ghi nhé, tính cái này hại óc muốn chết hà! 2. Tạo trễ bằng bộ định thời Phần lý thuyết về bộ định thời tôi không nhắc lại nữa cần lưu ý đến giá trị các thanh ghi điều khiển, thanh ghi giá trị của bộ định thời. Với mỗi lần bộ đếm lên thêm một đơn vị tốn 1 chu kỳ máy, tương ứng với 1,085 μs. Khi cho chạy từ 0000 ➡ FFFF ta có 65.535 chu kỳ máy. Code: ORG 00H ; đặt địa chỉ bộ nhớ chương trình LOOP: MOV A, #01H ; đặt giá trị 01H vào thanh ghi A MOV P1, A ; đưa A vào thanh ghi P1, cổng P1 sẽ được bật MOV A, #00H ; đặt giá trị 00H vào thanh ghi A MOV P1, A ; đưa A vào thanh ghi P1, cổng P1 sẽ được tắt ACALL DELAY ; gọi hàm DELAY SJMP LOOP ; nhẩy tới nhãn LOOP lặp lại chương trình RET ; thoát khỏi vòng lặp DELAY: MOV TMOD, #10H ; đặt chế độ 1, timer 1 AGAIN: MOV R1, #EH ; đặt số lần bộ định thời chạy (15 lần) MOV TL1, #00H ; đặt giá trị 0 cho các bit thấp timer1 MOV TH1, #00H ; đặt giá trị 0 cho các bit cao timer1 SETB TR1 ; khởi chạy bộ định thời BACK: JNB TF1, BACK ; lặp tại chỗ chờ cờ tràn bật khi tới FFFF CLR TR1 ; tắt bộ định thời CLR TF1 ; xóa cờ tràn DJNZ R3, AGAIN ; lặp lại RET END Toàn AGAIN được lặp lại 15 lần nên ta có số chu kỳ được tính là: 1 + 14(1+1+1+1+2+65.535+1+1+2) = 917.631 chu kỳ máy Thời gian: 617.631 x 1,085 ≈ 1s Nếu cần tính xác hơn hay thay đổi các tham số các bạn chọn lại giá trị nạp vào R1, TL1, TH1 cho phù hợp. Việc sử dụng bộ đình thời có thể kết hợp với ngắt code sẽ uyển chuyển hơn, nhịp nhàng hơn. (cái này chưa nắm chắc không dám viết bài, khi nào sẽ viết sau) ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ Nhìn chung tính toán bằng bộ định thời đơn gian hơn, hơn nữa ở các chương trình phức tạp trong lúc bộ định thời đếm vi xử lý có thể tiếp tục thực hiện các lệnh khác. Tuy vậy việc sử dụng bộ định thời cần nắm chắc kiến thức hơn, thực tế chạy lại không hay chính xác lắm. Vì vậy, với các yêu cầu đơn giản người ta thường dùng phương án 1 hơn.

3 comments:

  1. Unknown19 May, 2020 08:07

    tks ad nha. dù thầy cô có dạy nhưng mình vẫn muốn tìm kiếm trên mạng. Blog đỉnh đó!

    ReplyDeleteReplies
      Reply
  2. Unknown26 August, 2020 08:48

    delay trên sai giá trị R0 với R2 delay dưới thiếu giá trị R3

    ReplyDeleteReplies
      Reply
  3. dong08 September, 2020 20:51

    Có nhầm đau ko bạn? Biên dịch nạp thử delay 1s đầu tiên nó chớp quá nhanh cảm giác 1/4 giây

    ReplyDeleteReplies
      Reply
Add commentLoad more... Newer Post Older Post Home Subscribe to: Post Comments (Atom)

Blog Archive

  • ▼  2018 (17)
    • ▼  January 2018 (11)
      • MẠCH PHÂN ÁP
      • CHẠY LẠI CHƯƠNG TRÌNH SỬ DỤNG LỆNH GOTO, NHÃN TRONG C
      • CHẠY LẠI CHƯƠNG TRÌNH BẰNG VÒNG LẶP DO - WHILE BẰNG C
      • NHỮNG QUY ĐỊNH MỚI VỀ BHXH TỪ 01/01/2018 NGƯỜI LAO...
      • 25 CON CHIP LÀM RUNG CHUYỂN THẾ GIỚI
      • BÀI TOÁN RÚT GỌN PHÂN SỐ BẰNG CODE C++
      • BÀI TOÁN TÍNH BỘI CHUNG NHỎ NHẤT BẰNG C++
      • Album ảnh đẹp Sơn La Vol03 || Son La beautiful pho...
      • Album ảnh đẹp Sơn La Vol 02 || Son La beautiful ph...
      • Tính toán vòng lặp tạo trễ cho vi điều khiển họ 80...
      • Album ảnh đẹp Sơn La Vol.01 || Son La beautiful ph...

Popular Posts

  • BÀI TOÁN RÚT GỌN PHÂN SỐ BẰNG CODE C++ Đề bài: nhập vào một phân số rút gọn cho tới khi là phân số tối giảm. Bài làm: #include <iostream.h> #include <conio.h> v...
  • HƯỚNG DẪN VẼ MẠCH BẰNG KICAD  Thực sự tôi chưa am hiểu sâu sắc về phần mềm này lắm và đây cũng là lần đầu làm một cái “vượt sức mình” như này nên chắc chắn tài liệu này ...
  • Tính toán vòng lặp tạo trễ cho vi điều khiển họ 8051 bằng code Assembly     Vòng lặp tạo trễ là một đoạn mã thường xuyên xuất hiện trong các chương trình hợp ngữ Assembly dùng trong các hệ thống nhúng vận hành t...
  • MẠCH PHÂN ÁP    Làm thế nào để hạ một điện áp một chiều từ mức 12v sang 9v?     Đơn giản! Ta mắc vào một điện trở để gây sụp áp: ...
  • Bài toán cổ gà chó C++ Đề bài: Vừa gà vừa chó Bó lại cho tròn Ba mươi sáu con (36 con) Một trăm chân chẵn (100 chân) Hỏi có bao nhiêu gà, chó? Bài giải:...
  • Những câu truyện ma ở miền núi (phần 2) Link phần 1 2.Về ma cà rồng    Một chút biện luận : nhìn chung một sinh vật hút máu người sống mang hình dạng con người với đa phần mọi n...
  • CHẠY LẠI CHƯƠNG TRÌNH BẰNG VÒNG LẶP DO - WHILE BẰNG C    >> CHẠY LẠI CHƯƠNG TRÌNH SỬ DỤNG LỆNH GOTO, NHÃN TRONG C    Khi chạy một chương trình c đơn giản, đôi khi ta muốn chạy lại chương...
  • Bài toán viết hình vuông bằng ký tự "*" C++ Đề bài: vẽ hình vuông có cạnh là a //chương trình viết ra hình vuông đặc có cạnh là a #include <stdio.h> #include <iostream...
  • Bài toán tìm trọng tâm tam giác C++ Đề bài: Tìm tọa độ trọng tâm tam giác cho trước. Bài làm: //chương trình tìm trọng tâm tam giác #include <stdio.h> #include <...
  • MỘT SỐ THUẬT NGỮ TIẾNG ANH VIẾT TẮT TRONG NGÀNH VIỄN THÔNG Thuật ngữ Tên tiếng Anh Nghĩa tiếng Việt A/D Analog-Digital Converter Bộ chuyển đổi tương tự số ADSL Asymmetric Digital Subscribe...

Từ khóa » Câu Lệnh Djnz