![]() |
Macro delay cho Pic18, sai số 1 chu kỳ lệnh
1 Attachment(s)
Thông thường sau khi viết chương trình bằng ASM, để sử dụng lại đoạn code đã viết cho một chương trình khác ta thường copy và paste. Bài viết này hướng dẫn viết một macro thư viện, tiện cho việc sử dụng lại các module đã viết. Và mình sẽ bắt đầu với module delay cho Pic18
Một số điểm lưu ý với macro delay này: 1. Thời gian: 1 cycles = 4 xung clock. Ví dụ: Pic hoạt động ở tần số 20Mhz tức là một giây Pic thực hiện 20*10^6 xung clock. 2. Lệnh Goto address: Lệnh này là 1 lệnh 2 words, thời gian thực hiện là 2 cycles. Khi dịch ra hex nó bao gồm 1 word... mà mình không biết (hi hi) và 1 word là lệnh NOP. Ta quan tâm đến cái NOP này. Ví dụ: Goto $+d'4' movlw d'10' Do MPASM định offset theo byte. 2 words=4bytes. Lệnh này sẽ nhảy đến vị trí lệnh kế tiếp là lệnh movlw d'10', mất 2 cycles Nếu thay lệnh trên là "Goto $+d'2' thì nó sẽ nhảy đến cái word thứ 2 của nó là NOP. Do đó lúc này để đến được lệnh movlw d'10' nó mất 3 cycles. 3. Lệnh decfsz f,d,a: Trừ thanh ghi f cho 1. Bỏ qua lệnh kế tiếp nếu kết quả bằng 0. Nếu d=0, kết quả chứa trong WREG, d=1 thì chứa trong thanh ghi f. a=0 sử dụng access bank, a=1 sử dụng BSR để tham khảo bank hiện tại. Thời gian thực hiện: f!=0--> 1cycles. f=0 -->Lệnh tiếp theo nếu là 1 word thì 2 cycles; còn nếu lệnh tiếp theo là 2 word, thời gian thực hiện sẽ là 3 cycles. Ví dụ: với d1=1 decfsz d1,d'1',d'0' Goto address Sau khi trừ thì d1=0 nó sẽ bỏ qua lệnh kế tiếp tức là word thứ 1 của lệnh goto, nó sẽ thực hiện word thứ 2 của lệnh goto... Nhưng mà hehe... mình đã nói ở trên word thứ 2 là NOP. Cho nên lúc này nó cần tới 3 cycles. Như vậy, trong cả 2 trường hợp là d1=0 và d1!=0 thì tổng thời gian thực hiện đoạn lệnh nhỏ ở trên là 3 cycles. Rồi, đủ rồi... Here we go. Các link tham khảo: http://www.piclist.com/techref/picli...egen/delay.htm http://www.piclist.com/techref/micro...ayTutorial.htm Chúng ta sẽ làm gì đầu tiên? Đầu tiên tất nhiên là suy nghĩ roài. Haizzz, giả sử như-việc viết một chương trình delay mà khi được gọi đến nó sẽ delay đúng thời gian mà ta qui định-là khả thi. Như vậy, lúc này nó bao gồm thêm một lệnh call hoặc rcall và 1 lệnh return. 2 lệnh này mỗi lệnh thực hiện trong 2 cycles. Như vậy để sử dụng được delay thì khoảng thời gian ít nhất phải là 4 cycles. Việc này tạm thời gác lại vì nó hoàn toàn có thể giải quyết được bằng macro. Vấn đề bây giờ là tìm được thuật toán để delay một khoảng thời gian thích hợp với thuật toán đó (hix...). Xét đoạn chương trình sau: decfsz d1,d'1',d'0' Goto $-d'2' Nếu d1!=0 thì nó sẽ nhảy về lệnh decfsz. Như vậy đoạn code mất tổng cộng là 3*d1 cycles. Để sử dung được lệnh này làm chương trình con tất nhiên phải có thêm: Code:
delay_1l ; nhãn của chương trình con Xét đoạn chương trình tiếp theo: Code:
decfsz d1,d'1',d'0' Code:
delay_2l ; nhãn của chương trình con Thời gian delay thích hợp cho đoạn chương trình delay_2l là: 14 cycles<=cycles_need<=197384 cycles. .................................................. ............. Bây giờ nói đến macro. Cái macro dùng để làm gì? Nói nôm na thì nó được sử dụng để sinh mã đúng với mong muốn của người lập trình. Trong trường hợp này là: nếu cycles_need có giá trị trong một đoạn nào đó thì ta đặt một đoạn code delay tương ứng. _ Với 0<= cycles_need<= 8: ta sử dụng các lệnh goto và nop để tạo delay _ Với 9<= cycles_need<=774: ta sử dụng delay_1l _ Với 775<= cycles_need<=197384: ta sử dụng delay_2l Tham khảo về macro, các directives if...else...end, while...endw và các chỉ dẫn dành cho biên dịch trong phần help. Macro delay_cycles sẽ gọi 1 macro tương ứng tùy theo giá trị của cycles cần delay Code:
delay_cycles macro cycles Code:
delay_0l macro cycles Code:
delay_1l macro cycles Code:
delay_2l macro cycles Code:
label macro [arg1,arg2...] Code:
decfsz d1 Code:
movlw primary2 Phần việc còn lại là hoàn thiện đoạn Macro delay_0l, delay_1l, delay_2l , thêm vào delay_3l với thời gian delay lớn hơn. Thêm macro delay_us, delay_ms, và delay_s bằng cách quy đổi thời gian cần delay ra cycles. Muốn vậy thì phải thêm 1 macro được người dùng sử dụng để cho biết tần số của Pic18 được sử dụng, ta đạt là macro use_delay Code:
use_delay macro _fosc Có 3 lưu ý nhỏ khi sử các Macro này: 1> Sai số 1 cycles là do khi qui đổi từ thời gian us, ms, s; sang cycles. 2> Sau khi sử dụng các Macro này thì thanh ghi WREG bị thay đổi 3> Do chỉ sử dung "movwf f_reg" nên theo mặc định trong MPASM thì chỉ sử dụng access bank dể tham khảo đến thanh ghi d1,d2,d3. Do đó cần phải đặt 3 thanh ghi này ở bank thích hợp 4> Thời gian delay tối đa là 50,529,034 cycles. Nếu muốn thêm bạn có thể viết lại hoặc viết thêm macro delay_4l 5> Cách sử dụng Macro trên cho Pic18: sử dụng đơn giản, trước tiên phải chỉ định tần số hoạt động của Pic18, tất nhiên là không quên phần include file vào use_delay d'20' ; nếu tần số hoạt động là 20Mhz delay_us d'50' ; delay khoảng thời gian là 50 us Do không thể giải thích chi tiết về các dòng lệnh trong macro nên nếu bạn nào có thắc mắc thì cứ tự nhiên đặt câu hỏi. Thân namqn: bạn chú ý tránh sử dụng Unicode tổ hợp. |
Múi giờ GMT. Hiện tại là 10:00 PM. |
Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam