Điện - Điện Tử - Chương II: Tập lệnh PIC dòng Mid – Range

I. Các quy ước của ngôn ngữ MPASM Một dòng lệnh chuẩn trong MPASM được viết như sau: [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.

pdf10 trang | Chia sẻ: hoang10 | Lượt xem: 589 | Lượt tải: 0download
Bạn đang xem nội dung tài liệu Điện - Điện Tử - Chương II: Tập lệnh PIC dòng Mid – Range, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
Chương n: Tập lệnh PIC dòng Mid – Range I. Các quy ước của ngôn ngữ MPASM Một dòng lệnh chuẩn trong MPASM được viết như sau: [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 [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. [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. [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) 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ố hai, 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. 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 3. Quy ước kí hiệu: • W : thanh ghi W ( working register). • F : thanh ghi F ( File register) • 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 nhãn. • b= Bit address : địa chỉ của bit trong 1 byte ( thanh ghi) nào đó. a. 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: 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à thanh ghi W, sau đó lấy b cộng với c, rồi gán 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 b. Đí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 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 ; c. Đị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 d. 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 ADDWF c, W MOVWF a ; a := b+ c ; 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 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ó 18 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à 13 lệnh điều khiển. II. 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. [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ú: 1. Để 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 2. 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áo cho chúng ta biết rằng thanh ghi bị tràn. [nhãn] ADDWF F, d ; Nội dung của thanh ghi W ; được cộng với nội dung của thanh ghi F, ; kết quả được cất lại vào d. Thực hiện lệnh: d = W + F Các bit trạng thái bị ảnh hưởng: C, DC, Z Nếu d = W (0) thì kết quả sẽ được cất vào W, nếu d = F(1) thì kết quả sẽ được cất trở lại vào F. Nếu không viết d phía sau, xem như mặc định d = F. Ví dụ: Ban đầu: W = 200 BIEN = 50 (thanh ghi được đặt tên là BIEN) C = ? DC = ? Z = ? CONG_1 ADDWF BIEN, W ; W = 200 + 50 Kết quả: W = 250 BIEN = 50 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 ADDWF BIEN, F ; BIEN = 250 + 50 Kết quả: W = 200 BIEN = 44 C = DC = Z = Ghi chú: Làm thế nào để đặt tên cho một thanh ghi? Chúng ta có nhiều cách đặt tên cho một thanh ghi. Cách thứ nhất dùng ORG 0x20 BIEN RES 1 ; BIEN có độ dài là 1 byte bắt đầu từ địa chỉ BIEN_2 RES 2 ; 0x20. Hay nói cách khác, BIEN chính là ; thanh ghi có địa chỉ 0x20. Cách này dùng để ; đặt tên cho hàng loạt biến liên tiếp nhau. ; BIEN_2 sẽ có độ dài 2 byte bắt đầu từ 0x21 Cách thứ hai dùng cblock. Cách thứ ba dùng #DEFINE để đặt tên cho hằng số hoặc đặt tên cho biến có địa chỉ được định sẵn. Hai cách sau chúng ta sẽ nhắc tới trong phần DIRECTIVE Tổng kết chương Như vậy, bài học hôm nay chúng ta đã học về các lệnh và cách viết lệnh bằng ngôn ngữ MPASM. Chúng ta đã học một dòng lệnh chuẩn được viết như thế nào, và cách viết chú thích. Trong một dòng lệnh cần nhớ những quy tắc đặt nhãn, và cú pháp lệnh. Trong một đoạn lệnh, cần cân nhắc về việc ghi chú thích. Hiểu được bài học này, các bạn hoàn toàn có thể viết một số phép toán rời rạc mà không cần hình thành một chương trình chạy. Chúng ta sẽ làm một số bài tập để làm quen với việc viết các lệnh và thực hiện các công việc trên ngôn ngữ MPASM. Đây là những bài tập không phải là khó, nhưng cũng không phải là đơn giản cho những người mới học vi điều khiển. Nhưng các bạn hãy cố gắng thực hiện các bài tập này để hiểu rõ hơn về tập lệnh của PIC trước khi bắt đầu những bài học sau. Lời giải cho các bài tập này sẽ được thảo luận trên diễn đàn điện tử (www.diendandientu.com). Bài tập 1: phép cộng cho các biến 2 byte Cho biến A gồm 2 byte và thanh ghi B gồm 2 byte . Các bạn hãy thực hiện một đoạn chương trình tính tổng của A + B và lưu vào thanh ghi C gồm 3 byte Trong đó A1, A2, B1, B2 là các byte mang các giá trị bất kỳ. Bài tập 2: thực hiện vòng lặp và kiểm tra điều kiện lặp Thực hiện vòng lặp được trình bày bằng ngôn ngữ Pascal sau bằng ngôn ngữ MPASM: A: = 0; B: = 0; For I:=1 to 100 do Begin A: = A + 1; B: = B + 2; End; Trong đó A, B, I là các thanh ghi (hay các biến) 8 bit thông thường. Bài tập 3: kiểm tra điều kiện, phép trừ và lệnh GOTO Cho A và B là hai thanh ghi 8 bit bất kỳ. Kiểm tra điều kiện A > B thì nhảy về NHAN_1, nếu A = B thì nhảy về NHAN_2, nếu A < B thì nhảy về NHAN_3. If (A>B) then goto NHAN_1 Else If (A=B) then goto NHAN_2 Else goto NHAN_3; Bài tập 4: tương tác bit và dịch bit Cho thanh ghi A có giá trị bất kỳ, và thanh ghi B có giá trị ban đầu bất kỳ. Bắt đầu đoạn lệnh, cho B = 0. Dịch nội dung thanh ghi A sang trái từng bit một. Nếu bit bị dịch đi trên thanh ghi A là 1 thì tăng thanh ghi B lên một đơn vị. Nếu bit bị dịch đi là 0 thì trừ thanh ghi B đi một đơn vị. Thực hiện việc này cho hết 8 bit của thanh ghi A. Thực hiện tiếp việc bật tắt bit 7 của thanh ghi B. Nếu số bit mang giá trị 0 của thanh ghi A nhiều hơn số bit mang giá trị 1 thì bit 7 của thanh ghi B sẽ mang giá trị 0, và ngược lại. Dùng 4 bit đầu tiên của thanh ghi B (bit 3 – bit 2 – bit 1 – bit 0) để thể hiện hiệu số giữa số bit mang giá trị 0 và số bit mang giá trị 1 trong thanh ghi A. A2 A1 B2 B1 C3 C2 C1
Tài liệu liên quan