Đề tài Hướng dẫn về tập lệnh của dòng PIC Midrange

Một dòng như thế này được gọi là một dòng lệnh. Chương trình MPASM được chia làm 4 cột rõ ràng. Cột thứ nhất để viết nhãn, cột thứ hai để viết tên lệnh muốn thực hiện mà chúng ta sẽ trình bày dưới kia, cột thứ 3 là tham số thứ nhất của lệnh, cột thứ tư là tham số thứ hai của lệnh. Giữa tham số thứ nhất và tham số thứ 2 luôn cách nhau một dấu phẩy (,). Các cột được cách nhau bằng ít nhất một ký tự TAB (khoảng trắng rộng). Độ dài của khoảng trắng này có thể được quy định sao cho dễ nhìn với người lập trình.Giữa cột thứ 3 và cột thứ tư không cần có khoảng TAB. Nhưng để dễ dàng cho việc đọc lại chương trình, chúng ta vẫn nên dùng khoảng TAB giữa hai cột này.

pdf47 trang | Chia sẻ: tuandn | Lượt xem: 3338 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Đề tài Hướng dẫn về tập lệnh của dòng PIC Midrange, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Người báo cáo:  Đoàn Hiệp  Tài liệu:  BOOK03.02  Ngày:  10/31/2005  Trang:  1/47  BOOK no 03.02  Gửi đến:  Đoàn Hiệp, DMĐ, ĐTA, MTĐ, www.picvietnam.com  Nội dung:  Tập lệnh PIC Midrange    MICROSOFT WORD Tóm tắt:  Hướng dẫn về tập lệnh của dòng PIC Midrange  1. Các quy ước của ngôn ngữ MPASM  [nhãn]  LỆNH   tham số 1,   tham số 2  Một dòng như thế này được gọi là một dòng lệnh. Chương trình MPASM được chia làm 4  cột rõ ràng. Cột thứ nhất để viết nhãn, cột thứ hai để viết tên lệnh muốn thực hiện mà chúng ta  sẽ trình bày dưới kia, cột thứ 3 là tham số thứ nhất của lệnh, cột thứ tư là tham số thứ hai của  lệnh. Giữa tham số thứ nhất và tham số thứ 2 luôn cách nhau một dấu phẩy (,). Các cột được  cách nhau bằng ít nhất một ký tự TAB (khoảng trắng rộng). Độ dài của khoảng trắng này có  thể được quy định sao cho dễ nhìn với người lập trình.Giữa cột thứ 3 và cột thứ tư không cần  có khoảng TAB. Nhưng để dễ dàng cho việc đọc lại chương trình, chúng ta vẫn nên dùng  khoảng TAB giữa hai cột này.  Nếu để mặc định như khi cài đặt MPLAB, chúng tôi đề nghị sử dụng hình thức như sau:  tab - tabtab - tab tab - tab [nhan] LENH thamso_1, thamso_2     Chúng ta phải viết sao cho chương trình được viết phải phân biệt rõ thành từng cột, vừa  đẹp mắt khi trình bày, và dễ đọc lại chương trình.  1.1. [nhãn]  [nhãn] là một chuỗi ký tự để đánh dấu một điểm nào đó trong chương trình, thay vì phải  ghi nhớ vị trí đó trong bộ nhớ, chúng ta thay vị trí đó bằng một cái [nhãn]. [nhãn] này thường  được gọi lại bằng lệnh GOTO hoặc CALL.   Mỗi câu lệnh, có thể có hoặc không có [nhãn]. Tuy nhiên, nên viết sao cho số [nhãn] là ít  nhất để tránh sự lầm lẫn và rối mắt khi lập trình.   Người báo cáo:  Đoàn Hiệp  Tài liệu:  BOOK03.02  Ngày:  10/31/2005  Trang:  2/47  [nhãn] được viết trong cột thứ nhất của dòng lệnh. [nhãn] không được bắt đầu bằng các ký  tự đặc biệt như: *,&, khoảng trắng, các con số (0,1,2…)… Giữa các ký tự của nhãn cũng không  được có các ký tự đặc biệt *,^, khoảng trắng,…   Độ dài của một [nhãn] không giới hạn, tuy nhiên, chúng ta phải viết sao cho [nhãn] luôn  nằm trong cột thứ nhất của dòng lệnh, độ dài nhãn vừa phải để dễ quan sát, đủ thông tin gợi  nhớ và thuận tiện khi lập trình.  Chúng ta hoàn toàn có thể ký hiệu các [nhãn] là NHAN_1, NHAN_2… nhưng nội dung  thông tin của nhãn không đủ để thể hiện công việc sẽ được thực hiện, như vậy sẽ rất khó nhớ  khi lập trình, nhất là khi chương trình của các bạn dài và có đến hàng chục hàng trăm nhãn  trong chương trình.  Ví dụ: nhãn đúng và nhãn sai  HELLO        nhãn đúng  hello        nhãn đúng  good_bye      nhãn đúng  goodbye_1      nhãn đúng  2_hello        nhãn sai (bắt đầu bằng một con số)  good^bye      nhãn sai (có ký tự đặc biệt trong nhãn)  bon  jour        nhãn sai (có khoảng trắng trong nhãn)  welcome        nhãn sai (bắt đầu nhãn bằng ký tự trắng)  1.2. LỆNH và các tham số:  LỆNH là tên của các lệnh gợi nhớ được liệt kê theo bảng chứ cái ABC ở bên dưới. LỆNH  được viết vào cột thứ hai, mỗi dòng lệnh phải có tên LỆNH, nếu không có thì sẽ không biết  dòng lệnh đó làm việc gì. LỆNH thể hiện công việc phải làm của dòng lệnh.  Tùy theo LỆNH mà có thể có tham số 1 và tham số 2, hoặc chỉ có tham số 1, hoặc không có  tham số nào hết. Trong một dòng lệnh, phải viết đủ tham số của LỆNH đó.  Tập lệnh được cung cấp phía cuối chương. Ý định của chúng tôi là trình bày song song tập  lệnh và phần chú giải này để các bạn dễ đối chiếu, so sánh, tuy nhiên, tờ giấy cuốn sách không  thể gấp làm đôi, chính vì thế chúng tôi đề nghị các bạn photo hoặc in thêm một bảng tập lệnh  dán lên trước bàn làm việc để vừa đọc phần này vừa so sánh, và khi lập trình có thể dễ dàng  tra cứu.  Người báo cáo:  Đoàn Hiệp  Tài liệu:  BOOK03.02  Ngày:  10/31/2005  Trang:  3/47  Ví dụ: tham số của một LỆNH  Lệnh có 2 tham số:  [nhãn]    ADDWF  F,  d  [nhãn]    BTFSS F,  b  Lệnh có 1 tham số:  [nhãn]    CLRF    F  [nhãn]    ADDLW  k  Lệnh không có tham số:  [nhãn]    NOP  [nhãn]    RETURN  [nhãn]    SLEEP  1.3. Quy ước kí hiệu:   ‐ W  = Working register: thanh ghi W.  ‐ F  = File register: thanh ghi F   ‐ d   = destination (đích): nếu d=0, kết quả cất vào W. Nếu d=1, kết quả cất vào F.  ‐ k  = Literal value: là số 8 bit hoặc một địa chỉ trong bộ nhớ chương trình 11 bit.  ‐ b   = bit address : địa chỉ của bit trong 1 byte ( thanh ghi) nào đó.  1.3.1. Thanh ghi W:  Chúng ta thấy rằng, bản chất của các dòng lệnh được thực hiện trên máy tính là các phép  toán được thao tác trên các thanh ghi. Do vậy, bất kỳ một câu lệnh nào cũng sẽ thực hiện một  phép toán nào đó, và kết quả của phép toán đó phải được sử dụng cho các lệnh tiếp theo, nếu  không dòng lệnh đó trở nên một dòng lệnh vô nghĩa.  Ngoại trừ lệnh NOP là lệnh không thực hiện thao tác gì và tốn đi một chu kỳ máy, nhưng  nó có tác dụng để cân bằng thời gian thực hiện các đoạn chương trình tương đương. Chúng ta  sẽ nói về việc cân bằng thời gian thực hiện chương trình bằng lệnh NOP trong các phần về giải  thuật lập trình phía sau.  Vấn đề chúng tôi đề cập ở đây, đó là việc tính toán sẽ được xảy ra như thế nào bên trong vi  điều khiển. Nếu các bạn là người đã học lập trình Pascal, C, hoặc các ngôn ngữ cấp cao khác,  các bạn sẽ thấy rằng khi thực hiện phép toán cộng hai biến b và c, sau đó gán vào biến a, các  bạn có thể làm một cách trực tiếp như sau:  Người báo cáo:  Đoàn Hiệp  Tài liệu:  BOOK03.02  Ngày:  10/31/2005  Trang:  4/47  a: = b + c;  Tuy nhiên, việc này đối với PIC không thể thực hiện được, mà chúng ta phải thực hiện theo  từng bước như sau, chuyển b vào thanh ghi W, sau đó lấy W cộng với c, rồi gán lại vào thanh  ghi W, sau đó mới chuyển kết quả vào a. Công việc được thực hiện bằng một chuỗi lệnh sau:  CONG  MOVF  b,  W    ; W := b      ADDWF  c,  W    ; W := W + c      MOVWF  a      ;   a := W  Như vậy, ở đây, PIC chỉ cho phép trong một thời điểm tương tác với 1 thanh ghi (hay một  biến). Nếu cần có sự tương tác giữa hai hay nhiều thanh ghi, phải thông qua thanh ghi W như  là một thanh ghi đệm. Chính vì vậy, cứ có một lệnh tương tác với thanh ghi, thì dường như sẽ  có một lệnh tương ứng tương tác với thanh ghi W.  Ví dụ: tập lệnh tương tác thanh ghi W  ADDLW: W = W +k  ADDWF: d = W + F  ANDLW: W = W and k  ANDWF: d = W and F  CLRW: xóa thanh ghi W  CLRF: xóa thanh ghi F  IORLW: W = W or k  IORWF: d = W or F  MOVLW: W = k  MOVF: d = F    MOVWF: F = W  SUBLW: W = k – W  SUBWF: d = F – W  XORLW: W = W xor k  XORWF: d = W xor F  1.3.2. Đích d:  Ngoài ra, các bạn có thể thấy rằng d chỉ có thể là 0, hoặc 1. Khi d = 0, có nghĩa là kết quả lại  được lưu vào thanh ghi W. Như vậy, thanh ghi W vừa có thể coi là một thanh ghi tạm, lại vừa  có thể coi là một thanh ghi hoạt động liên tục trong quá trình chạy chương trình của bạn. Bạn  cũng luôn luôn nhớ rằng tại mỗi thời điểm thực hiện một dòng lệnh, chỉ được phép thao tác  với một thanh ghi duy nhất, và (hoặc) thanh ghi W. Không có một lệnh nào cho phép tương  tác với hai thanh ghi khác nhau mà một trong hai thanh ghi đó không phải thanh ghi W. Điều  thứ hai cần ghi nhớ, đó là cứ có một lệnh tương tác với thanh ghi W, thì sẽ có một lệnh tương  Người báo cáo:  Đoàn Hiệp  Tài liệu:  BOOK03.02  Ngày:  10/31/2005  Trang:  5/47  ứng tương tác với thanh ghi (biến) F. Điều ngược lại không đúng. Nhưng nếu có một lệnh nào  tương tác với thanh ghi F, thì kết quả đều có thể được ghi vào thanh ghi W hoặc thanh ghi F.  Hãy chú ý tới cột bên phải của bảng trên d (đích) có thể là thanh ghi W hoặc thanh ghi F.  Lưu ý: Chúng ta hòan toàn có thể thay thế d tương ứng với 0 là W và 1 là F để dễ nhớ. Chương  trình dịch MPASM cho phép ghi như vậy.  Ví dụ:  hai câu lệnh này là tương đương  TANG_1    INCF  BIEN_1,  1  TANG_1    INCF  BIEN_1,  F  Cả hai câu lệnh này đều tăng BIEN_1 lên 1 đơn vị và cất giá trị tăng lên đó vào lại BIEN_1.  Nếu viết bằng Pascal, câu lệnh trên sẽ như sau :  BIEN_1 : = BIEN_1 + 1 ;  1.3.3. Địa chỉ bit b:   Điều chúng ta sẽ quan tâm ở đây là tham số b ở trên. Tham số b chỉ xuất hiện trong 4 lệnh  tương tác bit : BCF, BSF, BTFSS, BTFSC. Tham số này chỉ có giá trị 0, 1, 2, 3, 4, 5, 6, 7. Ngoài ra  không thể mang bất kỳ một giá trị nào khác. Vì sao như vậy ? Vì chúng ta đang làm việc với vi  điều khiển PIC 8 bit, có nghĩa là dữ liệu được tính toán trong vi điều khiển chỉ có 8 bit và được  đánh số như sau :  Thanh ghi F :  Bit 7  Bit 6  Bit 5 Bit 4 Bit 3 Bit 2 Bit 1  Bit 0 Chính vì vậy, chỉ số b là vị trí bit, cho nên chỉ có thể mang giá trị từ 0 đến 7. Các bạn xem ví  dụ sau :  Ví dụ : Quan sát thanh ghi được đặt tên là A có giá trị 10110110  [nhãn]    BCF    A,  5    ; xóa bit 5 của thanh ghi A  Sau khi thực hiện lệnh này, thanh ghi A sẽ có giá trị : 10010110  [nhãn]    BSF    A,   6    ; bật bit 6 của thanh ghi A  Sau khi thực hiện lệnh này, thanh ghi A sẽ có giá trị : 11010110  Người báo cáo:  Đoàn Hiệp  Tài liệu:  BOOK03.02  Ngày:  10/31/2005  Trang:  6/47  1.3.4. Chú thích:  À, và một điều nữa xuất hiện, đó là các bạn thấy sau khi chúng tôi viết dòng lệnh ví dụ trên  đây, phía bên phải, chúng tôi đánh dấu « ; » và viết một số ghi chú cho câu lệnh. Đây là một  chuẩn đúng chứ không phải chúng tôi viết chú thích cho cuốn sách mà viết thêm vào.  MPASM cũng như các ngôn ngữ lập trình khác, cho phép người lập trình viết chú thích  cho mỗi dòng lệnh hoặc một đoạn các dòng lệnh để sau này dễ kiểm tra, sửa chữa, hoặc giúp  cho người khác có thể đọc được dễ dàng hơn các nội dung mình viết.  Tất cả các chú thích đều phải nằm trên một dòng và nằm sau dấu chấm phẩy trên dòng đó.  Nếu chú thích nào dài hơn một dòng thì phải có dấu chấm phẩy ở đầu các dòng bên dưới  Ví dụ :  ;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐  ; Chúng ta thực hiện một ví dụ tính toán  ; theo công thức a : = b + c  ; bằng ngôn ngữ MPASM  ;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐  CONG  MOVF  b,  W    ; chuyển giá trị từ thanh ghi b vào W      ADDWF  c,  W    ; cộng giá trị W và c, ghi lại vào W      MOVWF  a      ; ghi giá trị tổng vào a                ; tại sao chúng ta phải làm thế này?                ; tại vì không thể làm khác!  ;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐  ; Kết thúc tính toán  ;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐  Tất cả các chú thích, các ký tự bất kỳ được viết phía sau dấu “;” trên cùng một dòng đều vô  nghĩa đối với chương trình dịch, và chương trình dịch sẽ không dịch tất cả những gì nằm phía  sau dấu chấm phẩy trong dòng đó.  Vấn đề nẩy sinh với việc viết chú thích đó là phải viết làm sao vừa đủ để có thể dễ dàng  kiểm tra lại sau này, và không viết quá nhiều sẽ phải mất nhiều thời gian viết chú thích hơn là  viết lệnh thực thi. Chẳng hạn ví dụ về việc viết chú thích như trên kia là quá thừa, và chúng ta  không cần phải viết quá nhiều như thế.  Hãy thử viết thế này thì sao?  CONG  MOVF  b,  W      ADDWF  c,  W      MOVWF  a      ;   a := b + c  Người báo cáo:  Đoàn Hiệp  Tài liệu:  BOOK03.02  Ngày:  10/31/2005  Trang:  7/47  Chỉ đơn giản như vậy thôi, bạn sẽ đỡ mất công viết chú thích, và sẽ cung cấp đủ nội dung  cho bạn khi bạn đọc lại chương trình. Viết chú thích theo như trong cuốn sách Tự học Visual  C++ trong 21 ngày cũng chính là một nghệ thuật. Vì vậy, các bạn cũng nên tập viết chú thích  cho hiệu quả đối với MPASM. Trong quá trình thực hiện các bài tập, chúng tôi sẽ cố gắng  truyền cho bạn các ý tưởng khi viết chú thích, và chúng tôi mong các bạn tiếp nhận nó, và sử  dụng nó để chúng ta sẽ có cùng một hệ thống viết chú thích, từ đó về sau chúng ta sẽ dễ đọc  và hiểu nhau hơn.  Cuối cùng, chúng tôi đưa ra một vài con số thống kê mà có thể nó sẽ giúp ích cho các bạn  dễ hình dung trong quá trình học tập lệnh của PIC. Tổng cộng dòng PIC Mid‐Range có 35  lệnh. Mỗi lệnh thường chiếm 1 chu kỳ máy, trừ các lệnh về điều khiển con trỏ chương trình.  Có 16 lệnh tương tác byte (bao gồm thanh ghi F bất kỳ và thanh ghi W), chỉ có 4 lệnh tương  tác bit và 15 lệnh điều khiển.  2. Độ dài mã lệnh và chu kỳ máy  Nhận thấy một thực tế rằng, các bạn sinh viên mới làm quen với vi điều khiển thường lầm  lẫn về hai khái niệm số chu kỳ máy thực hiện lệnh và độ dài mã lệnh. Do đó, trong phần này,  chúng tôi chỉ cố gắng giải thích sơ qua để các bạn có thể phân biệt hai vấn đề trên thật rõ ràng.  2.1. Chu kỳ máy  Xuyên suốt tập tài liệu này, chúng tôi chỉ muốn hướng dẫn các bạn một cách tạo ra dao  động cho PIC bằng thạch anh bởi vì những cách tạo dao động khác đều có sẵn trong datasheet.  (chưa viết xong)  2.2. Độ dài mã lệnh  Độ dài mã lệnh của dòng PIC midrange là 14 bit và được đánh số như sau:  13  12  11  10  9  8  7  6  5  4  3  2  1  0  Hình 1: Mã lệnh của dòng PIC  midrange  Cũng như chúng ta đã nói ở trên, tập lệnh PIC midrange có thể được chia thành 3 loại chủ  yếu, lệnh tương tác byte, lệnh tương tác bit và các lệnh điều khiển. Sự khác nhau của các lệnh  này là gì?  Các bạn chú ý rằng, với lệnh tương tác byte, thì chúng ta luôn có 2 thông số là F và d, trong  đó F là địa chỉ thanh ghi, hay nói ngắn gọn là thanh ghi, và d là bit để chọn xem kết quả được  Người báo cáo:  Đoàn Hiệp  Tài liệu:  BOOK03.02  Ngày:  10/31/2005  Trang:  8/47  lưu ngược lại vào F hay lưu ra W. Trong khi đó, lệnh tương tác bit cần có 3 bit để mã hoá vị trí  của bit trong một thanh ghi nào đó (từ 0 đến 7, nghĩa là từ 000 đến 111).  Với các lệnh điều khiển và tính toán, thì chúng ta có các giá trị 8 bit k (từ 0 đến 255), và hai  lệnh đặc biệt CALL và GOTO thì giá trị k là 11 bit (từ 0 đến 2047).  Chúng ta sẽ xem xét cách tổ chức mã lệnh của dòng PIC midrange ở các mục dưới đây.  2.2.1. Các lệnh tương tác byte  13  12  11  10  9  8  7  6  5  4  3  2  1  0  0  0  OPCODE  d  Địa chỉ của F trong bộ nhớ  Hình 2: Mã lệnh của các lệnh tương tác byte  Các bạn chú ý một điều rằng, địa chỉ của một thanh ghi, chỉ có 7 bit thôi, và nằm từ bit 0  đến bit 6. Mỗi thanh ghi mặc dù có 8 bit, nhưng địa chỉ của nó chỉ có 7 bit.  Phần OPCODE ở đây là gì? Chính là phần mã hoá cả các lệnh mà chúng ta viết như  ADDWF, ANDWF,…. Khi viết như thế này, là chúng ta viết bằng các mã gợi nhớ, trong khi  đó, vi điều khiển hiểu các lệnh này dưới dạng bit. Vì vậy, nó phải được mã hoá để vi điều  khiển hiểu.  Một điểm lưu ý là đối với các lệnh tương tác byte, phần mã hoá của nó dài 6 bit, nằm từ bit  8 đến bit 13. Trong đó, bit12 – bit13 = 00 (như hình 2.2)  Kết quả, chúng ta thấy rằng, phần OPCODE có 6 bit, nhưng hai bit đầu tiên đã là 00, chính  vì vậy, chỉ còn lại 4 bit để phân biệt các lệnh với nhau và chúng ta chỉ có tối đa 16 lệnh tương  tác byte.  2.2.2. Các lệnh tương tác bit  13  12  11  10  9  8  7  6  5  4  3  2  1  0  0  1  OPCODE  b  b  b  Địa chỉ của F trong bộ nhớ  Hình 3: Mã lệnh của các lệnh tương tác bit  Tương tự như trên, bit quy định địa chỉ của thanh ghi F trong các lệnh tương tác bit là 7 bit,  nằm từ bit 0 đến bit 6. Các bit nằm từ bit 7 đến bit 9 dùng để quy định vị trí của bit từ 0 đến 7  trong thanh ghi (nghĩa là từ 000 đến 111).  Người báo cáo:  Đoàn Hiệp  Tài liệu:  BOOK03.02  Ngày:  10/31/2005  Trang:  9/47  Phần OPCODE của các lệnh tương tác bit có mã hoá bắt đầu bằng 01 ứng với bit 12 và 13.  Chính vì vậy, phần còn lại để phân biệt các lệnh khi mã hoá chỉ còn lại 2 bit, nên chỉ có thể mã  hoá được 4 lệnh. Do đó, chúng ta thấy rằng chỉ có 4 lệnh tương tác bit là BCF, BSF, BTFSC và  BTFSS.  2.2.3. Các lệnh điều khiển  13  12  11  10  9  8  7  6  5  4  3  2  1  0  1  1  OPCODE  k (8 bit)  Hình 3: Mã lệnh của các lệnh điều khiển  Chúng ta thấy rằng, mã lệnh của các lệnh điều khiển cũng chỉ có 6 bit, 8 bit còn lại được  dành cho phần giá trị k nhập vào. Khác với các lệnh tương tác byte có 7 bit dùng để chỉ địa chỉ  một thanh ghi và 1 bit d dùng để chọn vị trí đích của phép tính.  Hai bit 12 và 13 của nhóm lệnh này được mặc định là 11. Phần OPCODE 6 bit chỉ còn lại 4  bit để phân biệt các lệnh trong nhóm này. Tuy nhiên, trong nhóm lệnh này, người ta không  dùng hết 16 lệnh mà chỉ dùng 6 lệnh là: ADDLW, ANDLW, IORLW, MOVLW, SUBLW và  XORLW  2.2.4. Lệnh GOTO và CALL  13  12  11  10  9  8  7  6  5  4  3  2  1  0  1  0  0  CALL ‐ k (11 bit)  1  0  1  GOTO ‐ k(11 bit)  Hình 4: Mã lệnh của lệnh CALL và GOTO  Hai lệnh này là hai lệnh đặc biệt, phần OPCODE chỉ có 3 bit, còn lại 11 bit là địa chỉ của vị  trí cần nhảy tới (k).  2.2.5. Các lệnh điều khiển đặc biệt  Các lệnh điều khiển đặc biệt, là các lệnh không tương tác với các thanh ghi có địa chỉ trong  bộ nhớ dữ liệu, bao gồm các lệnh: CLRWDT, NOP, RETURN, RETFIE, SLEEP  Người báo cáo:  Đoàn Hiệp  Tài liệu:  BOOK03.02  Ngày:  10/31/2005  Trang:  10/47  Các lệnh này vì không chứa các thanh ghi trong mã lệnh, nên phần đầu OPCODE của nó sẽ  là 000000 (6 bit từ bit 13 đến bit 8 đều là 0). Như hình sau:  13  12  11  10  9  8  7  6  5  4  3  2  1  0  0  0  0  0  0  0  0  Phần mã hoá để phân biệt các lệnh  Hình 5: Mã lệnh của các lệnh điều khiển đặc biệt  Vậy một điều làm chúng ta thắc mắc là, làm sao các lệnh này phân biệt được với lệnh  MOVWF, vì lệnh MOVWF cũng có phần OPCODE là 00 0000 như sau:  13  12  11  10  9  8  7  6  5  4  3  2  1  0  0  0  0  0  0  0  1  Địa chỉ của F trong bộ nhớ  Hình 6: Mã lệnh của lệnh MOVWF  Các bạn lưu ý rằng lệnh MOVWF thì đích tới để ghi kết quả sẽ là F, do đó ở vị trí bit d (bit  7) sẽ là 1. Trong khi đó, các lệnh điều khiển đặc biệt, mã lệnh của nó tại vị trí bit 7 sẽ là 0.  Như vậy, các lệnh được mã hoá một cách hoàn toàn. Trong phần tiếp theo của chương này,  chúng tôi sẽ đề cập đến từng lệnh và cách sử dụng các lệnh này. Tuy nhiên, chúng tôi không  nhắc lại cụ thể mã lệnh của từng lệnh, bởi vì thiết nghĩ rằng nó không cần thiết nữa vì mục  đích của chúng tôi là viết cuốn sách hướng dẫn cơ bản, chứ không đi sâu vào vấn đề nghiên  cứu mã code để phát triển sâu về PIC.  2.3. Số chu kỳ của một lệnh:  (chưa viết xong)  Người báo cáo:  Đoàn Hiệp  Tài liệu:  BOOK03.02  Ngày:  10/31/2005  Trang:  11/47  3. Giải thích tập lệnh  Phần này chúng tôi cố gắng giải thích từng lệnh một cách thật kỹ lưỡng, để các bạn có thể  hiểu rõ và sử dụng chính xác từng lệnh.  Ngoài ra, vì lý do hướng dẫn và giúp các bạn làm quen với tập lệnh của PIC một cách  nhanh chóng, chúng tôi quyết định đảo vị trí của một số lệnh trong tập lệnh, nhằm giúp cho  các bạn dễ dàng ghi nhớ hơn.  Trong phần tập lệnh này, phần ghi chú cho mỗi lệnh là rất quan trọng. Nó là phần chúng  tôi muốn trình bày về   (chưa viết xong)  Người báo cáo:  Đoàn Hiệp  Tài liệu:  BOOK03.02  Ngày:  10/31/2005  Trang:  12/47   [nhãn]    ADDLW  k      ; Nội dung của thanh ghi W   ; được cộng với số 8 bit k,  ; kết quả được cất lại vào W.  Thực hiện lệnh: W = W + k  Các bit trạng thái bị ảnh hưởng: C, DC, Z  k chỉ có thể là số có giá trị tương đương một số thập phân từ 0 đến 255  Ví dụ:   Ban đầu:    W   = 200   C  = ?  DC  = ?  Z  = ?  CONG_1   ADDLW  d’50’      ; W = 200 + 50  Kết quả:    W   = 250  C  =  DC  =  Z  =  Nếu bây giờ chúng ta tiếp tục thực hiện phép cộng như sau  CONG_2   ADDLW  d’20’      ; W = 250 + 20  Kết quả:    W   = 14  C    =   DC   =  Z  =   Ghi chú:   ‐ Để viết một số hệ thập phân (hệ cơ số 10) các bạn viết d’XXX’, để viết một số theo hệ nhị  phân (cơ số 2) các bạn viết b’XXXXXXXX’, và viết một số hệ thập lục phân (cơ số 16) các  bạn viết h’XX’ hoặc 0xXX.  ‐ Ví dụ: d’50’, d’103’, b’01101101’, b’11011011’, h’C3’, 0xA8, 0x44 …  ‐ Dòng PIC mà chúng ta tìm hiểu là các MCU 8 bit. Do vậy, không thể nào một thanh ghi  dữ liệu có thể chứa một số mà giá trị của nó lớn hơn giá trị có thể thể hiện bằng 8 bit.  Nhắc  lại  rằng, một  số  8  bit  chỉ  có  thể  thể  hiện một  số  nhị phân  từ  b’00000000’  đến  b’11111111’, hay một số thập phân từ d’0’ đến d’255’ và số thập lục phân từ 0x00 đến  0xFF. Một khi phép toán cộng làm tràn 8 bit, nó chỉ có thể giữ lại kết quả là 8 bit, còn giá  trị tràn sẽ bị bỏ qua. Tuy nhiên, các bit trạng thái C, Z, DC sẽ bá