PDA

View Full Version : Một số vấn đề về MPASM


thaile
11-08-2008, 01:32 AM
Ai cũng biết ASM là ngôn ngữ cấp thấp hay đơn giản chỉ là những từ gợi nhớ cho các lệnh bên trong chip, cùng với các directive được cung cấp bởi hãng phát hành hỗ trợ cho việc biên dịch chương trình.
Chính vì thế sử dụng ASM viết chương trình rất khó để quản lý các project cỡ vừa, chứ đừng nói tới cỡ lớn:
1> Việc chọn Bank: nếu chương trình nhỏ, ít biến thì không vấn đề gì, nhưng với những chương trình có số biến lớn thì việc nhớ chính xác vị trí các biến để chọn bank là một điều không hề đơn giản và gây nhiều khó chịu khi lập trình.
2> Việc quản lý bộ nhớ dữ liệu đối với các chương trình cỡ vừa là không hề đơn giản với những người mới làm quen với ASM
3> Với các chương trình lớn nhiều module thì quả thật là khó khăn
4> Không có các toán tử logic như and, or, not; các phép so sánh khó sử dụng
5> Không có các hàm if...then...else; while...do

Chính vì thế mà người ta thường hay chọn các ngôn ngữ khác để viết cho Pic như HTpic, MCC, CCSC, MikroC...

Ưu điểm lớn nhất của ASM chính là viết code được tối ưu, và khi viết bằng ASM ta học được nhiều điều về cái cục đen đen khó chịu kia. Tuy nhiên việc tối ưu cũng không hề đơn giản một chút nào

Đây là một số kinh nghiệm của mình, mình làm quen với vxl nói chung và pic nói riêng cũng chưa lâu, chỉ khoảng 3 tháng trở lại đây, cho nên những điều mình nói có thể không đúng, mong các bạn đóng góp. Và nói thật thì mình cũng chưa làm một cái project cỡ vừa nào như ở trên đã nói.

Giải quyết 1 số vấn đề: Các vấn đề được giải quyết theo hướng viết macro.
Nếu bạn quan tâm thì tham khảo thêm một số directives ,tham khảo về Macro trong MPLAB IDE---> Help/topic/Mpasm assembler
Lưu ý: Các code trong này chỉ dành cho Pic18f458

1> Việc chọn bank: Sử dụng 2 biến cho biên dịch chương trình "R_bsr, N_bsr" (Right_bsr, Next, bsr)
(biến cho biên dịch chương trình được dùng sử dụng cho trình biên dịch, nói cách khác nhờ các biến này mà ta biên dịch được chương trình theo đúng ý đồ)

a> define bank: PIC 18f458 có 16 bank từ 0 đến 15 nên ta define nó như sau( tra theo datasheet)

bank0 equ 0x100
bank1 equ 0x200
...
bank15 equ 0x1000
end_GPR_access_bank set 0x05f
begin_SFR_access_bank set 0xf60

R_bsr set d'0' ; 2 biến này không phụ thuộc vào loại Pic18 mà ta dùng
N_bsr set d'0'

b>Thuật toán:
_ Sử dụng R_bsr để lưu giá trị bank chứa thanh ghi hiện tại.
_ Xét thanh ghi tiếp theo xem nó nằm ở bank nào.
_ Quyết định xem hoặc sử dụng access bank, hoặc dùng "banksel", hoặc không dùng cả 2 thứ vừa rồi
Code dưới đây giải quyết vấn đề trên:

op_banksel macro reg ;nhiệm vụ của macro này là xem thanh ghi trong
local i, chk ;lệnh addwf thuộc bank nào, lưu vào N_bsr
chk=0
i=0
while chk==0
if reg<(bank#v(i))
chk=1
endif
i+=1;
endw
N_bsr=i-1;
endm

op_addwf macro f_reg,d_reg
op_banksel f_reg ;gọi macro op_banksel
if N_bsr==R_bsr ;so sanh giá trị next_bsr
addwf f_reg, d_reg, banked ;và right_bsr
else
if (f_reg>=begin_SFR_access_bank)|(f_reg<=end_GPR_access_bank)
addwf f_reg, d_reg, access
else
banksel f_reg
addwf f_reg, d_reg, banked
R_bsr=N_bsr
endif
endif
endm

Như vậy sau này khi sử dụng lệnh "addwf f,d,a" (thông tin về lệnh này tra trong datasheet), ta chỉ cần thay thế nó bằng "op_addwf f,d" (không cần tùy chọn "a" để xài access_bank hay không vì trong macro đã làm sẵn việc này)

Tiếp theo chỉ việc thay thế các lệnh liên quan đến chọn bank

Đổi đuôi file dưới thành .inc rồi include vào chương trình