Thông báo

Collapse
No announcement yet.

Timer/Counter

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Timer/Counter

    Cấu trúc bên trong của bộ định thời
    Attached Files
    Càng biết nhiều càng thấy mình biết ít.

  • #2
    Thanh ghi TCON và TMOD

    Thanh ghi SFR : TCON và TMOD
    Attached Files
    Càng biết nhiều càng thấy mình biết ít.

    Comment


    • #3
      Re: Timer/Counter

      Nguyên văn bởi ATYLA
      Cấu trúc bên trong của bộ định thời
      bác có thể nói rõ hơn được không vậy.
      "ta la mot hat bui tren xa mac bao la"

      Comment


      • #4
        Thanhghi TMOD

        Bit Gate : Khi bit này đựoc set (logic "1"), timer được điều khiển bởi ngắt ngoài INT1 đối với timer1 và INT0 đối với timer0.
        Bộ định thời sẽ được khởi động khi chân vào INT1 hoặc INT0 ở mức cao và dừng khi chúng ở mức thấp.
        Khi bit Gate là "0", bộ đếm sẽ được khởi động độc lập so với các chân này. Việc khởi động và dừng bộ định thời thực hiện bằng phần mềm.

        Bit C/T : bit này dùng để lựa chọn xung clock là internal ( của thạch anh) hay là clock tù bên ngoài ở chân T1 (timer1) hoặc T0 (timer0).
        Tóm lại bit này quyết định là bộ định thời được sử dụng ở chế độ timer, tạo trễ thời gian hay là dùng ở chế độ counter, đếm sự kiện


        M1,M0 : dùng để lựa chọn chế độ hoạt động của timer

        M1 M0 Chế độ hoạt động

        0 0 Mode0: 13 bit timer
        0 1 Mode1: 16 bit timer
        1 0 Mode2 : 8 bit tự động nạp lại
        1 1 Mode3: timer riêng lẻ


        * Ví dụ minh hoạ :

        a) TMOD = 0000 0001 -->Chế độ 1 của bộ định thời timer0 được chọn

        b) TMOD = 0010 0000-->Chế độ 1 của bộ định thời timer1 được chọn

        c) TMOD = 0001 0010-->Chế độ 1 của bộ định thời timer0 và
        timer1 được chọn



        * Như chúng ta đã biết mỗi bộ định thời cần 1 xung đồng hồ để giữ nhịp. Nếu C/T=0, tần số thạch anh đi liền với 8051 được sử dụng làm nguồn xung clock cho bộ định thời, tần số của bộ định thời luôn bằng 1/12 tần số thạch anh.(Xem hình minh hoạ cấu trúc)
        Vì thế tần số thạch anh quyết định tốc độ nhịp của bộ định thời.
        Thạch anh 12 Mhz--> Khi viết chương trình tạo trễ thời gian, mỗi bước tăng của bộ định thời là (1/12)*12 Mhz=1 Mhz-->T=1 us.

        Thạch anh 11.059 Mhz-->(1/12)*11.059 Mhz=921.6 Khz--->T=1.085 us
        Càng biết nhiều càng thấy mình biết ít.

        Comment


        • #5
          Thanh ghi TCON

          Bit TF1 : Cờ tràn của của timer1, bit này chuyển lên 1 khi bộ định thời bị tràn FF->00.

          Bit TR1 : Khi bit này được set lên 1, bộ định thời (timer1) được khởi động. TR1=0, dừng bộ định thời.

          Bit TF0 và TR0 tương tự như đối với timer 1. Các bit này dùng cho timer0

          IE1
          : Cờ ngắt ngoài theo sườn xung. Nó được thiết lập bởi CPU khi sườn ngắt ngoài chuyển từ cao xuống thấp.Nó được xoá bởi CPU khi ngắt được xử lí.
          Bit IT1 : Bit điều khiển ngắt, nó được set bằng phần mềm để lựa chọn ngắt theo sườn xung hay theo mức.

          IE0 và IT0 tương tự IE1 và IT1.--> dùng cho timer0
          Càng biết nhiều càng thấy mình biết ít.

          Comment


          • #6
            để tham khảo thêm về bộ timer /counter bác có thể tham khảo thêm về
            cuốn vdk 8051 của tống văn on
            đây là đoạn code ve counter để bác tham khảo
            void timer0(void) interrupt 0
            {
            P1_0=1; // led
            }

            void main()
            {
            P1_0=0; // led
            TMOD =0x55 ; // khoi dong bo dem su kien
            TH0= 0xfe;
            TL0= 0x0b;
            TR0=1; // khoi dong bo timer
            while (1) {}
            }
            day la doan code dung bo dem su kien , chan T0 cua vdk noi voi chan tin hieu
            cua mot bo encoder , vdk dem du 500 xung thi xuat tin hieu ra P1_0 ( ngat) led sang .
            SHARE KHO PHIM LỚN

            Comment


            • #7
              Counter

              Thanh ghi TMOD :
              Bit 7 6 5 4 3 2 1 0
              name GATE C/T M1 M0 GATE C/T M1 M0
              ---
              M1 , M0 tại bit 1 , 0 là chế độ của bộ định thời 0
              M1 , M0 tại bit 5 , 4 là chế độ định thời 1
              -- Bit 6 là C/T ( chọn chế độ timer hay counter của bộ định thời 1 )
              C/T = 1 là đếm sự kiện ( counter)
              -- Bit 2 là C/T của bộ định thời 0.

              +++ để khởi động bộ định thời : Nhìn bảng trên --->
              giả dụ bạn nghĩ cần khởi động bộ định thời như sau :
              GATE = 1 C/T = 1..... tương ứng các bit sau : 11000000 ( 8 bit )
              ___________
              Viết trong C : TMOD = 11000000b ;
              hoặc TMOD = 0xC0 ; Tất nhiên đây là ví dụ truy cập để khởi động , khi thực tế bạn xem cấu trúc ( nhìn hình bài viết trên ) sẽ xác định được cái nào cần là 1 hay là 0 ( 1 tương đương với đóng , và 0 tương đương với mở.
              Module RF chuyên dụng điều khiển, truyền dữ liệu, thiết kế đề tài, dự án điện tử - chuyển giao công nghệ... ĐT: 0904964977 - email: dientuqueduong@yahoo.com

              Comment


              • #8
                Cái khó và quan trọng nhất của vi điều khiển là ngắt sự kiện, định thời và đếm...
                ----------
                --- Các bác cho biết cách kiểm tra và xuất ra port thế nào với timer vậy ???
                Không biết tôi viết thế này đúng chưa :
                void main()
                {
                Khởi động định thời }
                while (!TF0) // kiểm tra
                {
                P1_1 =1; // đưa P1.1 lên cao
                TF0 = 0; // xóa cờ tràn
                }

                hoặc thế này :
                while (1)
                {
                if (TF0 ==1)
                {
                P1_1 =1;
                TF0 =0 ;
                }
                else { P1_1 =0;}
                ///////////////////////////////////////
                + Tôi làm thí nghiệm viết 1 chương trình cho output led tại chân P1.1
                ( led nhấp nháy 3 lần 1 giây ) 3 Hz
                nhưng thời gian trễ này quá dài , không biết áp dụng cách nào ???
                Chẳng lẽ sử dụng 2 timer liền để nối tiếp nhau ???
                Giá trị của timer trước nạp cho timer sau ???
                --- Tôi biết là xung timer 1MHz ( thạch anh 12MHz) thì có cái công thức tính , công thức tính này thế nào vậy ???
                --- Bác nào làm ơn giúp tôi cái bài led nhấp nháy này ...
                Module RF chuyên dụng điều khiển, truyền dữ liệu, thiết kế đề tài, dự án điện tử - chuyển giao công nghệ... ĐT: 0904964977 - email: dientuqueduong@yahoo.com

                Comment


                • #9
                  Nguyên văn bởi queduong
                  Cái khó và quan trọng nhất của vi điều khiển là ngắt sự kiện, định thời và đếm...
                  ----------
                  --- Các bác cho biết cách kiểm tra và xuất ra port thế nào với timer vậy ???
                  Không biết tôi viết thế này đúng chưa :
                  void main()
                  {
                  Khởi động định thời }
                  while (!TF0) // kiểm tra
                  {
                  P1_1 =1; // đưa P1.1 lên cao
                  TF0 = 0; // xóa cờ tràn
                  }

                  hoặc thế này :
                  while (1)
                  {
                  if (TF0 ==1)
                  {
                  P1_1 =1;
                  TF0 =0 ;
                  }
                  else { P1_1 =0;}
                  ///////////////////////////////////////
                  + Tôi làm thí nghiệm viết 1 chương trình cho output led tại chân P1.1
                  ( led nhấp nháy 3 lần 1 giây ) 3 Hz
                  nhưng thời gian trễ này quá dài , không biết áp dụng cách nào ???
                  Chẳng lẽ sử dụng 2 timer liền để nối tiếp nhau ???
                  Giá trị của timer trước nạp cho timer sau ???
                  --- Tôi biết là xung timer 1MHz ( thạch anh 12MHz) thì có cái công thức tính , công thức tính này thế nào vậy ???
                  --- Bác nào làm ơn giúp tôi cái bài led nhấp nháy này ...
                  Cao nhân rf bây giờ lại mày mò vđk rồi đây! Anh em trên diễn đàn vẫn đang rất muốn chiêm ngưỡng các bài viết rf của bác.

                  Về chuyện timer thì bác trễ bao nhiêu chẳng được, bác thêm biến về số lần tràn timer là OK. Ví dụ:
                  main()
                  {
                  while(1)
                  {
                  if(TF0)
                  {
                  TF0=0;
                  //Nạp giá trị timer cho thanh ghi định thời TH0 và TL0
                  if(i++==N)
                  {
                  P1_1=!(P1_1);
                  i=0;
                  }
                  }
                  }
                  }
                  Tuy nhiên dùng ngắt là tối ưu nhất.
                  Bác cho N lớn thì có thể tạo tần số thấp thoải mái.
                  Còn clock của timer sẽ = tần số thạch anh/12;
                  Timer = clock timer*giá trị nạp. Giá trị nạp thực vào TH0 và TL0 =65536-giá trị nạp.
                  Tức là Th0=bytehigh(65536-giá trị nạp);
                  Tl0=bytelow(65536-giá trị nạp);

                  Comment


                  • #10
                    Trễ thời gian

                    Bộ định thời hoạt động ở chế độ 1, 16 bit giá trị tối đa là 65535 (tức 2 mũ 16)

                    Với thạch anh 12 MHZ, tần số xung đầu vào bộ định thời bằng tần số thạch anh chia 12. (1/12 )*12 MHZ =1 MhZ---> Bộ định thời sẽ đếm xung clock nguồn từ thạch anh cho hoạt động định thời, bước đếm là 1 us ( với tần số 1 MHZ).

                    Như vậy với giá trị tối đa 65535 (FFFFh) thì nếu không sử dụng thêm các vòng lặp ta chỉ có thể tạo chương trình trễ tối đa là 65535 us ( tức là hơn 65 ms).


                    Bộ định thời sẽ đếm lên bắt đầu từ giá trị nạp cho thanh ghi THx và Tlx. (x=0,1) cho đến khi tràn

                    Ví dụ để tạo chương trình trễ là 100 us giá trị cần nạp cho bộ định thời là :

                    65535-100=65435 --> đổi sang hexa (dùng calculator của Windows mà đổi) là FF9Bh
                    Như vậy giá trị cần nạp cho THx là FFh, cho TLx là 9Bh.

                    Đoạn chương trình con viết bằng C như sau:

                    void delay(void)
                    {
                    TMOD=0x01; //(timer0, chế độ 1, định thời 16 bit)
                    TH0=0x0FF;
                    TL0=0x9C;
                    TR0=1; // Khởi động timer
                    while(!TF0);
                    TR0=0; // Dừng bộ định thời
                    TF0=0; // xóa cờ tràn
                    }

                    Ví dụ khác : tạo trễ 50 ms= 50.000 us

                    Giá trị nạp cho bộ định thời là 65535-50000=15535 đổi sang hexa là
                    3CAFh

                    Như vậy giá trị nạp cho Thx là 3Ch, cho TLx là AFh


                    Để tạo thời gian trễ lớn hơn sử dụng thêm các vòng lặp For, Do While ..


                    Chẳng hạn bây giờ dựa trên chương trình con tạo trễ 50ms ta viết 1 chương trình tạo trễ lớn hơn 65 ms

                    void delay50(unsigned char n)
                    {
                    unsigned char i;
                    for(i=0;i<n;i++)
                    {
                    TMOD=0x01;
                    TH0=0x3C;
                    TL0=0xAF;
                    TR0=1;
                    While(!TF0);
                    TR0=0;
                    TF0=0;
                    }


                    Trong chương trình chính nếu ta làm 1 ví dụ đơn giản là nhấp nháy LED thì viết như sau :

                    void main()

                    {

                    while(1)
                    {
                    P1.0=1;
                    delay50(100); // tre 5 s
                    P1.0=0;
                    delay50(100);
                    }


                    }
                    Càng biết nhiều càng thấy mình biết ít.

                    Comment


                    • #11
                      Tuyệt !!!
                      Tôi làm được rồi , tuy đo tần số nó không chính xác là 3 HZ nhưng cũng tầm tầm đó, ít ra thì cái led cũng nhấp nháy được.
                      -- Nghe chừng học C dễ hơn ASM nhỉ .
                      Thế là chỉ trong có 2 ngày đọc cái counter/TIMER của bác ATYLA tôi đã nắm được cách viết này trong C ( mặc dù 2 ngày trước tôi chẳng biết một tẹo gì về C cả ).
                      hè hè , bây giờ tôi đã lập trình được gần như hầu hết các chức năng của IC số bằng con 89C51 roài.
                      Bác nào nhã ý giới thiệu nốt cái UART truyền 232 , khởi tạo baud , truyền , kiểm tra là ổn há.

                      + Chia sẻ một chút kinh nghiệm của tôi ( 1 tuần học được khá khá vi điều khiển 8051 sử dụng C .
                      1) Mua 1 con AT89C2051 về , làm cái mạch phát triển development board để thí nghiệm ( học phải đi đôi với hành ).
                      + Gắn các led vào các đầu I/O của 89C2051 và bắt đầu làm thí nghiệm.
                      a) Viết chương trình cho tất cả các led ở một port sáng lên ( set bit =1) --- Tôi sử dụng RAISONANCE - RIDE
                      #include <reg51.h>
                      void main()
                      { P3 = 0x7F ; }

                      hoặc P3 = 127 ;
                      chú ý : một số chương trình như Keil có định địa chỉ trực tiếp nên nếu bạn viết P3 = 1; thì các led của P3 sẽ sáng lên, riêng RIDE không có định địa chỉ bit trực tiếp nên nếu viết P3 = 1; trong trường hợp này chỉ có led ở chân P3.0 sáng.
                      - trong trường hợp cụ thể nếu P3 được gán cho một biến số nào đó , dạng byte thì P3 = a ( a kiểu byte) thì cả port 3 này sẽ đồng loạt sáng hay tắt.
                      Vì các câu lệnh gộp của RIDE làm chương trình dịch ra rất nhỏ đó là 1 thế mạnh.
                      b) Câu lệnh kiểm tra input , out put :
                      ( trong trường hợp cần kiểm tra sự kiện , xung , logic tại một đầu vào sau đó xuất kết quả ra một chân khác ta phải dùng cái này .
                      ( hiểu được cái này là làm được rất nhiều chức năng logic...)
                      #include <reg51.h>
                      void main()
                      {
                      while (1) // vòng lặp vô hạn
                      if ((P1&2)) //kiểm tra mức logic cao tại chân P1.1
                      { P3 = 1;} // nếu chân P1.1 có mức cao thì chân P3.0 có mức cao --LED sáng
                      }
                      +++++
                      c) các lệnh về timer/ counter ( Như bài biết của các bác ATYLA , giaosucan đã viết ở trên.

                      ( Qua 3 bước này , nắm vững là làm được nhiều việc rồi đó.)
                      --- Có điều kiện Quế Dương sẽ post các bài lập trình của mình lên.
                      Vạn sự khởi đầu nan , QD có thể học C - 8051 chỉ trong 1 tháng , bạn có thể học trong 1 năm , 2 năm... đó là cách tiếp nhận của mỗi người nhưng nếu bạn chia sẻ các vướng mắc của mình mọi người sẽ giúp đỡ.
                      --- Mong các bạn chỉ giáo.
                      Module RF chuyên dụng điều khiển, truyền dữ liệu, thiết kế đề tài, dự án điện tử - chuyển giao công nghệ... ĐT: 0904964977 - email: dientuqueduong@yahoo.com

                      Comment


                      • #12
                        Tui có 1 ý kiến thê này:
                        Bác QD làm được cái phần nào thì post lên luôn, cho những người đi sau học hỏi. Có sơ đồ nguyên lý hay cái ảnh chụp = wedcam cũng được. Trong quá trình nếu bí chỗ nào, hoặc chỗ nào ko chạy thì chúng ta cùng gỡ cho bác QD.

                        Comment


                        • #13
                          em cũng đã từng định thời bằng timer rồi , em thấy dùng ngay mode0, chế độ 8bit auto reload ấy, chỉ cần quy định số lần tràn phù hợp là có thể định thời thoải mái. mà việc nạp giá trị cho TLx hoàn toàn tự động khỏi phải set lai bằng vòng lặplên khá đơn giản.
                          thứ gì không mua được bằng tiền sẽ mua được bằng rất nhiều tiền!!

                          Comment


                          • #14
                            8051's TIMERs

                            Chế độ 8bit Auto-Reload không phải là chế độ 0 mà là chế độ 2. Nếu dùng mode này để làm trễ thì đúng là được cái nhàn nhờ việc reload cho timer được thực hiện tự động. Tuy nhiên nếu thời gian trễ là lớn thì lượng biến đếm phải dùng rất lớn vì khoảng thời gian giữa các lần tràn chỉ tối đa là 256us. Lượng biến đếm lớn thì thao tác kiểm soát giá trị đếm (gán, tăng, giảm...) cũng phức tạp lên. Hơn nữa dù có auto-reload thì vẫn phải dùng đến ngắt để kiểm soát biến đếm. Vậy thì tiếc chi hai cái lệnh reload bằng tay?
                            Mọi người bàn về timer với các chế độ khác nhau, nhưng hình như mới chỉ chú ý đến ứng dụng đếm thời gian chứ chưa để ý đến ứng dụng đếm sự kiện ngoài. Khi dùng để đếm sự kiện ngoài (C/T = 1) thì không phải chế độ nào cũng dùng được. Xin bổ sung là ở chế độ 3 (M0 = M1 = 1), timer0 được tách thành 2 timer 8bit riêng rẽ là TL0 và TH0, tuy nhiên chỉ có TL0 là có thể dùng như timer/counter, còn TH0 chỉ có thể dùng là timer. Ngoài ra trong chế độ này, timer/counter TL0 sẽ bị chi phối bởi các bit dành cho timer0 trong TMOD, còn timer TH0 lại bị chi phối bởi các bit dành cho timer1 trong TMOD. Timer1 không chạy trong chế độ này.

                            Comment


                            • #15
                              Re: 8051's TIMERs

                              Nguyên văn bởi blackmoon
                              Mọi người bàn về timer với các chế độ khác nhau, nhưng hình như mới chỉ chú ý đến ứng dụng đếm thời gian chứ chưa để ý đến ứng dụng đếm sự kiện ngoài. Khi dùng để đếm sự kiện ngoài (C/T = 1) thì không phải chế độ nào cũng dùng được. Xin bổ sung là ở chế độ 3 (M0 = M1 = 1), timer0 được tách thành 2 timer 8bit riêng rẽ là TL0 và TH0, tuy nhiên chỉ có TL0 là có thể dùng như timer/counter, còn TH0 chỉ có thể dùng là timer. Ngoài ra trong chế độ này, timer/counter TL0 sẽ bị chi phối bởi các bit dành cho timer0 trong TMOD, còn timer TH0 lại bị chi phối bởi các bit dành cho timer1 trong TMOD. Timer1 không chạy trong chế độ này.
                              Đúng vậy, đi khắp các diễn đàn, chỉ nghe đếm thời gian, nhưng em ko nghe thấy dùng con 89 đếm sự kiện. Em liền mở datasheet ra, thì thấy mình chưa làm tơi phần nàythế này,
                              Nếu có ai muốn tìm hiểu cùng thì có link sau:
                              http://www.atmel.com/dyn/resources/prod_documents/DOC4316.PDF
                              Nói cặn cẽ cấu trúc của timer của 8951
                              -------------------

                              Comment

                              Về tác giả

                              Collapse

                              ATYLA Tìm hiểu thêm về ATYLA

                              Bài viết mới nhất

                              Collapse

                              Đang tải...
                              X