Thông báo

Collapse
No announcement yet.

cảm biến siêu âm SRF05 với PIC 16F877a!!!!!!!!!!!!!!!!!!!!!!!!!!

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

  • cảm biến siêu âm SRF05 với PIC 16F877a!!!!!!!!!!!!!!!!!!!!!!!!!!

    xin mọi người quân tâm dùng xem code sai chỗ nào nhá
    khi mình chạy thì nó chỉ hiển thị số 0 trên LCD
    mình dùng SRF05 này để đo khoảng cách. dùng mode1 chân trigger và echo mắc riêng.
    ai có hảo tm chỉnh mình với!!!!!!

    #include <16F877.h>
    #include <defs_16f877a.h>
    #fuses HS,NOWDT,NOPROTECT,NOLVP
    #device *=16
    #use delay(clock=20000000)
    #include <lcd_lib_4bit.c>
    #define TRIGGER pin_B4// chan phat song sieu am
    //chan ECHO nhan tin hieu ve noi vao RC2
    #BYTE TRISC=0X87
    #BYTE PORTC=0X07
    #BIT RC2=0X7.2
    float dist,getvar ;
    int1 has_echo=0,echo=0;

    ////////////////////////////////////////////////

    #int_CCP1
    void ccp1_isr()
    {
    setup_ccp1(CCP_CAPTURE_RE);//thiet lap Capture CCP1 do xung canh len
    enable_interrupts(INT_CCP1);//cho phep ngat khi ccp1 co tin hieu
    enable_interrupts(GLOBAL);
    if(pin_c2)
    set_timer1(1000); //reset timer1 ve 0
    setup_ccp1(CCP_CAPTURE_FE); //chuyen sang do xung canh xuong
    if(!pin_c2);//khi co xung canh xuong
    getvar=get_timer1(); //doc gia tri timer1 ngay khi co xung echo canh xuong
    dist=(getvar-485)/28.3; //so lieu dua theo ket qua do thuc te
    dist=getvar;
    }
    //----10us cho trigger----
    void trig()
    {
    output_high(TRIGGER);
    delay_us(10);
    output_low(TRIGGER);
    }
    void main()
    {
    SET_TRIS_B(0X00);
    SET_TRIS_C(0xff);
    lcd_init();

    while(1)
    {
    trig();
    ccp1_isr();
    lcd_putcmd(0x01);
    printf(lcd_putchar,"dist=%6.1f",dist);
    lcd_putchar("cm");
    delay_ms(1000);
    }
    }

  • #2
    #int_CCP1
    void ccp1_isr()
    {
    setup_ccp1(CCP_CAPTURE_RE);//thiet lap Capture CCP1 do xung canh len
    enable_interrupts(INT_CCP1);//cho phep ngat khi ccp1 co tin hieu
    enable_interrupts(GLOBAL);
    if(pin_c2)
    set_timer1(1000); //reset timer1 ve 0
    setup_ccp1(CCP_CAPTURE_FE); //chuyen sang do xung canh xuong
    if(!pin_c2);//khi co xung canh xuong
    getvar=get_timer1(); //doc gia tri timer1 ngay khi co xung echo canh xuong
    dist=(getvar-485)/28.3; //so lieu dua theo ket qua do thuc te
    dist=getvar;
    }
    Ko bít bạn có lập lập trình C kỹ chưa, hay là bạn dùng compiler khác, if xong phải mở ngoặc chứ, hok thoy chỉ thực thi 1 lệnh ngay phía sau, còn if mà chấm phẩy lun là if thừa đó bạn.

    Nhự vậy mới đúng này:

    if(pin_c2) {
    set_timer1(1000); //reset timer1 ve 0
    setup_ccp1(CCP_CAPTURE_FE); //chuyen sang do xung canh xuong
    }
    else { //khi co xung canh xuong
    getvar=get_timer1(); //doc gia tri timer1 ngay khi co xung echo canh xuong
    dist=(getvar-485)/28.3; //so lieu dua theo ket qua do thuc te
    dist=getvar;
    }
    Computer Science major - Vietnamese-German University
    Sponsored by

    Comment


    • #3
      Nguyên văn bởi minh_cly Xem bài viết
      Ko bít bạn có lập lập trình C kỹ chưa, hay là bạn dùng compiler khác, if xong phải mở ngoặc chứ, hok thoy chỉ thực thi 1 lệnh ngay phía sau, còn if mà chấm phẩy lun là if thừa đó bạn.

      Nhự vậy mới đúng này:

      if(pin_c2) {
      set_timer1(1000); //reset timer1 ve 0
      setup_ccp1(CCP_CAPTURE_FE); //chuyen sang do xung canh xuong
      }
      else { //khi co xung canh xuong
      getvar=get_timer1(); //doc gia tri timer1 ngay khi co xung echo canh xuong
      dist=(getvar-485)/28.3; //so lieu dua theo ket qua do thuc te
      dist=getvar;
      }
      thank bạn!!!!
      bạn ơ mình sữa rồi nhưng vẫn không được bản đã từng lập trình cho con SRF05 trên pic 16f877a chưa chỉ tớ với

      Comment


      • #4
        Bạn nên Enable ngắt trong main luôn, khi ngắt chỉ setup lại thoy. Còn trả timer 1 về 0 sao lại cho giá trị 1000.
        Bạn hình như chưa setup timer 1 thì phải (mặc định là disable đó bạn, hok đếm đc đâu). Và 16F877 có 2 chân capture lận, đừng tiết kiệm quá.
        Kết quả ghi trong datasheet òy đó, nếu echo đo bằng us thì chia cho 58 ra cm.

        P/S: Và trong datasheet cũng nói là 2 lần đo ít nhất cách nhau 50ms, hok cần chờ đến 1s đâu.
        Computer Science major - Vietnamese-German University
        Sponsored by

        Comment


        • #5
          Nguyên văn bởi minh_cly Xem bài viết
          Bạn nên Enable ngắt trong main luôn, khi ngắt chỉ setup lại thoy. Còn trả timer 1 về 0 sao lại cho giá trị 1000.
          Bạn hình như chưa setup timer 1 thì phải (mặc định là disable đó bạn, hok đếm đc đâu). Và 16F877 có 2 chân capture lận, đừng tiết kiệm quá.
          Kết quả ghi trong datasheet òy đó, nếu echo đo bằng us thì chia cho 58 ra cm.

          P/S: Và trong datasheet cũng nói là 2 lần đo ít nhất cách nhau 50ms, hok cần chờ đến 1s đâu.
          bạn ơi bạn có thể chỉ cụ thể trong code được không???. còn về dùng thêm chân captrure nữa tớ không muốn vì sau này tớ muốn đọc 2 con SRF05 nên dùng một chân chắc vẫn đọc được chứ
          vì tớ mới bắt đầu học lập trình cho pic nên đang gà quá mong bạn chỉ bảo tận tình với nhá!!!
          cảm ơn bạn rất nhiều!!!!

          Comment


          • #6
            Nguyên văn bởi chungpmth Xem bài viết
            bạn ơi bạn có thể chỉ cụ thể trong code được không???. còn về dùng thêm chân captrure nữa tớ không muốn vì sau này tớ muốn đọc 2 con SRF05 nên dùng một chân chắc vẫn đọc được chứ
            vì tớ mới bắt đầu học lập trình cho pic nên đang gà quá mong bạn chỉ bảo tận tình với nhá!!!
            cảm ơn bạn rất nhiều!!!!
            Mình cũng chưa làm việc vs SRF05 nhưng sau khi đọc datasheet, code có thể đc viết thế này:
            Code:
            #include <16F877.h>
            #include <defs_16f877a.h>
            #fuses HS,NOWDT,NOPROTECT,NOLVP
            #device *=16
            #use delay(clock=20000000)
            #include <lcd_lib_4bit.c>
            #define TRIGGER pin_B4// chan phat song sieu am
            //chan ECHO nhan tin hieu ve noi vao RC2
            #BYTE TRISC=0X87
            #BYTE PORTC=0X07
            #BIT RC2=0X7.2
            float dist,getvar;
            int1 has_echo=0;
            
            ////////////////////////////////////////////////
            
            #int_CCP1
            void ccp1_isr()
            {
                if(pin_c2) { // Nếu là xung cạnh lên
                    set_timer1(0); // Reset timer1 về 0
                    setup_ccp1(CCP_CAPTURE_FE); // Chuyển Capture 1 đo cạnh xuống
                }
                if(!pin_c2) { // Nếu là xung cạnh xuống
                    getvar=get_timer1(); // Đọc giá trị timer 1
                    dist=(getvar*0.8)/58; // Mỗi 1 nhịp của timer 1 tương ứng vs 0.8 us, lấy us chia cho 58 ra cm
                    setup_ccp1(CCP_CAPTURE_RE); // Chuyển Capture 1 đo xung lên trở lại
                    has_echo = 1; // Đã nhận xong echo
                }
            }
            //----Ngat timer 1----
            #int_TIMER1
            void  TIMER1_isr(void) {
               has_echo = 1; // Tràn timer mà ko có echo thì cho wa (tối đa của SRF05 là 30ms, tràn timer là 52ms)
               dist = -1; // Số này bạn muốn cho sao cũng đc, tức là ko đo được
            }
            
            //----10us cho trigger----
            void trig()
            {
                output_high(TRIGGER);
                delay_us(10);
                output_low(TRIGGER);
            }
            void main()
            {
                SET_TRIS_B(0X00);
                SET_TRIS_C(0xff);
                lcd_init();
            
                setup_timer_1(T1_INTERNAL|T1_DIV_BY_4); //20 MHz thì tràn trong 52ms (tối đa xung của SRF05 là 30ms)
            
                setup_ccp1(CCP_CAPTURE_RE); // Thiết lập Capture 1 đo cạnh lên
            
                enable_interrupts(int_TIMER1); // Ngắt timer 1, đề phòng trường hợp ko có echo
                enable_interrupts(INT_CCP1); // Ngắt Capture 1
                enable_interrupts(GLOBAL);
            
                while(1)
                {
                    has_echo = 0; // Xác lập lại echo
                    trig(); // Trigger
                    while (has_echo  == 0) { } // chờ đến khi nhận hết echo
                    lcd_putcmd(0x01);
                    printf(lcd_putchar,"dist=%6.1f",dist);
                    lcd_putchar("cm");
                    delay_ms(100); // 0.1 s đo một lần
                }
            }
            Computer Science major - Vietnamese-German University
            Sponsored by

            Comment


            • #7
              Nguyên văn bởi minh_cly Xem bài viết
              Mình cũng chưa làm việc vs SRF05 nhưng sau khi đọc datasheet, code có thể đc viết thế này:
              Code:
              #include <16F877.h>
              #include <defs_16f877a.h>
              #fuses HS,NOWDT,NOPROTECT,NOLVP
              #device *=16
              #use delay(clock=20000000)
              #include <lcd_lib_4bit.c>
              #define TRIGGER pin_B4// chan phat song sieu am
              //chan ECHO nhan tin hieu ve noi vao RC2
              #BYTE TRISC=0X87
              #BYTE PORTC=0X07
              #BIT RC2=0X7.2
              float dist,getvar;
              int1 has_echo=0;
              
              ////////////////////////////////////////////////
              
              #int_CCP1
              void ccp1_isr()
              {
                  if(pin_c2) { // Nếu là xung cạnh lên
                      set_timer1(0); // Reset timer1 về 0
                      setup_ccp1(CCP_CAPTURE_FE); // Chuyển Capture 1 đo cạnh xuống
                  }
                  if(!pin_c2) { // Nếu là xung cạnh xuống
                      getvar=get_timer1(); // Đọc giá trị timer 1
                      dist=(getvar*0.8)/58; // Mỗi 1 nhịp của timer 1 tương ứng vs 0.8 us, lấy us chia cho 58 ra cm
                      setup_ccp1(CCP_CAPTURE_RE); // Chuyển Capture 1 đo xung lên trở lại
                      has_echo = 1; // Đã nhận xong echo
                  }
              }
              //----Ngat timer 1----
              #int_TIMER1
              void  TIMER1_isr(void) {
                 has_echo = 1; // Tràn timer mà ko có echo thì cho wa (tối đa của SRF05 là 30ms, tràn timer là 52ms)
                 dist = -1; // Số này bạn muốn cho sao cũng đc, tức là ko đo được
              }
              
              //----10us cho trigger----
              void trig()
              {
                  output_high(TRIGGER);
                  delay_us(10);
                  output_low(TRIGGER);
              }
              void main()
              {
                  SET_TRIS_B(0X00);
                  SET_TRIS_C(0xff);
                  lcd_init();
              
                  setup_timer_1(T1_INTERNAL|T1_DIV_BY_4); //20 MHz thì tràn trong 52ms (tối đa xung của SRF05 là 30ms)
              
                  setup_ccp1(CCP_CAPTURE_RE); // Thiết lập Capture 1 đo cạnh lên
              
                  enable_interrupts(int_TIMER1); // Ngắt timer 1, đề phòng trường hợp ko có echo
                  enable_interrupts(INT_CCP1); // Ngắt Capture 1
                  enable_interrupts(GLOBAL);
              
                  while(1)
                  {
                      has_echo = 0; // Xác lập lại echo
                      trig(); // Trigger
                      while (has_echo  == 0) { } // chờ đến khi nhận hết echo
                      lcd_putcmd(0x01);
                      printf(lcd_putchar,"dist=%6.1f",dist);
                      lcd_putchar("cm");
                      delay_ms(100); // 0.1 s đo một lần
                  }
              }
              cảm ơn bạn nhiều quá!!!
              ban thật là tận tình!!!
              thank bạn nhiều mai tớ test thử trên mạch thật nếu có vấn đề gì mong bạn giải đáp nhá!!!

              Comment


              • #8
                Àh quên, bạn sửa lại dòng này getvar=get_timer1(); thành getvar = CCP_1; để cho việc cho đc chính xác hơn. (get_timer1 là lấy tại thời điểm đó, còn CCP_1 là get_timer1 tại thời điểm ngắt.
                Computer Science major - Vietnamese-German University
                Sponsored by

                Comment


                • #9
                  bạn ơi mình test thử rồi chạy ổn
                  bạn cho mình hỏi thêm nhá!
                  mình đang định dùng tín hiệu đo được từ cảm biến để điều khiển động cơ bước theo khoảng cách đo được
                  nhưng loay hoay mãi vẫn chưa hình dung được mạch và cách kết nối bạn chỉ mình được không??
                  cảm ơn bạn nhá!!!

                  Comment


                  • #10
                    Động cơ bước thì mình chưa từng làm, chắc phải nhờ mấy cao thủ khác ròy
                    Computer Science major - Vietnamese-German University
                    Sponsored by

                    Comment


                    • #11
                      vậy à!!!!
                      cảm ơn bạn nhiều nhá!!!!!

                      Comment


                      • #12
                        Nguyên văn bởi minh_cly Xem bài viết
                        Động cơ bước thì mình chưa từng làm, chắc phải nhờ mấy cao thủ khác ròy
                        bạn ơi sao mình đọc nó cứ báo mỗi dist=-1 mà không thấy thay đổi gì có phải chăng chưa đo được timer chưa ngắt nhỉ????

                        Comment


                        • #13
                          Nguyên văn bởi chungpmth Xem bài viết
                          bạn ơi sao mình đọc nó cứ báo mỗi dist=-1 mà không thấy thay đổi gì có phải chăng chưa đo được timer chưa ngắt nhỉ????
                          Chắc là nó đo quá xa hay quá gần, timer chỉ ngắt khi ko có echo mà thoy.
                          Computer Science major - Vietnamese-German University
                          Sponsored by

                          Comment


                          • #14
                            mình thử rồi mà cũng không được hay là do ham ngắt chưa hoạt động bạn nhỉ!!!!!

                            Comment


                            • #15
                              Chết, code mình thiếu, bạn sửa như vậy nè:
                              #int_TIMER1
                              void TIMER1_isr(void) {
                              if (has_echo == 0) {
                              has_echo = 1; // Tràn timer mà ko có echo thì cho wa (tối đa của SRF05 là 30ms, tràn timer là 52ms)
                              dist = -1; // Số này bạn muốn cho sao cũng đc, tức là ko đo được
                              }
                              }
                              Computer Science major - Vietnamese-German University
                              Sponsored by

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X