![]() |
|
Tài trợ cho PIC Vietnam |
PIC - Thiết kế và Ứng dụng Ý tưởng cho các sản phẩm sử dụng PIC/dsPIC và các sản phẩm của Microchip |
|
Ðiều Chỉnh | Xếp Bài |
![]() |
#13 | |
PIC Bang chủ
|
Trích:
Chúng ta có một số ràng buộc cần phải thực hiện. Giải sử, với 5us, chúng ta có thể thực hiện khoảng 20 lệnh (không dùng thạch anh tốc độ cao hơn), nhưng giả sử dùng dsPIC tốc độ cao hơn thì chúng ta có thể bớt đi một chút nguy hiểm, nhưng F cứ giả sử là như vậy đã để chúng ta giải quyết bài toán. Giải pháp 1, chúng ta giảm bớt những câu lệnh trong chương trình ngắt ngoài: Timer_temp[i] = timer i = i+1; Cái này dùng để giữ giá trị ngắt ngoại lại thôi, có nghĩa là chúng ta không xử lý gì cả, chỉ giữ lại giá trị để gần tới hết chu kỳ chúng ta mới xử lý, và truyền về máy tính để xử lý (chu kỳ 10s), giả sử đến 9.5 giây chúng ta mới xử lý. Rồi, đoạn chương trình vào ngắt, giả sử chúng ta viết chương trình chỉ trong 1 page, và các lệnh vào ngắt có thể bỏ bớt những dòng lệnh thừa. Giảm tối đa được số lệnh vào và ra ngắt còn khoảng 10 lệnh, thay vì khoảng 20 lệnh như chuẩn, tức là chúng ta mất 2us ở đây. Như vậy, về mặt nguyên tắc, nếu hai xung gần nhau nhất là 5us, thì đảm bảo xử lý được. Cách làm như sau: Chương trình ngắt: Đoạn vào ngắt; TIMERHIGH[i] = TIMER1H; TIMERLOW[i] = TIMER1L; i = i+1; Đoạn kết thúc ngắt; Như vậy, sau khi gần hết chu kỳ, chúng ta gửi mảng giá trị Timer[i] = TIMERHIGH[i]_TIMERLOW[i] (word 16 bit, kết nối lại) về cho máy tính xử lý. Còn lại, đảm bảo trong vòng chương trình ngắt, chỉ xử lý tối đa khoảng 2,3us thôi. Trong đó, thời gian TOF = Timer[1] - đoạn vào ngăt; vì thời điểm đầu quay về. delay[i] = Timer[i+1] - Timer[i] Còn các đoạn sau thì chúng ta biết rõ là nó vào ngắt rồi Như vậy luôn luôn đảm bảo. Vấn đề tiếp theo. Đó là may mắn khi mà timer chưa tràn. Chúng ta phải xử lý vấn đề khi timer tràn nữa. Như vậy, chúng ta phải bật một cái ngắt cho timer tràn nữa, nhưng luôn luôn ưu tiên ngắt ngoài. Lưu ý ở đây, timer bắt buộc setup ở tỉ lệ 1:1 so với tốc độ máy. Cho nên, chỉ vài lệnh, thì timer không thể tràn 2 lần được, vì timer 1bit. Giả sử có 6 lần vào ngắt (6 xung nhận về, nếu đủ 6 xung thì thôi, không cho phép ngắt ngoài nữa). Tổng thời gian tối đa: 30 (lệnh trong ngắt ngoài) x 6 = 300. Trong khi đó, 16bit lưu được số lớn hơn nhiều. Thành ra cái này hoàn toàn không sợ. Chỉ sợ là giữa hai xung bất kỳ, có khi timer sẽ bị tràn. Khi này chúng ta xử lý như sau: Chương trình ngắt: Đoạn vào ngắt; Nếu là ngắt ngoài, thực hiện chương trình ngat1: Nếu là ngắt timer, thực hiện chương trình ngat2: ngat1: TIMERHIGH[i] = TIMER1H; TIMERLOW[i] = TIMER1L; i = i+1; ngat2: chỗ này lưu ý, phải enable ngắt ngoài timer_counter = timer_counter + 1; temp[i] = i; để biết là lúc nào thì thì cờ tràn, sau này mới xử lý được Đoạn kết thúc ngắt; Như vậy, rõ ràng, neu như trong đoạn này mà ngắt ngoài xảy ra, chúng ta sẽ gặp vấn đề. bị mất một số chu kỳ nếu như ngắt xảy ra. Do vậy, chỗ này phải sử dụng kỹ thuật ngắt trong ngắt. Phần ngắt trong ngắt, bạn có thể xem cách xử lý ở dientuvietnam. Viết MPASM thì sẽ đơn giản hơn. Lúc này đặt lại cờ GIE, nếu như ngắt xảy ra thì nó sẽ tự động nhảy lại về chương trình ngắt. Chúc vui
__________________
Công ty TNHH Thương mại và Giao nhận R&P store.hn@rpc.vn - store.hcm@rpc.vn Học PIC như thế nào? |
|
![]() |
![]() |
|
|