Thông báo

Collapse
No announcement yet.

Đọc ADC với pic 16f887

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

  • Đọc ADC với pic 16f887

    Em đang gặp phải 1 vấn đề là nếu mạch bình thường cắm lm35 vô thì nhiệt độ ít thay đổi. Nhưng không hiểu tại sao khi cắm thêm RS232 vô mạch để hiển thị nhiệt độ lên máy tính thì nhiệt độ chạy liên tục, em nghĩ chắc là do cắm nguồn chung với mạch pic nên bị như thế. Mấy bạn cho mình hỏi cách khắc phục và khai báo lại với. Xin cảm ơn.
    setup_adc_ports(sAN0|VSS_VDD);
    setup_adc(ADC_CLOCK_DIV_2);
    em khai như thế này ko biết có đúng ko, em dùng ADC 10bit

  • #2
    thứ 1: lm35 của bạn có qua opamp khuếch đại ko hay cắm trực tiếp ? Bạn có chắc là từ đầu đã tính toán đúng nhiệt độ chưa ?
    thứ 2: cắm thêm rs232 là cắm như thế nào ? hiển thị qua lcd hay led ...
    thứ 3: ghi code cụ thể ra mới biết đường nói chứ ai biết port nào chân nào, setup, delay ...

    "bạn" của "em" đọc xong chẳng ai muốn trả lời
    Đang thất nghiệp 0988-010-486

    Comment


    • #3
      Mình dùng LM35 cắm qua opam khuếch đại.
      Mình cắm cổng RS232 vô luôn trên mạch, nguồn dùng nguồn chung với VDK.
      Hiển thị qua LCD
      #include "D:\Chuong trinh\Do nhiet do\new\main.h"
      #include <def_877a.h>
      #include <lcd_lib_4bit.c>
      int16 giatri,caidat,giatri1;
      int8 mode=0,n=0,i=0,rda=0;
      int8 string[16];
      void hienthi(int8 t);
      void quetphim();
      void gui_rs232(int8 a);
      void gui_cd(int8 a);
      #INT_RDA
      void RDA_interrupt(){
      rda=getc();delay_ms(10);
      n=getc();
      delay_ms(10);

      }
      void main()
      {
      set_tris_A(0xff);
      set_tris_D(0x00);
      lcd_init();
      lcd_putcmd(0x01);
      lcd_putcmd(0x80);
      ENABLE_INTERRUPTS(INT_RDA);
      enable_interrupts(GLOBAL);
      setup_adc_ports(sAN0);
      setup_adc(ADC_CLOCK_DIV_2);
      set_adc_channel(0);



      while (mode==0) {
      giatri=read_ADC();
      giatri=giatri/2.048/4;
      if (giatri!=giatri1) {
      gui_rs232(giatri);
      gui_cd(n);
      }
      giatri1=giatri;
      LCD_putcmd(0x80);
      LCD_putchar("Nhiet do: ");
      LCD_putcmd(0x89);
      HIENTHI(giatri);
      LCD_putchar("oC ");
      LCD_PutCmd(0xC0);
      LCD_putchar("Cai dat : ");
      LCD_putcmd(0xC9);
      HIENTHI(n);
      LCD_putcmd(0xCD);
      LCD_putchar("oC ");
      delay_ms(0.1);
      quetphim();

      }


      }



      void hienthi(int8 t)
      {
      unsigned char v;
      if(t<10)

      LCD_putchar(t+48);
      else
      if(t<100)
      {
      LCD_putchar(t/10+48);
      LCD_putchar(t%10+48);
      }
      else
      {
      v=t/10;
      LCD_putchar(v/10+48);
      LCD_putchar(v%10+48);
      LCD_putchar(t%10+48);
      }
      }
      void quetphim() {
      if (RB0==0) {while (RB0==0) {;} {mode=1;}
      while (mode==1) {
      LCD_putcmd(0x80);
      LCD_putchar("CAI DAT NHIET DO");
      LCD_putcmd(0x89);
      LCD_PutCmd(0xC0);
      LCD_putchar("Cai dat : ");
      LCD_putcmd(0xC9);
      HIENTHI(n);
      LCD_putcmd(0xCD);
      LCD_putchar("oC ");
      delay_ms(0.1);
      if (RB1==0) {while (RB1==0) {;} {n=n+1;}}
      if (RB2==0) {while (RB2==0) {;} {if (n>0) {n=n-1;}}}
      if (RB0==0) {while (RB0==0) {;} gui_cd(n);mode =0;}
      }

      }
      }

      void gui_rs232(int8 a) {

      if(a<10)
      {

      string[1]=a+48;

      puts("A");
      putc(string[0]);
      putc(string[1]);

      }
      if(a>9&&a<100)
      {
      unsigned char c=a/10;
      unsigned char d=a%10;
      string[2]=(c+48);
      string[3]=(d+48);

      puts("A");
      putc(string[2]);
      putc(string[3]);
      }
      if(a>99)
      {
      unsigned char t=a/100;
      unsigned char c=a/10-10*t;
      unsigned char d=a%10;

      string[4]=(t+48);
      string[5]=(c+48);
      string[6]=(d+48);
      puts("B");
      putc(string[4]);
      putc(string[5]);
      putc(string[6]);
      }

      }


      void gui_cd(int8 a) {

      if(a<10)
      {

      string[1]=a+48;

      puts("B");

      putc(string[1]);

      }
      if(a>9&&a<100)
      {
      unsigned char c=a/10;
      unsigned char d=a%10;
      string[2]=(c+48);
      string[3]=(d+48);

      puts("B");
      putc(string[2]);
      putc(string[3]);
      }
      if(a>99)
      {
      unsigned char t=a/100;
      unsigned char c=a/10-10*t;
      unsigned char d=a%10;

      string[4]=(t+48);
      string[5]=(c+48);
      string[6]=(d+48);
      puts("A");
      putc(string[4]);
      putc(string[5]);
      putc(string[6]);
      }

      }

      Comment


      • #4
        Khi rút RS232 ra thì mạch chạy ổn định lắm, nhiệt độ ít thay đổi. Khi cắm vô thì nó nhảy lung tung nhưng vẫn nằm trong khoảng nhiệt độ bình thường,
        nghĩa là +-2 độ. Nhưng nó nhảy kinh quá

        Comment


        • #5
          các khai báo này có ở main.h àh ?

          #device *=16
          #FUSES NOWDT, HS, NOPUT, NOPROTECT, NOBROWNOUT
          #use delay(clock= )
          #use rs232(baud= , xmit=PIN_ ,rcv=PIN_ )
          Đang thất nghiệp 0988-010-486

          Comment


          • #6
            Nguyên văn bởi tay mơ Xem bài viết
            các khai báo này có ở main.h àh ?

            #device *=16
            #FUSES NOWDT, HS, NOPUT, NOPROTECT, NOBROWNOUT
            #use delay(clock= )
            #use rs232(baud= , xmit=PIN_ ,rcv=PIN_ )
            khai báo này ở main.h bạn. Đâu cũng được mà

            Comment


            • #7
              Tui compile lại thấy nhiều warning báo thiếu delay prevent - nhưng vì không biết file main.h nên thôi ko nói về code nữa - cứ coi như code đúng thì phần cứng lỗi,ic max232 bị die, ngắt RDA lấy lệnh (n) từ máy tính - mà máy tính có ON - hoặc gữi sai byte khi sai baud, khi nó bị gọi ngắt liên tục hoặc chạm đè phím quét
              Đang thất nghiệp 0988-010-486

              Comment


              • #8
                không cần cắm vô máy tính thì nó cũng nhảy, đã thử disable ngắt RDA. chỉ cần cắm nguồn của max232 vô là nhảy mặc dù dữ liệu truyền lên và xuống đều đúng

                Comment


                • #9
                  Nguyên văn bởi emperordx Xem bài viết
                  không cần cắm vô máy tính thì nó cũng nhảy, đã thử disable ngắt RDA. chỉ cần cắm nguồn của max232 vô là nhảy mặc dù dữ liệu truyền lên và xuống đều đúng
                  Gửi hình nguyên lý lên đi bạn. Cả hình đi dây mạch in nếu có thể.

                  Việc đọc ADC bạn đã lấy trung bình chưa? Lấy trung bình là một cách đơn giản để ổn định hơn kết quả.

                  p/s: cách viết lệnh của bạn khó nhìn quá. Bạn nên chia thành từng block để phân biệt khối lệnh chức năng, nên cách lề đều cho khối rẽ nhánh hay lặp...
                  Bạn có thấy viết lệnh như phía dưới dễ đọc hơn không?

                  Code:
                  void main()
                  {
                     set_tris_A(0xff);
                     set_tris_D(0x00);
                     lcd_init();
                     lcd_putcmd(0x01);
                     lcd_putcmd(0x80);
                     ENABLE_INTERRUPTS(INT_RDA);
                     enable_interrupts(GLOBAL);
                     setup_adc_ports(sAN0);
                     setup_adc(ADC_CLOCK_DIV_2);
                     set_adc_channel(0);
                     //
                     while (mode==0)
                       {
                        giatri=read_ADC();
                        giatri=giatri/2.048/4;
                        if (giatri!=giatri1)
                          {
                           gui_rs232(giatri);
                           gui_cd(n);
                          }
                        giatri1=giatri;
                        LCD_putcmd(0x80);
                        LCD_putchar("Nhiet do: ");
                        LCD_putcmd(0x89);
                        HIENTHI(giatri);
                        LCD_putchar("oC ");
                        LCD_PutCmd(0xC0);
                        LCD_putchar("Cai dat : ");
                        LCD_putcmd(0xC9);
                        HIENTHI(n);
                        LCD_putcmd(0xCD);
                        LCD_putchar("oC ");
                        delay_ms(0.1);
                        quetphim();
                       }
                  }
                  Tôi không chắc CCSC sẽ xử lý đúng ý đồ của bạn với lệnh giatri=giatri/2.048/4delay_ms(0.1).

                  Comment


                  • #10
                    cảm ơn anh em đã đóng góp ý kiến, mình đã giải quyết được vấn đề này rồi.

                    Comment


                    • #11
                      cho e hỏi cái các bác, e viét chương trình đo adc hiện lcd, chương trình đã chạy nhưng có cái thắc mắc là sao e khai báo #device adc=8 thì ccs dịch bị lỗi, bỏ dòng đó đi thì dịch được, ở đầu chương trình e khai báo #include <16f887.h> rùi. Cho e hỏi luôn trong ccs muốn láy được giá trị adc 10 bít thì lấy như thế nào vậy ạh , sao e thấy lệnh nó ngắn gọn quá, chỉ có readadc thôi àh, thì nó chỉ ra toàn 8 bit thôi hix
                      CK6C -HUI

                      Comment


                      • #12
                        Nguyên văn bởi minhtri0405 Xem bài viết
                        cho e hỏi cái các bác, e viét chương trình đo adc hiện lcd, chương trình đã chạy nhưng có cái thắc mắc là sao e khai báo #device adc=8 thì ccs dịch bị lỗi, bỏ dòng đó đi thì dịch được, ở đầu chương trình e khai báo #include <16f887.h> rùi. Cho e hỏi luôn trong ccs muốn láy được giá trị adc 10 bít thì lấy như thế nào vậy ạh , sao e thấy lệnh nó ngắn gọn quá, chỉ có readadc thôi àh, thì nó chỉ ra toàn 8 bit thôi hix
                        Hàm read_adc() sẽ trả về giá trị ADC có số bit bằng với số bit đã khai báo trong câu lệnh
                        #device *=16 adc=x.
                        Đương nhiên là để lấy được đúng 10 bit phải dùng biến 16 bit.

                        Comment


                        • #13
                          bởi vì pic16f887 có bộ adc 10 bit nên phải khai báo là adc=10 (xem datasheet)
                          muốn thu adc 10 bit thì ta phải có một biến 16 bit (WORD) - tức là dùng 2 biến 8 bit (BYTE), một cái làm byte low, một cái làm byte high ( trong đó byte low dùng đủ 8 bit - byte high chỉ dùng có 2 bit ), nhưng CCS làm ngầm hết mọi chuyện này rồi

                          Code:
                          #include <16F877A.h>
                          #device *=16 ADC=10
                          #fuses HS,NOWDT,NOLVP
                          #use delay(clock=20000000)
                          ...
                          INT16 ADC16
                          ...
                          void main() {
                          ...
                          SET_ADC_CHANNEL (0);
                          ADC16 = READ_ADC ();
                          PRINTF(LCD_PUTCHAR, "%04lu" ADC16 );
                          số đọc đc sẽ hiển thì là từ "0000" tới "1023"
                          zậy thôi
                          Đang thất nghiệp 0988-010-486

                          Comment


                          • #14
                            Nguyên văn bởi tay mơ Xem bài viết
                            bởi vì pic16f887 có bộ adc 10 bit nên phải khai báo là adc=10 (xem datasheet)
                            muốn thu adc 10 bit thì ta phải có một biến 16 bit (WORD) - tức là dùng 2 biến 8 bit (BYTE), một cái làm byte low, một cái làm byte high ( trong đó byte low dùng đủ 8 bit - byte high chỉ dùng có 2 bit ), nhưng CCS làm ngầm hết mọi chuyện này rồi

                            Code:
                            #include <16F877A.h>
                            #device *=16 ADC=10
                            #fuses HS,NOWDT,NOLVP
                            #use delay(clock=20000000)
                            ...
                            INT16 ADC16
                            ...
                            void main() {
                            ...
                            SET_ADC_CHANNEL (0);
                            ADC16 = READ_ADC ();
                            PRINTF(LCD_PUTCHAR, "%04lu" ADC16 );
                            số đọc đc sẽ hiển thì là từ "0000" tới "1023"
                            zậy thôi
                            Không nhất thiết khai báo ADC = 10 tuy ADC là 10 bit.
                            Khai báo ADC = x ( 8 hoặc 10 ) để hỗ trợ trong hàm Read_ADC(). Nếu khai báo ADC=10 thì hàm Read_ADC sẽ trả về giá trị 10 bit tức là giá trị đúng của bộ ADC. Nếu khai báo ADC = 8 thì trong hàm Read_ADC nó sẽ đọc 10 bit của bộ ADC, sau đó chia giá trị 10 bit này cho 4 để được 1 giá trị 8 bit và trả về giá trị 8 bit này và do đó chỉ cần 1 biến 8 bit để lưu giá trị ADC.

                            Comment


                            • #15
                              Nguyên văn bởi duong_act Xem bài viết
                              ...
                              Khai báo ADC = x ( 8 hoặc 10 )
                              ...
                              Với PIC16877 thì x có thể là 8 hoặc 10 hoặc 16.


                              Nguyên văn bởi duong_act Xem bài viết
                              ...
                              Nếu khai báo ADC = 8 thì trong hàm Read_ADC nó sẽ đọc 10 bit của bộ ADC, sau đó chia giá trị 10 bit này cho 4 để được 1 giá trị 8 bit và trả về giá trị 8 bit này và do đó chỉ cần 1 biến 8 bit để lưu giá trị ADC.
                              Làm gì có vụ chia cho 4 ở đây nhỉ. Nếu chọn ADC=8 thì A/D RESULT REGISTERS sẽ được định dạng Left Justified và kết quả trả về của hàm read_adc() là Byte ADRESH.
                              Last edited by Acxen_lupine; 28-03-2013, 00:46.
                              Hôm nay trời nắng chang chang.
                              Mèo con đi học chẳng mang thứ gì.
                              Chỉ mang một cái bút chì.
                              Và mang một mẩu bánh mì con con.

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              • tuyennhan
                                Trả lời cho Tiếng Anh cho người Việt
                                bởi tuyennhan
                                Cái thư sai ngay câu chào Dear sir mới đúng Hi chỉ dùng cho người quen , các vấn đề về kỹ thuật nó không trả lời hoặc nói loanh quanh tránh ảnh hưởng đến công ty .
                                Giup1 người cần không giúp người không cần với lại văn mình vợ người nha đừng quên .
                                hôm nay, 07:44
                              • vi van pham
                                Trả lời cho Tiếng Anh cho người Việt
                                bởi vi van pham
                                Cám ơn những lời chúc tốt đẹp của em.

                                Việc em làm giống như chê sếp dốt, chẳng những không có miếng xôi nào để ăn mà còn chịu nhiều trù dập lên bờ , xuống ruộng.

                                Hãy tránh vết xe đổ của tui đi. Dành thời gian lo cho gia đình....
                                hôm nay, 02:00
                              • nhathung1101
                                Trả lời cho Tiếng Anh cho người Việt
                                bởi nhathung1101
                                Ngoại ngữ là không thể thiếu, nhất là làm việc với công nghệ.

                                Nhưng học để tán gái hay để đọc datasheet, manual là chuyện cần quan tâm.

                                Và đọc ở nguồn nào đáng tin cậy, chứ cứ lên tictok hay facebook học lỏm thì...
                                Hôm qua, 22:18
                              • dinhthuong80
                                Trả lời cho Tiếng Anh cho người Việt
                                bởi dinhthuong80
                                Bác nói rất khách quan và chính xác. Ngoại ngữ là chìa khóa thăng tiến dù làm gì. Chả thế mà nay nước mình dạy tiếng Anh từ tiểu học.

                                Nhớ hồi năm 2006 em ra Hải Phòng, Hải Dương tìm việc, thời đó ở Bình Dương lương công...
                                Hôm qua, 14:51
                              • dinhthuong80
                                Trả lời cho Tiếng Anh cho người Việt
                                bởi dinhthuong80
                                Cảm ơn bạn, ĐT cũng có ý nghĩ như vậy.

                                Thực ra, lỗi của hãng đó ( gọi là hãng vì không chỉ một model sản phẩm) là về phần cứng, ĐT tuy không biết về lập trình phần mềm nhưng cũng thấy rằng sẽ chẳng khó khăn gì đáng...
                                Hôm qua, 14:39
                              • dinhthuong80
                                Trả lời cho Tiếng Anh cho người Việt
                                bởi dinhthuong80
                                Dạ, bác bảy mấy tuổi đời rồi cũng không kém bố cháu bao nhiêu. Tuổi nghề thì bác cũng đáng tuổi cha chú.

                                Nhưng 2 điều trên thì chưa hẳn đã đáng quí và đáng tôn trọng bằng việc bác rất nhiệt tình chia sẻ kinh nghiệm chuyên...
                                Hôm qua, 14:28
                              • bqviet
                                Trả lời cho Tiếng Anh cho người Việt
                                bởi bqviet
                                Đúng, nếu chú tâm thì chỉ cần mỗi tiếng Việt là đã khá đủ để làm đa số công việc thông thường, ở thời đại ngày nay khi tài liệu sách vở phương tiện thông tin liên lạc đã nhiều. Nhưng cũng chính ở thời nay giao lưu các nước nhiều...
                                21-02-2025, 20:26
                              • mèomướp
                                Trả lời cho Tiếng Anh cho người Việt
                                bởi mèomướp
                                Dạ cháu nghĩ chú dinh... cứ mạnh dạn gửi thư đi ạ, chú có thể gửi bằng văn bản in chuyển phát nhanh sẽ có giá trị hơn. Vấn đề chưa hẳn là cần hãng làm gì đó, mà chỉ đơn giản là mình cảm thấy nhẹ lòng vì đã làm những việc bản...
                                21-02-2025, 12:32
                              • vi van pham
                                Trả lời cho Tiếng Anh cho người Việt
                                bởi vi van pham
                                Những lần hắt hơi sổ mũi làm tôi mệt lã, phải dùng rượu uống để ngũ. Tôi cũng đang uống rượu 1 mình, viết vài dòng này cho em ( có lẽ dt chỉ bằng tuổi em tôi).

                                Dinh thuong dang đi vào vết xe đổ của tôi. Càng chứng minh, có...
                                20-02-2025, 21:31
                              • bqviet
                                Trả lời cho Hỏi về cách hàn linh kiện ( giúp tớ với )
                                bởi bqviet
                                Thiết nghĩ thi thoảng bác lên đây chia xẻ ít kinh nghiệm cũng vui rồi. Còn chuyện con người sinh lão bệnh tử là thường, sống cùng với quy luật đó thôi. Bqv nhớ trước đây bác từng kể về chuyện rang chì ô-xít bằng chảo để phục hồi bình điện, đấy cũng là thành quả đáng nể phục ở thời kỳ thiếu thốn đó.
                                20-02-2025, 17:22
                              Đang tải...
                              X