PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > Cơ bản về vi điều khiển và PIC

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Cơ bản về vi điều khiển và PIC Những bài hướng dẫn cơ bản nhất để làm quen với vi điều khiển PIC

 
 
Ðiều Chỉnh Xếp Bài
Prev Previous Post   Next Post Next
Old 19-07-2008, 08:48 PM   #6
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Trích:
Nguyên văn bởi bachelor View Post
Thanhks, như vậy là đã rõ về hàm set_timerX();
Vấn đề tiếp theo
Trở lại bài toán mà tôi đã đề cập ở trên, tuy nhiên khi này khoảng cách (thời gian) giữa 2 xung thay đổi trong một dải lớn, giả thiết là từ 100us đến 10ms.
Vẫn sử dụng timer0 làm bộ định thời với clock nội = 1MHz, prescale = 1.
Khi này không thể sử dụng cách mà tôi đã nêu ở bài trước (vì với những khoảng thời gian > 256us thì rõ ràng hàm get_timer0() sẽ trả về giá trị sai)
Trong trường hợp này phương án giải quyết của tôi như sau:
- ở phần khởi tạo, cho phép ngắt bởi bộ định thời 0.
- phần chương trình thực hiện bởi ngắt định thời 0: tăng biến đếm i lên 1 (i là biến toàn cục)
- ngắt ngoài khi có xung thứ nhất đến: gán i = 0; gọi hàm set_timer0(0); gọi hàm enable_interrupts(INT_TIMER0);
- ngắt ngoài khi có xung thứ hai đến: diasble_interrupts(INT_TIMER0); Thời gian cần đo = i*256 + get_timer0(); [đơn vị us]
Khi test chương trình trên proteus với khoảng cách xung lớn thì khá chính xác, nhưng khi khoảng cách nhỏ hơn 256 us thì kết quả ra không chính xác và thay đổi loạn cả lên, không hiểu vì sao
Vậy mong mọi người xem qua phương án giải quyết bài toán của tôi và chỉ giùm tôi chỗ sai sót.
To Namqn: Trên thực tế bài toán tôi cần giải quyết cho phép sai số 1 vài us khi đo. Cũng lâu rồi không vào diễn đàn, quả thật đã từng hỏi vấn đề này nhưng trước đó tôi hỏi theo khía cạnh khác có thể nói là không liên quan . Thanks !
Về mặt nguyên tắc, phương pháp thực hiện của bạn là ổn. Trong thực tế, có những yếu tố dẫn đến sai lệch kết quả đo mà bạn không đánh giá trong phương pháp trên.

Như tôi đã nói ở post trên, có thời gian trễ giữa thời điểm xuất hiện xung và việc diễn ra các thao tác. Cụ thể: khi xuất hiện xung thứ nhất, vài chu kỳ máy sau trình phục vụ ngắt ngoài mới được thực hiện, và mất thêm vài chu kỳ máy nữa cho việc lưu các thanh ghi cần được lưu (việc này trình biên dịch tự làm) rồi mới đến các lệnh thực sự. Khi xuất hiện xung thứ hai, tương tự như vậy, cũng mất một khoảng thời gian nữa mới đến việc thực thi các lệnh mà bạn muốn thực hiện cho trường hợp này, bên trong chương trình phục vụ ngắt. Thời gian trễ ở trường hợp thứ nhất và trường hợp thứ hai có thể khác nhau. Điều quan trọng hơn nữa, thứ tự thực hiện lệnh cho các trường hợp sẽ ảnh hưởng rất lớn đến sai lệch của kết quả.

Bạn nên chỉnh lại thứ tự thực hiện như sau (cho trình phục vụ ngắt ngoài):
- Ngắt ngoài khi có xung thứ nhất đến: gọi hàm set_timer0(0); gọi hàm enable_interrupts(INT_TIMER0); gán i = 0;
- Ngắt ngoài khi có xung thứ hai đến: biến_tạm = get_timer0(), diasble_interrupts(INT_TIMER0); thời gian cần đo = i*256 + biến_tạm; [đơn vị us]

Tuy nhiên, tôi cho rằng phương pháp sau tốt hơn:
1. Khởi tạo timer0 và cho phép ngắt timer0, nhưng timer0 chưa chạy; xóa thanh ghi timer0

2. Giả thiết bạn dùng PIC16/PIC18, chương trình phục vụ ngắt sẽ kiểm tra ngắt ngoài trước rồi mới kiểm tra ngắt timer0

3. Ngắt ngoài khi có xung thứ nhất đến: bật timer0 bằng hợp ngữ; gán i = 0;

4. Ngắt ngoài khi có xung thứ hai đến: đọc thanh ghi timer0 vào biến_tạm bằng hợp ngữ; tắt timer0; xóa thanh ghi timer0; thời gian cần đo = i*256 + biến_tạm; [đơn vị us]

5. Phần code phục vụ ngắt timer0 chỉ tăng i

6. Nếu thời gian đo được luôn lớn hơn hay nhỏ hơn thời gian thực tế, bạn có thể bù sai lệch này trong công thức tính thời gian cần do.

Cần nhớ: Thứ tự viết code là quan trọng, vì bạn đo thời gian, mà các lệnh cũng cần thời gian để thực thi.

Thân,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
 


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 10:00 PM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam