PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > Các ngôn ngữ lập trình khác (CCS C, HT 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

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 21-05-2008, 02:12 AM   #1
mr_riverrain
Nhập môn đệ tử
 
Tham gia ngày: Jul 2007
Bài gửi: 8
:
Hỏi về ngắt timer1

Em đã bới tung cả diễn đàn(chủ yểu là ở "Cơ bản về vi điều khiển và PIC" và " Các ngôn ngữ lập trình khác ") lên để tìm xem có nói về ngắt timer mà sao khó quá. Có chỗ mấy anh hỏi thì lại không có ai trả lời. Đề bài của em là trong CCS C dùng Timer1 tạo ra một thời gian là 1 giây.
Ví dụ:
Code:
#Int_TIMER1
void Time()
{
   bien++;
    if (bien>=40)
      {    Count=get_timer1();
            set_timer1(0);
            St=1;
            bien=0;
       }
}
Em muốn hỏi cách tính làm sao tính ra chính sác 1 giây (tại sao lại là số 40 kia ). Hầu hết các bài hướng dẫn đều hướng dẫn cách tính bằng ASM theo từng lênh.
Có ai có thể hướng dẫn em cách tính không ạ?

thay đổi nội dung bởi: namqn, 21-05-2008 lúc 03:26 AM.
mr_riverrain vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 21-05-2008, 11:06 AM   #2
LeDuc
Đệ tử 6 túi
 
LeDuc's Avatar
 
Tham gia ngày: Mar 2007
Bài gửi: 150
:
Trích:
Nguyên văn bởi mr_riverrain View Post
Em đã bới tung cả diễn đàn(chủ yểu là ở "Cơ bản về vi điều khiển và PIC" và " Các ngôn ngữ lập trình khác ") lên để tìm xem có nói về ngắt timer mà sao khó quá. Có chỗ mấy anh hỏi thì lại không có ai trả lời. Đề bài của em là trong CCS C dùng Timer1 tạo ra một thời gian là 1 giây.
Ví dụ:
Code:
#Int_TIMER1
void Time()
{
   bien++;
    if (bien>=40)
      {    Count=get_timer1();
            set_timer1(0);
            St=1;
            bien=0;
       }
}
Em muốn hỏi cách tính làm sao tính ra chính sác 1 giây (tại sao lại là số 40 kia ). Hầu hết các bài hướng dẫn đều hướng dẫn cách tính bằng ASM theo từng lênh.
Có ai có thể hướng dẫn em cách tính không ạ?
Theo mình để dễ dàng thì bạn nên hiểu như thế này , timer 1 la timer 16 bit nghia la no co thể đếm từ 0 đến 65535 . Khi đếm hết nó sẽ quay lại từ đầu là 0 , và lúc đó sẽ xảy ra ngắt .
vd : giả sử cứ 1us timer đế lên 1 , vậy thì khi timer 1 tràn no sẽ đếm được 65535 um =65,535ms=0,065535 s .
Vậy để xác định thời gian ngắt thì chỉ việc xác định timer đếm bao nhiêu thôi đúng ko?
Bây giờ là cách xác định đây .
Thời gian đếm lên của timer phụ thuộc vào chu kỳ lệnh của vi điều khiển . chu kỳ lệnh bằng bao nhiêu thì thời gian định thời của timer củng như vậy . Nếu thạch anh 4M thì chu kỳ lệnh của VDK =1um .
Bậy giờ muốn 1s thì timer ngắt , nghia la sau 10^6 um . timer 1 phải ngắt , nhưng timer1 thì ko thể đếm đến 10^6. vậy ta phai sử dung chế độ prescale 1:8 . nghia la cứ 8 chu kỳ lệnh timer1 mới đếm lên 1 .. ==> 8*65535 = 524280 us .
Code:
#int timer1
  void ngat_timer1()
  {
      set_timer1(24280);   // mặc định giá trị ban đầu cho timer la 24280 . 
      dem++;                 //  timer 1 tràn sau ==> 500 000 us = 0.5s
      if(dem==2)            //  2* 500 000 =1s
          {
            ...................//  thực hiện hành động ;
             dem=0;
           }
   }
void main 
 setup_timer1(T1_INTERNAL|T1_DIV_BY_8); // cho timer 1 chay ở chế độ timer.Bột chia 8
 set_timer1(24280) ;                              // mặc định số đếm ban đầu cho timer1 la 24280.
 enable_interrupts(int_timer1);               // cho phép ngắt timer 1 
 enable_interrupts(global);                   //  cho phép ngắt toàn cục
 while(true)
 {
   .............
  }
__________________
_________________________________________________
Le Trung Duc
Industry Research & Application Center
NTT Institute of Hi_technolog
ltduc@ntt.edu.vn
leduc_cktd@yahoo.com.vn
http://www.nttc.edu.vn
CNC DIY : http://quangcaosanpham.com/shop/driverservo
0909300332
LeDuc vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 21-05-2008, 02:44 PM   #3
doremino
Đệ tử 3 túi
 
Tham gia ngày: Apr 2008
Bài gửi: 48
:
Trích:
Nguyên văn bởi LeDuc View Post
Theo mình để dễ dàng thì bạn nên hiểu như thế này , timer 1 la timer 16 bit nghia la no co thể đếm từ 0 đến 65535 . Khi đếm hết nó sẽ quay lại từ đầu là 0 , và lúc đó sẽ xảy ra ngắt .
vd : giả sử cứ 1us timer đế lên 1 , vậy thì khi timer 1 tràn no sẽ đếm được 65535 um =65,535ms=0,065535 s .
Vậy để xác định thời gian ngắt thì chỉ việc xác định timer đếm bao nhiêu thôi đúng ko?
Bây giờ là cách xác định đây .
Thời gian đếm lên của timer phụ thuộc vào chu kỳ lệnh của vi điều khiển . chu kỳ lệnh bằng bao nhiêu thì thời gian định thời của timer củng như vậy . Nếu thạch anh 4M thì chu kỳ lệnh của VDK =1um .
Bậy giờ muốn 1s thì timer ngắt , nghia la sau 10^6 um . timer 1 phải ngắt , nhưng timer1 thì ko thể đếm đến 10^6. vậy ta phai sử dung chế độ prescale 1:8 . nghia la cứ 8 chu kỳ lệnh timer1 mới đếm lên 1 .. ==> 8*65535 = 524280 us .
Code:
#int timer1
  void ngat_timer1()
  {
      set_timer1(24280);   // mặc định giá trị ban đầu cho timer la 24280 . 
      dem++;                 //  timer 1 tràn sau ==> 500 000 us = 0.5s
      if(dem==2)            //  2* 500 000 =1s
          {
            ...................//  thực hiện hành động ;
             dem=0;
           }
   }
void main 
 setup_timer1(T1_INTERNAL|T1_DIV_BY_8); // cho timer 1 chay ở chế độ timer.Bột chia 8
 set_timer1(24280) ;                              // mặc định số đếm ban đầu cho timer1 la 24280.
 enable_interrupts(int_timer1);               // cho phép ngắt timer 1 
 enable_interrupts(global);                   //  cho phép ngắt toàn cục
 while(true)
 {
   .............
  }
woa!!đúng là đàn anh chỉ dạy rất dễ hiểu !!cảm ơn huynh nhé!!tiếp tục phát huy cho anh em được nhờ nhé!!!
good luck!!!
doremino vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 16-05-2011, 11:39 PM   #4
alycuong
Đệ tử 1 túi
 
Tham gia ngày: Apr 2010
Bài gửi: 16
:
Trích:
Nguyên văn bởi LeDuc View Post
Theo mình để dễ dàng thì bạn nên hiểu như thế này , timer 1 la timer 16 bit nghia la no co thể đếm từ 0 đến 65535 . Khi đếm hết nó sẽ quay lại từ đầu là 0 , và lúc đó sẽ xảy ra ngắt .
vd : giả sử cứ 1us timer đế lên 1 , vậy thì khi timer 1 tràn no sẽ đếm được 65535 um =65,535ms=0,065535 s .
Vậy để xác định thời gian ngắt thì chỉ việc xác định timer đếm bao nhiêu thôi đúng ko?
Bây giờ là cách xác định đây .
Thời gian đếm lên của timer phụ thuộc vào chu kỳ lệnh của vi điều khiển . chu kỳ lệnh bằng bao nhiêu thì thời gian định thời của timer củng như vậy . Nếu thạch anh 4M thì chu kỳ lệnh của VDK =1um .
Bậy giờ muốn 1s thì timer ngắt , nghia la sau 10^6 um . timer 1 phải ngắt , nhưng timer1 thì ko thể đếm đến 10^6. vậy ta phai sử dung chế độ prescale 1:8 . nghia la cứ 8 chu kỳ lệnh timer1 mới đếm lên 1 .. ==> 8*65535 = 524280 us .
Code:
#int timer1
  void ngat_timer1()
  {
      set_timer1(24280);   // mặc định giá trị ban đầu cho timer la 24280 . 
      dem++;                 //  timer 1 tràn sau ==> 500 000 us = 0.5s
      if(dem==2)            //  2* 500 000 =1s
          {
            ...................//  thực hiện hành động ;
             dem=0;
           }
   }
void main 
 setup_timer1(T1_INTERNAL|T1_DIV_BY_8); // cho timer 1 chay ở chế độ timer.Bột chia 8
 set_timer1(24280) ;                              // mặc định số đếm ban đầu cho timer1 la 24280.
 enable_interrupts(int_timer1);               // cho phép ngắt timer 1 
 enable_interrupts(global);                   //  cho phép ngắt toàn cục
 while(true)
 {
   .............
  }
Em thấy chỗ set giá trị cho timer1 sai thì phải, chổ này theo e tính toán thì phải là: set_timer1(3035);

(65535 - 3035)*1us*8 = 500000us
alycuong vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 21-05-2008, 02:48 PM   #5
doremino
Đệ tử 3 túi
 
Tham gia ngày: Apr 2008
Bài gửi: 48
:
tiện đây cho tiểu đệ hỏi một câu về ngắt!!nếu không sử dụng timer để ngắt thì chương trình ngắt còn cách viết nào nửa không? lúc đó làm sao kiểm soát hoạt động của nó?(ý của em là bắt nó làm việc theo ý mình ý mà)
doremino vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-05-2008, 09:00 PM   #6
LeDuc
Đệ tử 6 túi
 
LeDuc's Avatar
 
Tham gia ngày: Mar 2007
Bài gửi: 150
:
Trích:
Nguyên văn bởi doremino View Post
tiện đây cho tiểu đệ hỏi một câu về ngắt!!nếu không sử dụng timer để ngắt thì chương trình ngắt còn cách viết nào nửa không? lúc đó làm sao kiểm soát hoạt động của nó?(ý của em là bắt nó làm việc theo ý mình ý mà)
Nói thật , mình kô hiểu ý bạn muốn hỏi về vấn đề gi ??bạn muốn hỏi về ngắt hay hỏi về timer ...
__________________
_________________________________________________
Le Trung Duc
Industry Research & Application Center
NTT Institute of Hi_technolog
ltduc@ntt.edu.vn
leduc_cktd@yahoo.com.vn
http://www.nttc.edu.vn
CNC DIY : http://quangcaosanpham.com/shop/driverservo
0909300332
LeDuc vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-05-2008, 11:39 PM   #7
doremino
Đệ tử 3 túi
 
Tham gia ngày: Apr 2008
Bài gửi: 48
:
Trích:
Nguyên văn bởi LeDuc View Post
Nói thật , mình kô hiểu ý bạn muốn hỏi về vấn đề gi ??bạn muốn hỏi về ngắt hay hỏi về timer ...
à tại từ trước tới giờ em chỉ biết ngắt timer thôi à!anh có bài tập hay tài liệu về các loại ngắt khác thì cho em tham khảo với!
doremino vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 07-04-2009, 11:41 PM   #8
thaithien
Đệ tử 7 túi
 
Tham gia ngày: Aug 2007
Bài gửi: 213
:
Sao không tiếp tục,đang hấp dẫn mà.MÌnh thấy trong CCS nó xây dựng rất nhiều ngắt nhưng chuă thử hết,ví dụ như ngắt bằng timer như trên,bằng ngắt ngoài,...
thaithien vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 14-04-2009, 11:55 PM   #9
nguyenluong
Đệ tử 2 túi
 
Tham gia ngày: Oct 2008
Bài gửi: 27
:
Bác LE DUC ơi, cho em hỏi về ngắt T0, và T1. Nhưng ngắt T2 thì sao
em khởi tạo như sau:
Timer0:
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2)
setup_timer0(6)
Timer1:
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8)
ca hai thi chay tot, nhưng Timer2 thì pó tay, mỗi Timer co cách khởi tạo khac nhau.
Bác Reply em nhé. Cảm ơn bác nhiều
nguyenluong vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 12-10-2010, 06:58 PM   #10
hcmut.khoamaisi
Đệ tử 4 túi
 
