Hỏi về ngắt timer1

Collapse
X
 
  • Giờ
  • Show
Clear All
new posts
  • mr_riverrain
    Nhập môn đệ tử
    • Jul 2007
    • 8

    #1

    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 ạ?
    Last edited by namqn; 21-05-2008, 02:26 AM.
  • LeDuc
    Đệ tử 6 túi
    • Mar 2007
    • 150

    #2
    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

    Comment

    • doremino
      Đệ tử 3 túi
      • Apr 2008
      • 48

      #3
      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!!!

      Comment

      • doremino
        Đệ tử 3 túi
        • Apr 2008
        • 48

        #4
        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à)

        Comment

        • LeDuc
          Đệ tử 6 túi
          • Mar 2007
          • 150

          #5
          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

          Comment

          • doremino
            Đệ tử 3 túi
            • Apr 2008
            • 48

            #6
            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!

            Comment

            • thaithien
              Đệ tử 7 túi
              • Aug 2007
              • 211

              #7
              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,...

              Comment

              • nguyenluong
                Đệ tử 2 túi
                • Oct 2008
                • 27

                #8
                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

                Comment

                • dspic4011
                  Đệ tử 4 túi
                  • Jul 2008
                  • 66

                  #9
                  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.
                  Last edited by namqn; 15-04-2009, 11:21 PM. Lý do: điều chỉnh thông tin
                  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.

                  Comment

                  • thaithien
                    Đệ tử 7 túi
                    • Aug 2007
                    • 211

                    #10
                    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.

                    Comment

                    • Hiepnv101
                      Đệ tử 1 túi
                      • Apr 2009
                      • 12

                      #11
                      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
                      Attached Files

                      Comment

                      • lequocbao
                        Đệ tử 6 túi
                        • Oct 2008
                        • 137

                        #12
                        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?
                        A&A

                        Comment

                        • hopeman
                          Đệ tử 6 túi
                          • Jul 2007
                          • 144

                          #13
                          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

                          Comment

                          • lequocbao
                            Đệ tử 6 túi
                            • Oct 2008
                            • 137

                            #14
                            mình dùng encoder 4 dây ra ,vcc,mass và chA,chB.
                            Cái đó thì yên tâm vì mình đã thử với ngắt ngoài RB0 rồi, 77a đọc rất tốt chỉ có tội là khi tăng tốc độ động cơ lên thì đọc sai kết quả.
                            Last edited by lequocbao; 10-05-2009, 04:01 PM.
                            A&A

                            Comment

                            • fcvanbachc1
                              Nhập môn đệ tử
                              • Mar 2009
                              • 1

                              #15
                              em mới vào nghề,có bài sau muốn hỏi.em đang đọc về ngắt của con dspic,thử lập trình ngắt cho nháy đèn led từ 0-9 cho nó.chương trình của em gặp vấn đề thì phải,vì khi em thay đổi giá trị của PR1 thì thời gian nháy vẫn thế.nó vẫn nháy loạn lên.vậy mong các anh sửa giúp em với,và tư vấn cho em chút it về ngắt,khi nào dùng ngắt trong,khi nào dùng ngắt ngoài.sau đây là đoạn chương trình của em viết cho C30:
                              #define __dsPIC33FJ12MC202__
                              #include <p33fj12mc202.h>
                              int led[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6 7};
                              int i;
                              void _ISR _T1Interrupt(void)
                              {
                              _T1IF = 0;
                              }
                              main()
                              {
                              TMR1=0;
                              PR1=0x2625A; //cho phep ngat sau 1 giay
                              T1CON=0x8030; //chon ti le dem trc la 256
                              _T1IF=0; //xoa co ngat TMR1
                              _T1IE=1; //cho phep ngat
                              TRISB=0xff00;
                              while(1)
                              {
                              for (i=0;i<10;i++)
                              {
                              PORTB=led[i];
                              }
                              }
                              }

                              Comment

                              Working...