|
Tài trợ cho PIC Vietnam |
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 |
08-04-2009, 11:49 PM | #1 |
Đệ tử 7 túi
Tham gia ngày: Aug 2007
Bài gửi: 213
: |
CCS-Chuyển giá trị từ chương trình chính sang chuơng trình ngắt
Mình viết đoạn code như sau để thực hiện ngắt trên port D:
Code:
// INTEXT.C MPB 10-4-07 // Demo external interrupt // RB0 low interrupts // foregroundoutput count #include "16F887.h" #use delay(clock=2000000) #int_ext void isrext() { output_D(255); delay_ms(1000); } void main() { int x=10; enable_interrupts(int_ext); enable_interrupts(global); ext_int_edge(H_TO_L); while(1) { output_D(x); x++; delay_ms(100); } } Bây giờ mình muốn chương trình ngắt thực hiện công việc là khi bắt đầu ngắt thì sẽ lấy giá trị hiện thời của x trong chương trình chính và đưa vào chương trình ngắt,mình sửa code lại như sau nhưng chưa chạy được: Code:
// INTEXT.C MPB 10-4-07 // Demo external interrupt // RB0 low interrupts // foregroundoutput count #include "16F887.h" #use delay(clock=2000000) #int_ext void isrext() { output_C(x); //muc dich là xuat ra portC giá trị của x hiện thời trong ct chính delay_ms(1000); } void main() { int x=10; enable_interrupts(int_ext); enable_interrupts(global); ext_int_edge(H_TO_L); while(1) { output_D(x); x++; delay_ms(100); } } |
09-04-2009, 12:22 AM | #2 |
Trưởng lão PIC bang
|
Bạn không nên dùng delay_ms(1000) trong chương trình xử lý ngắt, vì các hoạt động khác trong vòng lặp chính sẽ bị dừng lại cho đến khi trở về từ ngắt, mà trong ngắt bạn lại dừng lại 1000 ms chẳng làm gì cả.
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 |
09-04-2009, 01:24 AM | #3 |
Đệ tử 7 túi
Tham gia ngày: Aug 2007
Bài gửi: 213
: |
Vậy còn vấn đề biến x thì sao hả anh ?Em nghĩ là giá trị x trong chương trình chính đang chạy sẽ lưu vào một địa chỉ nhớ nào đó.làm sao mình đọc nó ra và gán vào cho biết nằm trong chương trình ngắt ?
|
09-04-2009, 03:33 AM | #4 | |
Trưởng lão PIC bang
|
Trích:
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 |
|
09-04-2009, 11:12 AM | #5 |
Đệ tử 4 túi
Tham gia ngày: Aug 2008
Bài gửi: 89
: |
Code:
// INTEXT.C MPB 10-4-07 // Demo external interrupt // RB0 low interrupts // foregroundoutput count #include "16F877a.h" #fuses HS,NOWDT #use delay(clock=12000000) int x=10; #int_ext void isrext() { output_c(x); //muc dich là xuat ra portC giá tri. cu?a x hie^.n tho+`i trong ct chính delay_ms(1000); } void main() { enable_interrupts(global); set_tris_b(get_tris_b()|0x01); enable_interrupts(int_ext); ext_int_edge(H_TO_L); while(1) { output_d(x); x++; delay_ms(100); } } Chú ý: Tầm cực biến x để isrext() có thể truy cập. Giá trị trên Port D sẽ thường nhỏ hơn 1 so với Port C vì lệnh x++ thực thi sau lệnh gán output_d(x) (chỉ trừ khi interrupt xảy ra ngay sau lệnh output_d(x) và trước lệnh x++, khả năng ~ 0) nên nếu muốn 2 Port xuất giá trị bằng nhau khi nhấn phím thì chuyển lệnh x++ lên trước.
__________________
Quang báo RG/RGB 6/8/12/16 bits màu Phone No: 0905.034.086 Email: lmquyen@gmail.com |
10-04-2009, 10:04 AM | #6 |
Đệ tử 1 túi
Tham gia ngày: Feb 2009
Bài gửi: 19
: |
- Mình cũng nghĩ vậy đó, nếu khai báo x la biến toàn cục thì ngắt có thể hiểu được đó!
|
10-04-2009, 10:26 AM | #7 | |
...Damned...
Tham gia ngày: Apr 2006
Nơi Cư Ngụ: Hồ Chí Minh
Bài gửi: 522
: |
Trích:
Với biến kiểu integer 8 bit, biểu thức x++ có thể được dịch thành mã máy là incf x, 1, tức là thực hiện x++ chỉ trong 1 chu kỳ máy, trong trường hợp này thì chưa có vấn đề. Nhưng không ai đảm bảo là biểu thức đó sẽ được dịch thành chỉ 1 lệnh. Nếu x là kiểu 16 hoặc 32 bit thì chắc chắn là không thể thực hiện x++ trong 1 chu kỳ máy. Nếu ngắt xảy ra khi đang thực hiện x++, chuơng trình phục vụ ngắt của bạn lại thay đổi giá trị của x thì sẽ gây lỗi chuơng trình và có thể rất khó phát hiện vì hiếm khi xảy ra. Để tránh trường hợp này, với những biến dùng chung cho cả chuơng trình chính và chuơng trình con bạn phải khai báo volatile. VD: volatile int x; |
|
10-04-2009, 11:53 AM | #8 | |
Đệ tử 4 túi
Tham gia ngày: Aug 2008
Bài gửi: 89
: |
Trích:
2. Việc khai báo volatile cho biết biến x có thể được truy cập, thay đổi giá trị từ nhiều điểm thực thị trong chương trình(nên thường dùng cho các port IO) chứ không đảm bảo việc khi thực hiện x++ sẽ đúng khi có nhiều chương trình cùng thao tác trên x. Một điểm nữa cần để ý là khai báo volatile sẽ giúp compiler sẽ thực hiện thao tác tối ưu đúng(không tự động xóa các biểu thức điều kiện sai) khi gặp biến volatile. 3. Giải pháp critical access đơn giản nhất là: Code:
disable_interrupts(GLOBAL); //Đảm bảo không có ngắt nào được thực thi đoạn code tiếp sau lệnh này x++; //x co the la so integer 8,16,32 bits enable_interrupts(GLOBAL);
__________________
Quang báo RG/RGB 6/8/12/16 bits màu Phone No: 0905.034.086 Email: lmquyen@gmail.com |
|
10-04-2009, 06:18 PM | #9 | ||||
...Damned...
Tham gia ngày: Apr 2006
Nơi Cư Ngụ: Hồ Chí Minh
Bài gửi: 522
: |
Trích:
Dĩ nhiên trong bài toán này, lỗi này ko xảy ra vì x++ chỉ thực hiện trong 1 chu kỳ máy. Và có xảy ra cũng ko gây ra chuyện gì ghê ghớm, chỉ hiện thị sai vài con led. Trích:
Trích:
Trích:
|
||||
10-04-2009, 08:10 PM | #10 |
Trưởng lão PIC bang
|
Google với cụm từ khóa "volatile in C", một vài link tốt như sau:
http://publications.gbdirect.co.uk/c..._volatile.html http://www.netrino.com/node/80 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 |
10-04-2009, 11:26 PM | #11 | |
Đệ tử 4 túi
Tham gia ngày: Aug 2008
Bài gửi: 89
: |
Ok, đồng ý nếu được chúng ta nên để ý và giải quyết triệt để vấn đề về đa truy cập biến dữ liệu để đảm bảo chương trình chạy đúng trong mọi trường hợp.
Trích:
__________________
Quang báo RG/RGB 6/8/12/16 bits màu Phone No: 0905.034.086 Email: lmquyen@gmail.com |
|
29-04-2009, 03:28 PM | #12 |
...Damned...
Tham gia ngày: Apr 2006
Nơi Cư Ngụ: Hồ Chí Minh
Bài gửi: 522
: |
"The use of volatile is poorly understood by many programmers".
|
01-05-2009, 10:29 AM | #13 | |
Đệ tử 2 túi
Tham gia ngày: Oct 2008
Bài gửi: 27
: |
Trích:
để delay_ms(1000) cũng được có sao đâu. Tùy theo mục đích của mình thôi, hơn nữa trong chương trình này mình chỉ sử dụng một ngắt thôi mà. Đâu sợ ngắt khác xảy ra. |
|
04-05-2009, 07:00 PM | #14 |
Đệ tử 2 túi
Tham gia ngày: Oct 2008
Bài gửi: 27
: |
Bác nghĩ vậy có thể chưa đúng, Nếu x là biến toàn cục thì biến x trong main va trong ngắt là một. Nếu x không phải là biến toàn cục thì khác nhau, tức là như bác nói vậy, x trong chương trình main là khác, khi vô ngắt x này tự lưu lại và x trong ngắt là một biến khác. Khi thoát khỏi ngắt thì nó lại pop giá trị x nảy lưu ra tính tiếp. chào
|
|
|