Lúng túng với Interrupts - nhờ trợ giúp
Code:
#include <16F877A.h> hiện tượng xảy ra thế này - khi cho dòng lệnh enable_interrupts(global) - cho phép ngắt - thì LCD ko hiện dòng chữ gì cả ? ngay cả khi ta reset để cố tình cho ct chỉ chạy trong MAIN (tức là phải có dòng "ready!' - khi disable_interrupts(global) thì dòng "ready!" hiện ra ( có thể hiểu là ct chạy đúng theo ý đồ ) tại sao vậy ? - chả lẽ set_tris các port bị sai so với phần cứng ? - hay khởi tạo ngắt chưa đúng , nên ct nhảy ngắt lung tung ? |
Nếu bạn debug = ICD2 thì INT_RB sẽ hoạt động ko đúng, vi lúc này 2 chân RB6 RB7 do ICD2 điều khiển.
Trong hàm phục vụ ngắt bạn không cần xóa cờ ngắt, trình dịch tự sinh mã làm điều này cho bạn. Bạn có thể sử dụng thư viện giao tiếp LCD của CCS C(trong thư mục /drivers) |
- thư viện LCD trong PICC/drivers là giao tiếp 4 bit , mình đang giao tiếp 8 bit
- mới nhập môn nên ko hiểu ICD2 là cái gì , đc biết nó là mạch debug ngoài , ko biết có đúng ko ? nhưng mình đang test ct trên mạch thật . Do đó , điều thắc mắc bây giờ là : cần chỉnh lại ct chỗ nào để chạy đúng ý đồ( ý đồ : khi có ngắt thì quét phím & hiển thị số đã bấm ; khi ko có ngắt thì hiện dòng READY! ) hay phải thay đổi lại phần cứng ? |
Bạn coi lại chân RA2==OK, bạn dùng CCS thì khi chạy, sau khi enable interrupts thì chuơng trình sẽ nhảy vào ISR liền. Khi đó nếu RA2=1 thì chuơng trình chỉ chạy trong phần ISR ( int_RB) mà thôi, chưa kịp tới vòng while(1) để hiển thị chữ ready.
|
Thực tế nếu ko xài ICD2, theo mình với chương trình như trên ngắt RB không bao giờ xảy ra vì bạn cấu hình PORTB<4:7> là output. Do 4 chân này không được pull-up hoặc pull-down nên cho dù cấu hình là input bạn cũng không thể dùng ngắt INT_RB theo đúng ý đồ được.
Chương trình của bạn viết khá rối rắm nên mình mới khuyên dùng thư viện của CCS, ví dụ Code:
ext_int_edge(H_to_L); Để kiểm tra nguyên nhân bạn thử disable INT_RB xem. |
Trích:
uhm ! đúng như bạn nói , khi mình disable int_RB thì mọi chuyện hoạt động bình thường Bây giờ : - cho 4 con trở 10k kéo xuống ở chân RB4 - RB7 . - còn cấu hình cho ngắt khi thay đổi mức trên RB , mình phải chữa lại ntn ? ĐÚng là mình chưa nghĩ thấu đáo vấn đề ! |
Trích:
cách giải thích của bien_van_khat có vẻ đúng . Mình nghĩ hơi nông cạn ! hic.... |
Code:
#use delay(clock=4000000) đây là mạch & code của anh nnh - có phải mắc mạch quét phím kiểu này thì mới dùng đc INT_RB ? ah có vẻ bây giờ mình đã phân biệt đc : ngắt có thay đổi mức trên RB & ngắt ngoài trên RB . Ko biết mình hiểu như thế đã trọn vẹn chưa ? |
Sơ đồ cũng như code bạn vừa đưa ra ở đây cũng có vấn đề, mình nghĩ rằng nó chỉ hoạt động đúng khi mô phỏng còn khi chạy thực tế mạch sẽ không ko hoạt động như ý đồ.
Thứ 1 về pull-up hoặc pull-down. Khi hoạt động thực tế, bạn không bao giờ được để Input pin lơ lửng như thế. Khi ở mode input, trở kháng vào của chân IO là trở kháng vào của cực Gate của MOSFET. Do trở kháng vào này cực kỳ lớn nên chỉ cần một sự biến thiên điện trường nhỏ cũng đủ gây nên một xung điện áp trên mạch vào, điện áp này đủ khả năng để đầu ra của Smith trigger thay đổi trạng thái, hoặc khiến mạch vào TTL chuyển mức. Nói tóm lại là tín hiệu đọc trên PORT sẽ nhảy tùm lum dù ko có phím bấm. Vậy nên dùng pull-up hay pull-down? Thiết kế input ko nên sử dụng pull-down, vì nếu pull-down, tức là khi idle, mức logic=0, vậy để chuyển mức logic thành 1, bạn cần phải đưa lên nguồn Vdd qua một điện trở hạn dòng (ko hạn dòng sẽ làm hư IO pin). Như vậy rõ ràng một mạch vào cần 2 điện trở là ko hiệu quả về linh kiện, chưa nói đến hiệu quả về thiết kế nếu IO pin cần hạn dòng nhiều, bạn phải tính toán giá trị điện trở cho phù hợp. Sử dụng pull-up vừa tiết kiệm vừa đơn giản. Thứ 2, ngắt thay đổi mức trên PORTB bạn có thể coi trong datasheet của 16F877A, đây là ngắt xảy ra khi mức logic trên PORTB<4:7> thay đổi (từ 0->1 hoặc từ 1->0). Bạn nên để ý là với 877A chỉ có 4 bit cao của PORTB là có chức năng này thôi nhé, và chỉ xảy ra khi chân đó là input. Với mạch của bạn rõ ràng vấn đề nằm ở ngắt INT_RB, bạn có thể mắc thêm 4 con 10K lên Vdd, hoặc gọi hàm Code:
port_b_pullups(TRUE); |
http://i189.photobucket.com/albums/z...atranphim2.jpg
http://i189.photobucket.com/albums/z.../LCDkeypad.png Code:
#int_RB - LCD giao tiếp 4 bit ( để lợi dụng thư viện CCS) - ma trận phím để sd INT_RB - cách viết code như vậy đã đúng : khi có ngắt thay đổi mức trên RB4-RB7 thì tạo ngắt & ct nhảy vào quetphim_hienthi() ; ko thì hiện dòng READY ! |
các bạn cho ý kiến về mạch + ct để mình hoàn thiện trước khi đi in . Chắc cái mạch mình đang test ... vứt đi rùi ! Làm lại mạch mới thôi ... cũng tốn kha khá đấy chứ nhẩy ? hic !
|
Múi giờ GMT. Hiện tại là 11:08 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