PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Cơ bản về vi điều khiển và PIC (http://www.picvietnam.com/forum/forumdisplay.php?f=8)
-   -   ADC 10 bit 18F4550 (http://www.picvietnam.com/forum/showthread.php?t=3738)

black_76 20-03-2009 02:31 AM

ADC 10 bit 18F4550
 
Các bác cho em hỏi một chút về ADC 10 bit của 18F4550. Đối với ADC 8 bit thì không vấn đề j nhưng với ADC 10bit thì khi cho hiển thị lên LCD nó chạy linh tinh cả và chữ số hàng nghìn bị lỗi. Em post cả code lên. Bác nào biết chỉ dùm em cái. Thanks.

Code:

#include <18f4550.h>
#device ADC = 16
#include <string.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=20000000)
#include <lcd.c>
      long data = 0;
      int8 donvi = 0,chuc = 0,tram = 0,nghin = 0;

//Chuong trinh hien thi
 void Display(long x)
  {
      donvi = (x%10);
      chuc = ((x%100)/10);
      tram = ((x/100)%10);
      nghin = (x/1000);
      if(nghin>0)
              {
              lcd_putc("Bien tro:");
              lcd_putc(nghin+48);
              lcd_putc(tram+48);
              lcd_putc(chuc+48);
              lcd_putc(donvi+48);
              }
    else if(tram>0)
              {
              lcd_putc("Bien tro:");
              lcd_putc(tram+48);
              lcd_putc(chuc+48);
              lcd_putc(donvi+48);
              }
    else if(chuc>0)
              {
              lcd_putc("Bien tro:");
              lcd_putc(chuc+48);
              lcd_putc(donvi+48);
              }
    else if(donvi>0)
              {
              lcd_putc("Bien tro:");
              lcd_putc(donvi+48);
              }
  }
 
//Chuong trinh hien thi

     
//Chuong trinh chinh
void Main()
{     
//LCD setup
      lcd_init();
      lcd_gotoxy(1,1);
      lcd_putc("PLEASE WAIT...");
      delay_ms(4000);
      lcd_putc('\f');
      lcd_putc("START");
      delay_ms(2000);
      lcd_putc('\f');
//ADC setup
      setup_adc( ADC_CLOCK_INTERNAL );
      setup_adc_ports( AN0 );     
      set_adc_channel( 0 );
      delay_us(10);
While ( true )
  {
      data = Read_ADC();
      Display(data);
      delay_ms(1000);
      lcd_putc('\f');
  }
}


namqn 20-03-2009 03:04 AM

Code của bạn có vài vấn đề:

- hàm lcd_putc() của CCS C chỉ nhận đối số là một ký tự, do đó các lệnh gọi hàm của bạn với đối số chuỗi sẽ cho kết quả không dự đoán được

- hàm Display() của bạn không cần viết phức tạp như vậy, chỉ cần dùng hàm itoa() của CCS C để chuyển số nguyên data thành chuỗi ký tự, và lần lượt hiển thị các ký tự đó bằng hàm lcd_putc(). Theo tôi, giữa các lần gọi hàm lcd_putc() nên có thời gian trễ vài chục đến 100 us, vì LCD không xử lý nhanh như vi điều khiển.

Thân,

bien_van_khat 20-03-2009 09:14 AM

Cách đơn giản nhất ko cần phải viết nhiều code là dùng hàm printf

printf(lcd_putc, "Bien tro: %.4lu", x);

printf là một hàm định dạng chuỗi mạnh của C. CCS dịch hàm printf rất hiệu quả.

namqn 20-03-2009 05:49 PM

Trích:

Nguyên văn bởi bien_van_khat (Post 23758)
Cách đơn giản nhất ko cần phải viết nhiều code là dùng hàm printf

printf(lcd_putc, "Bien tro: %.4lu", x);

printf là một hàm định dạng chuỗi mạnh của C. CCS dịch hàm printf rất hiệu quả.

printf() có thể định dạng chuỗi tốt, nhưng không giải quyết được vấn đề tốc độ đáp ứng chậm của LCD. Nếu theo hướng này, tôi đề nghị dùng hàm sprintf().

Thân,

black_76 22-03-2009 10:14 PM

Trích:

Nguyên văn bởi namqn (Post 23776)
printf() có thể định dạng chuỗi tốt, nhưng không giải quyết được vấn đề tốc độ đáp ứng chậm của LCD. Nếu theo hướng này, tôi đề nghị dùng hàm sprintf().

Thân,

Thank các bác đã đóng góp, em giải quyết đc vấn đề rồi. Dùng lệnh printf cũng đc, nhưng em vẫn khoái sản phẩm của mình dù có hơi dài. :D. Chỉ đơn giản là khai báo ADC ban đầu bị lỗi. Em sửa khai báo ADC lại là #device ADC 10 là ok. Hì.

yukinohana 22-09-2010 04:59 PM

Cho mình hỏi các giá trị nghìn, trăm, chục và đơn vị của bạn tại sao lại phải +48.

tungnh 23-09-2010 01:49 AM

Trích:

Nguyên văn bởi yukinohana (Post 38825)
Cho mình hỏi các giá trị nghìn, trăm, chục và đơn vị của bạn tại sao lại phải +48.

ví dụ ký tự '2' có giá tri là 2 +'0', ký tự '0' có giá trị là 48

vinh2809 23-09-2010 07:09 PM

Nhân tiện có người hỏi về ADC, các bác cho em hỏi giùm 1 chút.
16F887 có 1 ADC 10bit với 14 kênh AN0 => AN13.
Với lệnh Read_ADC mỗi lần chỉ đọc được 1 giá trị từ chân đã set trong lệnh Set_ADC_channel ( channel ) trước đó.Với channel channel có 0 -7 :
0-chân A0(AN0)=> 7-chân E2(AN7) (theo tài liệu của bác Trần Xuân Trường BK HCM trên forum) như vậy là thiếu có đúng không ?
Đáng nhẽ phải channel phải từ 0=>13 tương ứng với 13 kênh chứ
Hàm delay để trả về kết quả đúng là 10 micro giây hay 10 mili giây thế các bác ???

yukinohana 23-09-2010 11:45 PM

Adc
 
Trích:

Nguyên văn bởi vinh2809 (Post 38847)
Nhân tiện có người hỏi về ADC, các bác cho em hỏi giùm 1 chút.
16F887 có 1 ADC 10bit với 14 kênh AN0 => AN13.
Với lệnh Read_ADC mỗi lần chỉ đọc được 1 giá trị từ chân đã set trong lệnh Set_ADC_channel ( channel ) trước đó.Với channel channel có 0 -7 :
0-chân A0(AN0)=> 7-chân E2(AN7) (theo tài liệu của bác Trần Xuân Trường BK HCM trên forum) như vậy là thiếu có đúng không ?
Đáng nhẽ phải channel phải từ 0=>13 tương ứng với 13 kênh chứ
Hàm delay để trả về kết quả đúng là 10 micro giây hay 10 mili giây thế các bác ???

Về cái ADC nếu muốn xem pic có bao nhiêu chân adc thì chỉ cần đọc datasheet của con pic đó là được rồi. Con 16f877a thì chỉ có 8 kênh adc từ an0 đến an7 thôi bạn àh.
Còn hàm delay thì tùy bạn dùng delay_ms hay là delay_us thì nó trả về micro giây hay mili giây.
Sẵn tiện cảm ơn tungnh đã giải đáp thắc mắc của mình.

vinh2809 24-09-2010 02:15 AM

[QUOTE=yukinohana;38859]Về cái ADC nếu muốn xem pic có bao nhiêu chân adc thì chỉ cần đọc datasheet của con pic đó là được rồi. Con 16f877a thì chỉ có 8 kênh adc từ an0 đến an7 thôi bạn àh.
Còn hàm delay thì tùy bạn dùng delay_ms hay là delay_us thì nó trả về micro giây hay mili giây.
Ko, em nhìn rõ ràng bác Trường viết là 16F887 nên mới thắc mắc mà, cũng có thể là sơ suất gõ thiếu chữ A.
Còn cái trễ em hỏi là sau khi thực hiện Set_ADC_channel ( channel ) đợi trễ một thời gian rồi mói thực hiện hàm read_ADC ( ) để đảm bảo kết quả đúng. Trong tài liệu bác trường nói là 10 micro giây nhưng trong 1 số bài hướng dẫn khác lại không phải là con số này nên em thắc mắc là bao nhiêu thì chính xác ?


Múi giờ GMT. Hiện tại là 01:05 AM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam