PDA

View Full Version : Help! Sử dụng Macro


Jerry
17-11-2006, 09:07 AM
Em viết 1 macro như sau:

move MACRO variable,value
movlw value
movwf variable
ENDM

Trong chương trình chính em gọi macro như sau:

move Delay1,0x20

biến Delay1 em đã khai báo trong vùng RAM của PIC6F877.
Vậy mà khi dịch chương trình lại báo lỗi :

Illegal opcode (Delay1)

bây giờ em phải giải quyết thế nào hả các bác?
Khi em không dùng Macro nữa mà dùng luôn thế này ở chương trình chính:

movlw 0x20
movwf Delay1

thì chẳng báo lỗi gì cả. Nhưng em muốn học cách sử dụng Macro. Do vậy rất mong được các đại sư huynh chỉ giáo.

bien_van_khat
17-11-2006, 09:52 AM
Code tớ viết như vậy nè, quickbuild = MPL 7.5 bình thường.
Có lẽ bạn nên post code của bạn lên thì hay hơn.

#include <p16f877a.inc>


org 0x05
move macro variable,value
movlw value
movwf variable
endm

cblock 0x0c
delay1
endc

main
move delay1, 0x20
end

Jerry
17-11-2006, 11:00 AM
Chương trình chính em viết dài lắm, post hết lên đây em sợ loãng mất cái em cần hỏi nên em không post, chứ không phải em giấu giếm gì đâu. Hic, em viết đúng như bác hướng dẫn mà vẫn ko được. Em đang dùng MPLAB bản 7.41.

namqn
17-11-2006, 06:14 PM
Chương trình chính em viết dài lắm, post hết lên đây em sợ loãng mất cái em cần hỏi nên em không post, chứ không phải em giấu giếm gì đâu. Hic, em viết đúng như bác hướng dẫn mà vẫn ko được. Em đang dùng MPLAB bản 7.41.
Bạn viết chương trình mà không có indent (khoảng thụt đầu dòng), do đó các lệnh được xem là nhãn (vì nằm ở cột 1), và đối số được xem là lệnh. Như vậy bạn sẽ gặp thông báo lỗi là mã lệnh (opcode) không hợp lệ. Bạn thêm một khoảng thụt cho các lệnh trong macro của bạn là ok. Xem thử ví dụ của bien_van_khat thì thấy ngay là cậu ta có khoảng thụt cho các lệnh.

Thân,

Jerry
18-11-2006, 08:53 AM
Bác ơi em viết có thò có thụt đàng hoàng đấy chứ, nhưng vì khi post lên đây em không biết cách post code nên nó cứ dính liền vào nhau như vậy. Hồi trước có 1 bác dạy em cách post code lên diễn đàn, dùng ký tự # gì đó nhưng em tìm không thấy.

namqn: Khi bạn soạn thảo post, ở những phần code bạn chỉ cần chọn chúng và nhấn vào nút có hình # ở thanh công cụ phía trên khung soạn thảo (nếu không thấy thanh công cụ đầy đủ thì bạn chọn nút "Chuyển sang khung lớn" phía dưới khung soạn thảo). Thực tế thì việc nhấn nút đó sau khi chọn một đoạn text để hiển thị dạng code chỉ thêm các tag [ code] và [ /code] ở đầu và cuối của đoạn text cần định dạng (các tag thực không có khoảng trắng bên trong, tôi viết như vậy thì mới hiển thị bình thường).

Jerry
18-11-2006, 09:05 AM
Túm lại thì em vẫn chứ biết tại sao chương trình vẫn báo lỗi như vậy. Không biết có phải em viết chương trình có khai báo Directive kiểu CODE không. Nghĩa là em cố định địa chỉ PROGRAM MEMORY cho mỗi hàm và mỗi đoạn trong chương trình ấy (nói nôm na là như vậy). Ví dụ như là :

Start: CODE 0x0E
Begin: (thực hiện công việc nào đó ở đây)

đoạn khai báo trên làm cho chương trình hiểu là đoạn mã lệnh thực hiện công việc khai báo sau nhãn Begin sẽ được đặt ở địa chỉ bắt đầu là 0x000E ở trong bộ nhớ Program Memory của PIC.

Toàn bộ chương trình của em đều khai báo Directive kiểu như trên. Do vậy em không biết có phải điều đó ảnh hưởng đến việc sử dụng các MACRO trong chương trình không. Mong các cao nhân chỉ giáo!!!

namqn
18-11-2006, 09:12 PM
Túm lại thì em vẫn chứ biết tại sao chương trình vẫn báo lỗi như vậy. Không biết có phải em viết chương trình có khai báo Directive kiểu CODE không. Nghĩa là em cố định địa chỉ PROGRAM MEMORY cho mỗi hàm và mỗi đoạn trong chương trình ấy (nói nôm na là như vậy). Ví dụ như là :