hcmut.khoamaisi's Avatar
 
Tham gia ngày: Dec 2009
Nơi Cư Ngụ: TPHCM
Bài gửi: 79
:
Send a message via Yahoo to hcmut.khoamaisi
Thumbs up

Trích:
Nguyên văn bởi nguyenluong View Post
Bác LE DUC ơi, cho em hỏi về ngắt T0, và T1. Nhưng ngắt T2 thì sao
em khởi tạo như sau:
Timer0:
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2)
setup_timer0(6)
Timer1:
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8)
ca hai thi chay tot, nhưng Timer2 thì pó tay, mỗi Timer co cách khởi tạo khac nhau.
Bác Reply em nhé. Cảm ơn bác nhiều
Nếu bạn cũng khai báo TIMER2 như vậy thì không ra đâu.vì timer2 khia báo hoàn toàn khác với timer0 và 1 cụ thể:
Code:
setup_TIMER2(mode, period, postscale);
set_TIMER2(value);//xác định giá trị đầu(8bit) cho timer2
get_TIMER2();   //trả về trị số nguyên 8 bit
mode gồm:
T2_DISABLE
T2_DIV_BY_1
T2_DIV_BY_4
T2_DIV_BY_16
period :số nguyên tu 0-255
postcale:số nguyên 0-16
hcmut.khoamaisi vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 15-04-2009, 10:17 AM   #11
dspic4011
Đệ tử 4 túi
 
