Đ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. Đăng ngày 28 Tháng mười 2012 #1

    sinhviencabiet

    New Member

    Số bài viết: 10
    Đã được thích: 15
    Điểm thành tích: 3
    Giới tính: Nam
    Tiền:
    $3,184
    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:

    tung.lvan thích bài này.
  2. Đăng ngày 28 Tháng mười 2012 #2

    tung.lvan

    Nhóm MCU

    Số bài viết: 188
    Đã được thích: 133
    Điểm thành tích: 43
    Giới tính: Nam
    Tiền:
    $18,079
    Cho video lên đi em!
    Thú vị đấy!
  3. Đăng ngày 28 Tháng mười 2012 #3

    quang.dt7bk

    Nhóm MCU

    Số bài viết: 320
    Đã được thích: 293
    Điểm thành tích: 63
    Giới tính: Nam
    Tiền:
    $118,714
    Đâ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. Đăng ngày 29 Tháng mười 2012 #4

    sinhviencabiet

    New Member

    Số bài viết: 10
    Đã được thích: 15
    Điểm thành tích: 3
    Giới tính: Nam
    Tiền:
    $3,184
    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. Đăng ngày 9 Tháng mười một 2012 #5

    NguyenQuyNhat

    Nhóm MCU

    Số bài viết: 230
    Đã được thích: 243
    Điểm thành tích: 43
    Giới tính: Nam
    Nơi ở: Sóc Sơn Hà Nội
    Tiền:
    $102,318
    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. Đăng ngày 19 Tháng sáu 2013 #6

    tungbk208

    New Member

    Số bài viết: 4
    Đã được thích: 0
    Điểm thành tích: 1
    Giới tính: Nam
    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. Đăng ngày 19 Tháng sáu 2013 #7

    tungbk208

    New Member

    Số bài viết: 4
    Đã được thích: 0
    Điểm thành tích: 1
    Giới tính: Nam
    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. Đăng ngày 19 Tháng sáu 2013 #8

    Dukebk.dt7

    Member

    Số bài viết: 59
    Đã được thích: 31
    Điểm thành tích: 18
    Giới tính: Nam
    Tiền:
    $3,283
    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. Đăng ngày 20 Tháng sáu 2013 #9

    quang.dt7bk

    Nhóm MCU

    Số bài viết: 320
    Đã được thích: 293
    Điểm thành tích: 63
    Giới tính: Nam
    Tiền:
    $118,714
    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. Đăng ngày 20 Tháng sáu 2013 #10

    quang.dt7bk

    Nhóm MCU

    Số bài viết: 320
    Đã được thích: 293
    Điểm thành tích: 63
    Giới tính: Nam
    Tiền:
    $118,714
    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. Đăng ngày 20 Tháng sáu 2013 #11

    tungbk208

    New Member

    Số bài viết: 4
    Đã được thích: 0
    Điểm thành tích: 1
    Giới tính: Nam
    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. Đăng ngày 20 Tháng sáu 2013 #12

    tungbk208

    New Member

    Số bài viết: 4
    Đã được thích: 0
    Điểm thành tích: 1
    Giới tính: Nam
    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. Đăng ngày 20 Tháng sáu 2013 #13

    Dukebk.dt7

    Member

    Số bài viết: 59
    Đã được thích: 31
    Điểm thành tích: 18
    Giới tính: Nam
    Tiền:
    $3,283
    Ở đâ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. Đăng ngày 20 Tháng sáu 2013 #14

    an.dxuan

    Member

    Số bài viết: 53
    Đã được thích: 26
    Điểm thành tích: 18
    Giới tính: Nam
    Tiền:
    $1,770
    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. Đăng ngày 2 Tháng mười 2013 #15

    nvhuy

    New Member

    Số bài viết: 7
    Đã được thích: 1
    Điểm thành tích: 3
    Giới tính: Nam
    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. Đăng ngày 3 Tháng mười 2013 #16

    wata1105

    New Member

    Số bài viết: 20
    Đã được thích: 17
    Điểm thành tích: 3
    Giới tính: Nam
    Tiền:
    $1,571

    Ở đâ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. Đăng ngày 3 Tháng mười 2013 #17

    wata1105

    New Member

    Số bài viết: 20
    Đã được thích: 17
    Điểm thành tích: 3
    Giới tính: Nam
    Tiền:
    $1,571
    Mình có 1 thắc mắc sao không để TH0=0xfc ,TL0=0x17 cho tròn 1000us
  18. Đăng ngày 5 Tháng mười 2013 #18

    nvhuy

    New Member

    Số bài viết: 7
    Đã được thích: 1
    Điểm thành tích: 3
    Giới tính: Nam
    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. Đăng ngày 5 Tháng mười 2013 #19

    wata1105

    New Member

    Số bài viết: 20
    Đã được thích: 17
    Điểm thành tích: 3
    Giới tính: Nam
    Tiền:
    $1,571
    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. Đăng ngày 6 Tháng mười 2013 #20

    nvhuy

    New Member

    Số bài viết: 7
    Đã được thích: 1
    Điểm thành tích: 3
    Giới tính: Nam
    Tiền:
    $26
    thanks wata1105 nhe, minh hieu y ban roi :):)

Chia sẻ trang này