Start: CODE 0x0E
Begin: (thực hiện công việc nào đó ở đây)

đoạn khai báo trên làm cho chương trình hiểu là đoạn mã lệnh thực hiện công việc khai báo sau nhãn Begin sẽ được đặt ở địa chỉ bắt đầu là 0x000E ở trong bộ nhớ Program Memory của PIC.

Toàn bộ chương trình của em đều khai báo Directive kiểu như trên. Do vậy em không biết có phải điều đó ảnh hưởng đến việc sử dụng các MACRO trong chương trình không. Mong các cao nhân chỉ giáo!!!
Bạn xem lại phần code của macro, chứ không phải phần code của chương trình. Mỗi lần bạn gọi macro thì các lệnh bên trong macro sẽ được chèn vào vị trí gọi macro, sau khi đã khai triển các biểu thức tham số. Theo thông báo lỗi thì bạn đang có Delay1 được hiểu là opcode, như vậy chính xác là phần mã lệnh nằm trước đó được hiểu là nhãn.

Việc khai báo vị trí tuyệt đối của các đoạn mã lệnh thực ra không cần thiết, trừ khi bạn có lý do đặc biệt để làm điều đó. Chúng ta thường chỉ cần khai báo vị trí tuyệt đối khi viết code cho reset vector và các ngắt.

Thân,

bien_van_khat
20-11-2006, 11:38 PM
ông bạn jerry không post code lên đây thì có đoán mò cả tháng cũng chẳng ra.

Jerry
21-11-2006, 04:23 PM
Cảm ơn các bác đã quan tâm giúp đỡ em ạ. Em cũng muốn post code của em lên đây cho các bác dễ quan sát lắm nhưng nhìn lại thì thấy nó những vài MB nên cũng ngại (vì chương trình của em giải quyết rất nhiều việc, em chia thành rất nhiều file nhỏ để dễ quản lý như các file *.asm, *.inc, *.lkr...), hic hic.

bien_van_khat
22-11-2006, 05:39 PM
Cảm ơn các bác đã quan tâm giúp đỡ em ạ. Em cũng muốn post code của em lên đây cho các bác dễ quan sát lắm nhưng nhìn lại thì thấy nó những vài MB nên cũng ngại (vì chương trình của em giải quyết rất nhiều việc, em chia thành rất nhiều file nhỏ để dễ quản lý như các file *.asm, *.inc, *.lkr...), hic hic.

Zip lại rồi attach vô 1 cái post của bạn đó, hay code của bạn thuộc hàng top secret, :-/

hieulongan039
09-07-2007, 11:38 PM
các bác cao thủ về viết các macro thi xin vui lòng hướng dẫn cụ thể hơn, vì mình dọc hoài mà chẳng hiểu gì cả,
ko biết các macro đặt ở đâu và cách gọi ra để sử dụng?
CJNE: MACRO THANHGHI,SO,CONTRO
MOVLW SO
SUBWF THANHGHI,W
BTFSS STATUS,Z
GOTO CONTRO
ENDM
NCJNE: MACRO THANHGHI,SO,CONTRO1
MOVLW SO
SUBWF THANHGHI,W
BTFSC STATUS,Z
GOTO CONTRO1
ENDM
FJNE: MACRO THANHGHI1,THANHGHI2,CONTRO
MOVF THANHGHI2,W
SUBWF THANHGHI1,W
BTFSS STATUS,Z
GOTO CONTRO
ENDM
FJE: MACRO THANHGHI1,THANHGHI2,CONTRO
MOVF THANHGHI2,W
SUBWF THANHGHI1,W
BTFSC STATUS,Z
GOTO CONTRO
ENDM

namqn
10-07-2007, 12:19 AM
Macro có thể đặt trong tập tin nguồn chính, trong tập tin include. Điều quan trọng là macro phải được định nghĩa khi trình biên dịch gặp một lệnh gọi (khai triển) macro. Ví dụ, nếu chương trình của bạn dùng một macro được định nghĩa trong một tập tin include, bạn chỉ dẫn (directive) để include tập tin đó phải xuất hiện trước khi bạn dùng macro lần đầu tiên trong code chương trình.

Lấy ví dụ macro CJNE mà bạn đã post lên, cú pháp của nó là:
CJNE thanh_ghi_được_so_sánh, số_được_so_sánh, nhãn_nhảy đến

Do đó bạn gọi macro trong chương trình như sau:
...
CJNE R1, 0x21, Label_1
...
Label_1:
...

Ở lệnh gọi macro trên, bạn so sánh thanh ghi R1 (đã được định nghĩa trước đó) với số 0x21, nếu chúng bằng nhau thì nhảy đến Label_1.

Thân,