dspic4011's Avatar
 
Tham gia ngày: Jul 2008
Bài gửi: 66
:
Trước hết bạn cho biết là bạn đang dùng pic nào. Trên đây tôi viết cho pic16f887, trong pic này có timer2 là timer 8 bit dùng xung clock từ bộ dao động của pic. Giả xử bạn dùng thạch anh 20M => Fosc = 20, và Fcy = 20/4 = 5M chọn prescale =16 (đây là số lơn nhất) => tần số xung cấp cho timer2 lúc này là 5M/16 = 312.5khz => T = 3.2us. Tức là sau 3.2us thì giá trị của timer2 tăng lên 1. 8 bit =255 giá trị. thời gian timer2 sẽ bị tràn là 3.2 *255 = 816us. con số khá nhỏ bạn nên xem xét vấn đền này. Có thể timer2 của bạn đã hoạt động tốt mà bạn ko biết đó thôi.
__________________
kit phát triển các loại: http://picdevelopmenttool.webs.com/index.htm
Đã có LPC2103 kit, AT91SAM7S KIT và J_link v.7.

thay đổi nội dung bởi: namqn, 16-04-2009 lúc 12:21 AM. Lý do: điều chỉnh thông tin
dspic4011 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 16-04-2009, 12:17 AM   #12
thaithien
Đệ tử 7 túi
 
