ĐO TẦN SỐ XUNG VUÔNG VỚI 89s52....!

Thảo luận trong '8051' bắt đầu bởi sinhviencabiet, 28 Tháng mười 2012.

Users Viewing Thread (Users: 0, Guests: 0)

  1. sinhviencabiet

    sinhviencabiet New Member

    Tiền:
    $3,544
    Xin chào các bạn!
    Hôm nay, mình xin chia sẻ phương pháp đo tần số của tín hiệu sử dụng vi điều khiển Đăng ký hoặc đăng nhập để thấy Link -  Ủng hộ bài viết bằng nút " Thích", tần số được hiển thị lên Đăng ký hoặc đăng nhập để thấy Link -  Ủng hộ bài viết bằng nút " Thích".
    Thuật toán: tần số của tín hiệu cần đo là số lần thay đổi mức tín hiệu từ 1 xuống 0 trong khoảng thời gian 1s.
    Ý tưởng : Sử dụng 2 bộ timers của 89s52 là TIMER0 và TIMER1:
    -TIMER 0: được sử dụng như bộ định thời để tạo khoảng thời gian 1s.
    - TIMER 1: được sử dụng như bộ đếm sự kiện, khi có sự thay đổi của tín hiệu trên chân T1(P3.5), bộ đếm của TIMER1 sẽ tăng 1 đơn vị.
    Vậy giá trị thanh ghi đếm của TIMER1 trong 1s đúng bằng tần số tín hiệu đưa vào vi điều khiển. Các bạn chỉ cần đọc giá trị ra và cho hiển thị lên LCD1602.
    Code Test:
    HTML:
    /**********DO TAN SO TIN HIEU CAO TU NGOAI VAO HIEN THI LEN LCD*********/
    /**********SU DUNG TIMER0 DINH THOI 1S VA TIMER 1 DE DEM SO XUNG TIN HIEU*************/
    #include <main.h>
    #include <var.h>
     
    void ngat_trantimer0() interrupt 1
    {
        TH0=0xFC;
        TL0=0x2B;
        Time++;
        if(Time==1000)                     
        {
            Time=0;                                          // dinh thoi 1s
            TR1=0;
            tanso=(((TH1&0x00ff)<<8)|(TL1&0x00ff));          //tan so bang so xung dem duoc trong 1s
            TH1=0;
            TL1=0;
            TR1=1;
        }
        TF0=0;
    }
     
    void main()
    {
        char LCD_Buff[25];
        TMOD=0x51;
        IE=0x82;                                          //thiet lap ngat timer 0
        TR0=1;
        LCD_Init();
        LCD_gotoxy(0,0);
        LCD_puts("  MINHHAGROUP");
        LCD_gotoxy(0,1);
        LCD_puts("BANLINHKIEN.VN");
        delay_ms(2500);
        LCD_Clear();
        LCD_gotoxy(0,0);
        LCD_puts("TAN SO TIN HIEU:");
        while(1)
        {
            sprintf(LCD_Buff,"  F= %uHz",tanso);
            LCD_gotoxy(0,1);
            LCD_puts(LCD_Buff);
     
        }
    }
    Mình sẽ sử dụng phương pháp này để xử lý cảm biến màu Đăng ký hoặc đăng nhập để thấy Link -  Ủng hộ bài viết bằng nút " Thích" trong bài sau…^^!
    Video Demo:



    Các bạn có thể tham khảo code mẫu tại đây:

    Các file đính kèm:

    CHỦ ĐỀ NGẪU NHIÊN CÙNG CHUYÊN MỤC
    CHIA SẺ Share





    tung.lvan thích bài này.
  2. tung.lvan

    tung.lvan Nhóm MCU

    Tiền:
    $21,614
    Cho video lên đi em!
    Thú vị đấy!
  3. quang.dt7bk

    quang.dt7bk Nhóm MCU

    Tiền:
    $143,877
    Đây là cách để đo các tín hiệu có tần số cao (tần số tối đa của cách làm này nhớ không lầm khoảng 500KHz). Đối với tín hiệu có f thấp thì có thể dùng 1 bộ TIMER cùng 1 ngắt ngoài để đo...
  4. sinhviencabiet

    sinhviencabiet New Member

    Tiền:
    $3,544
    minh cũng đã dùng 1 timer và 1 ngat ngoài để đo tần số thấp nhưng khi test thử thì sai số còn hơi lớn ,mình đang sửa lai code ,khi nào hoàn chỉnh mình sẽ post để mọi người cùng tham khảo ^^!
  5. NguyenQuyNhat

    NguyenQuyNhat Admin

    Tiền:
    $121,181
    Theo mình thì bạn nên dùng 2 bộ timer khi muốn đo tần số cao, yêu cầu độ chính xác cao. :)
  6. tungbk208

    tungbk208 New Member

    Tiền:
    $4
    mình cũng đã dùng máy phát xung chuẩn để test thử code này nhưng sao sai số nhiều lắm. Mà trong video demo của bạn thì lại chính xác, thế là sao nhỉ. bạn giải thích hộ mình với!
  7. tungbk208

    tungbk208 New Member

    Tiền:
    $4
    mình cũng đã dùng máy phát xung chuẩn để test thử code này nhưng sao sai số nhiều lắm. Mà trong video demo của bạn thì lại chính xác, thế là sao nhỉ. bạn giải thích hộ mình với!
  8. Dukebk.dt7

    Dukebk.dt7 Member

    Tiền:
    $4,315
    Hi Bạn.
    Nếu mà sai số quá nhiều thì bạn nên xem lại tần số thạch anh mà bạn sử dụng. Ở đây dùng thạch anh 11,0592Mhz nhá. Nếu bạn dùng thạch anh tần số khác thì bạn tính lại giá trị nạp vào cho các timer.
    Chúc bạn thành công!
  9. quang.dt7bk

    quang.dt7bk Nhóm MCU

    Tiền:
    $143,877
    Chào bạn!
    Trong chương trình trên, các bạn đã đếm số xung tín hiệu trong thời gian 1s (cũng chính là tần số của tín hiệu), cách làm này đúng nhưng sẽ có sai số do thời gian lấy mẫu 1s là lớn, có thể khắc phục sai số này bằng cách giảm thời gian lấy mẫu xuống, giả sử chỉ cần đếm số xung tín hiệu trong khoảng thời gian 100ms sau đó lấy kết quả nhân với 10 là ra được tần số. Thời gian lấy mẫu càng nhỏ thì độ chính xác càng cao, tuy nhiên không được lấy nhỏ quá nhé vì như vậy sẽ tốn thời gian thực thi của vi điều khiển.
    Chúc bạn thành công!:)
  10. quang.dt7bk

    quang.dt7bk Nhóm MCU

    Tiền:
    $143,877
    Chào bạn!
    Trong chương trình trên, các bạn đã đếm số xung tín hiệu trong thời gian 1s (cũng chính là tần số của tín hiệu), cách làm này đúng nhưng sẽ có sai số do thời gian lấy mẫu 1s là lớn, có thể khắc phục sai số này bằng cách giảm thời gian lấy mẫu xuống, giả sử chỉ cần đếm số xung tín hiệu trong khoảng thời gian 100ms sau đó lấy kết quả nhân với 10 là ra được tần số. Thời gian lấy mẫu càng nhỏ thì độ chính xác càng cao, tuy nhiên không được lấy nhỏ quá nhé vì như vậy sẽ tốn thời gian thực thi của vi điều khiển.
    Chúc bạn thành công!:)
  11. tungbk208

    tungbk208 New Member

    Tiền:
    $4
    tần số thạch anh mình cũng dùng 11,0592Mhz mà. Nhưng đây là đếm xung ngoài nên mình nghĩ tần số thạch anh không ảnh hưởng gì.
  12. tungbk208

    tungbk208 New Member

    Tiền:
    $4
    nhưng mình muốn hỏi sao bạn cũng dùng phát xung chuẩn mà ra chính xác mà mình cũng dùng code đó mà sai số lớn thế hả bạn
  13. Dukebk.dt7

    Dukebk.dt7 Member

    Tiền:
    $4,315
    Ở đây dùng tần số thạch anh để định thời (tạo bộ thời gian chuẩn) từ đó đếm số xung trong 1s, nên nó có ảnh hưởng tới kết quả chứ.
  14. an.dxuan

    an.dxuan Nhóm MCU

    Tiền:
    $2,302
    Chào bạn ! Bạn có thể cho mình biết bạn test với tần số bao nhiêu và sai số bao nhiêu được không .Thuật toán này của mình không dùng để đo tần số cao ,mình cũng đã test với tần số cao và thấy sai số cũng không nhỏ .
  15. nvhuy

    nvhuy New Member

    Tiền:
    $26
    bạn ơi giải thích giùm mình tại sao TL0=0x2b =43,TH0=0xfc =252 trong void ngat_trantimer0() interrupt 1 mà định thời gian được 1s ko ? xin cảm ơn.mình mới học về vi điều khiển nên chưa rành lắm, có gì xin thông cảm nhé. hihii
  16. wata1105

    wata1105 New Member

    Tiền:
    $1,949

    Ở đây dùng biến Time để đếm số lần Timer0 tràn . Chu kì tràn timer0 là 0xffff-0xfc2b=980 chu kì máy .Ở đây dùng thạch anh 12Mhz .nên 1 chu kì máy =1us. Một lần tràn xảy ra là 980 x 1us=980us .Sau 1000 lần 1000 x 980us gần bằng 1s .
  17. wata1105

    wata1105 New Member

    Tiền:
    $1,949
    Mình có 1 thắc mắc sao không để TH0=0xfc ,TL0=0x17 cho tròn 1000us
  18. nvhuy

    nvhuy New Member

    Tiền:
    $26
    mình nhớ thầy nói là thanh ghi timer 0: 16 bit ( chọn chế độ 16 bit lập lại mà bạn) là phai từ 0x0000 đến 0xffff hay từ 0 đến 65535 thì mới tràn chứ ko phải la: Chu kì tràn timer0 là 0xffff-0xfc2b=980 chu kì máy như wata1105 da noi
    vậy 1s =10^6 us =50 000 *20 (-50000 = 0x3cb0)
    -->
    void 1s ()
    {
    TR0=1;
    for(i=0;i<20;i++)
    {
    while(TF0==0);
    TF0=0;
    TH0=0x3c;TL0=0xB0;
    }
    TR0=0;
    }
    ad xem dung ko?
    hồi mình thực tập viết chương trình đông hồ thực như vậy mà. hihi
  19. wata1105

    wata1105 New Member

    Tiền:
    $1,949
    Mã:
    void ngat_trantimer0() interrupt 1
    {
    [COLOR=#ff0000]    TH0=0xFC;[/COLOR]
    [COLOR=#ff0000]    TL0=0x2B;[/COLOR]
        Time++;
        if(Time==1000)                   
        {
            Time=0;                                          // dinh thoi 1s
            TR1=0;
            tanso=(((TH1&0x00ff)<<8)|(TL1&0x00ff));          //tan so bang so xung dem duoc trong 1s
            TH1=0;
            TL1=0;
            TR1=1;
        }
        TF0=0;
    }
    Ý mình là sao mỗi lần tràn thì trong chương trình ngắt sẽ đặt lại TH0=0xFC,TL0=0x2B .Và bắt đầu đếm lại từ đó .nên thời gian mà xảy ra mỗi lần tràn là: (0xFFFF - 0xFC2B)x1us=980us .Sau 1000 lần tràn 980us x 1000=1s.
  20. nvhuy

    nvhuy New Member

    Tiền:
    $26
    thanks wata1105 nhe, minh hieu y ban roi :):)

Chia sẻ trang này