Trích:
Nguyên văn bởi bachelor1979
- Khoảng cách giữa các xung phản xạ trên thực tế nhỏ nhất cỡ vài us, điều này tôi ko nói chính xác được vì còn tùy thuộc vào khoảng cách giữa các mục tiêu và quỹ đạo chuyển động của chúng, nếu chương trình ngắt có độ dài từ 5-10us thì có thể chấp nhận được (thực tế với khoảng cách xung 5us thì hoặc là các mục tiêu bay rất sát nhau, hoặc là chúng đang ở rất xa, trường hợp thứ nhất ít khi xảy ra vì khi đó các mục tiêu rất dễ đâm vào nhau hoặc dễ bị bắn theo kiểu "xuyên táo" nên ko mấy khi mục tiêu cơ động gần nhau như vậy, còn trường hợp thứ hai với cự ly xa như vậy thì việc xác định đó là mục tiêu tốp hay xác định nhầm là 1 mục tiêu đơn ko quan trọng lắm)
- Số lượng các xung phản xạ dao động từ 0 (khi ko có mục tiêu) đến 6 (ở bài trước tôi đã nói rồi mà n < 7), n sẽ ko cố định mà có thể thay đổi (bạn cứ hình dung: giả sử ban đầu có 6 mục tiêu (tối đa) bay vào -> có 6 xung phản xạ, sau đó tùy tình huống có thể 1 mục tiêu phát nhiễu hoặc cơ động vòng ra(tức là bay ra khỏi vùng quan sát được của VIKO) -> số lượng xung phản xạ giảm đi) nói chung tối đa là 6 xung
- Khoảng cách gần nhất giữa các xung là 5us (cứ cho là như vậy đi để bài toán đỡ phức tạp hơn) còn khoảng cách xa nhất là 10s (nếu nhìn vào giản đồ xung bạn sẽ thấy điều này - bởi vì nếu khoảng cách đó vượt quá 10s nó sẽ bị lầm sang chu kỳ sau và trên thực tế không có xung phản xạ nào như vậy cả)
- Để F và các bạn dễ hình dung hơn tôi sẽ post lên đây chương trình mô phỏng VIKO của tôi, tất nhiên vẫn đang trong giai đoạn test và các mục tiêu là giả
Thân !!!
|
Dựa theo những gì bạn nói, chúng ta chắc chắn phải sử dụng ngắt trong ngắt để thực hiện vấn đề này.
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