Tham gia ngày: Aug 2007
Bài gửi: 213
:
Trích:
Nguyên văn bởi dspic4011 View Post
Trước hết bạn cho biết là bạn đang dùng pic nào. Trên đây tôi viết cho pic16f887, trong pic này có timer2 là timer 8 bit dùng xung clock từ bộ dao động của pic. Giả xử bạn dùng thạch anh 20M => Fosc = 20/5 = 5M chọn prescale =16 (đây là số lơn nhất) => tần số xung cấp cho timer2 lúc này là 5M/16 = 312.5khz => T = 3.2us. Tức là sau 3.2us thì giá trị của timer2 tăng lên 1. 8 bit =255 giá trị. thời gian timer2 sẽ bị tràn là 3.2 *255 = 816us. con số khá nhỏ bạn nên xem xét vấn đền này. Có thể timer2 của bạn đã hoạt động tốt mà bạn ko biết đó thôi.
Fosc=20/4=5 :với 4 là chu kỳ để vi điều khiển thực hiện 1 lệnh.dspic4011 sửa lại để cho các bận mới đọc dễ hiểu hơn chứ không thì rắc rối lắm.
thaithien vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-05-2009, 12:13 PM   #13
Hiepnv101
Đệ tử 1 túi
 
Hiepnv101's Avatar
 
Tham gia ngày: Apr 2009
Nơi Cư Ngụ: Viet Nam
Bài gửi: 12
:
Trích:
Nguyên văn bởi mr_riverrain View Post
Em đã bới tung cả diễn đàn(chủ yểu là ở "Cơ bản về vi điều khiển và PIC" và " Các ngôn ngữ lập trình khác ") lên để tìm xem có nói về ngắt timer mà sao khó quá. Có chỗ mấy anh hỏi thì lại không có ai trả lời. Đề bài của em là trong CCS C dùng Timer1 tạo ra một thời gian là 1 giây.
Ví dụ:
Code:
#Int_TIMER1
void Time()
{
   bien++;
    if (bien>=40)
      {    Count=get_timer1();
            set_timer1(0);
            St=1;
            bien=0;
       }
}
Em muốn hỏi cách tính làm sao tính ra chính sác 1 giây (tại sao lại là số 40 kia ). Hầu hết các bài hướng dẫn đều hướng dẫn cách tính bằng ASM theo từng lênh.
Có ai có thể hướng dẫn em cách tính không ạ?
Đây có thể là cái bạn cần
Hình Kèm Theo
File Type: jpg Timer interrupt.JPG (48.4 KB, 100 lần tải)
Hiepnv101 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-05-2009, 01:30 PM   #14
lequocbao
Đệ tử 6 túi
 
lequocbao's Avatar
 
Tham gia ngày: Oct 2008
Nơi Cư Ngụ: HCM
Bài gửi: 137
:
Hỏi cách thiết lập timer1 là counter đếm xung ngoài!?

#int_timer1
void timer1_ext_isr(void)
{
count++;
rpm++;
}

void main()
{
set_tris_a(0x00);
set_tris_b(0x01);
set_tris_c(0x8f);
set_tris_e(0xff);
set_tris_d(0x00);

set_timer1(65335);//200xung=65535-65335
setup_timer_1(T1_EXTERNAL);
enable_interrupts(int_timer1);
ENABLE_INTERRUPTS(GLOBAL);

count=0;
rpm=0;
while(TRUE)
{
led_scan(count/100,led5);
led_scan((count/10)%10,led6);
led_scan(count%10,led7);

led_scan(rpm/1000,led1);
led_scan((rpm/100)%10,led2);
led_scan((rpm%100)/10,led3);
led_scan((rpm%100)%10,led4);
}
}


Encoder nối RC0 :200xung/vòng nhưng sao mình thấy động cơ quay cả chục vòng thì 2 biến count,rpm mới tăng lên 1 đơn vị.Có bác nào biết tại sao không?
lequocbao vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-05-2009, 03:08 PM   #15
hopeman
Đệ tử 6 túi
 
hopeman's Avatar
 
Tham gia ngày: Jul 2007
Bài gửi: 146
:
Trích:
Nguyên văn bởi lequocbao View Post
#int_timer1
void timer1_ext_isr(void)
{
count++;
rpm++;
}

void main()
{
set_tris_a(0x00);
set_tris_b(0x01);
set_tris_c(0x8f);
set_tris_e(0xff);
set_tris_d(0x00);

set_timer1(65335);//200xung=65535-65335
setup_timer_1(T1_EXTERNAL);
enable_interrupts(int_timer1);
ENABLE_INTERRUPTS(GLOBAL);

count=0;
rpm=0;
while(TRUE)
{
led_scan(count/100,led5);
led_scan((count/10)%10,led6);
led_scan(count%10,led7);

led_scan(rpm/1000,led1);
led_scan((rpm/100)%10,led2);
led_scan((rpm%100)/10,led3);
led_scan((rpm%100)%10,led4);
}
}


Encoder nối RC0 :200xung/vòng nhưng sao mình thấy động cơ quay cả chục vòng thì 2 biến count,rpm mới tăng lên 1 đơn vị.Có bác nào biết tại sao không?
Bạn có thể cho biết bạn dùng loại Encoder nào ko? có một số em encoder bạn phải dùng trở kéo ở mức 1 (5V) . bạn có thể thử đo lại xem em của bạn có thể tự lên mức 1 được chưa?
__________________
mạch nạp - kit phát triển - linh kiện điện tử www.PNLabvn.com
hopeman vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


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à 03:45 AM.


Đượ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