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)
-   -   Mới học ADC - vướng mắc 1 số chỗ xin được hỏi (http://www.picvietnam.com/forum/showthread.php?t=2228)

nhong 08-04-2008 01:30 AM

Mới học ADC - vướng mắc 1 số chỗ xin được hỏi
 
em đang tập dùng chức năng adc của pic nhưng gặp 1 số vấn đề như vầy,

*acquisition time, em ko biết tính cái khoảng delay trong đoạn code sau như nào, nó có phụ thuọc vào osc mà mình dùng ko
Code:

setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
delay_us(10);

*realtime convert, nghĩa là em muốn nó nhận biết sự thay đổi liên tục ấy, vd em thay đổi điện áp vào ANx 1 cái thì làm sao để thằng led 7 đoạn nó cũng thay đổi theo tương ứng, vì em mới chỉ biết cách lấy giá trị Digital từ đầu vào Analog(giá trị tĩnh).

*adc của em xuất ra 10 bit(2 thanh ghi) nhưng mà cổng xuất như portB chỉ có 8 bit, thì làm thế nào để giữ nguyên dc độ chính xác(Vref/1024) hoặc là giảm độ chính xác xuống 8 bit(Vref/256)

*có bác nào có đoạn code hiển thị điện áp vào ANx (analog) ra led 7 đoạn thì cho em xin tham khảo(viết bằng CCS C)

code em viết thì thế này, cái này em mới chỉ cho hiển thì qua 8led trên cổng B thôi, em dùng hàm while và delay để lặp đi lặp lại quá trình convert trong 1 khoảng delay nhất định thì đầu ra digital cũng thay đổi được khi mình thay đổi điện áp vào nhưng hình như ko ổn lắm vì nó cứ nhấp nháy, ko liền mạch, các bác các thầy chỉ giáo hộ em chút, em xin cám ơn!

Code:

#include <16f877a.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
void main()
{
float voltage;
//thiet lap che do cho portb
trisa=0xff;
trisb=0x00;
trisc=0x00;
trisd=0x00;
trise=0x00;

//adc intiate
setup_adc(adc_clock_internal);
setup_adc_ports(an0);
delay_us(20);
//read
while (true){
voltage=(float)read_adc();
portb=voltage;
delay_ms(100);
portb=0;
delay_ms(100);
}
}


namqn 08-04-2008 01:57 AM

Acquisition time phụ thuộc vào nhiều yếu tố, bạn tham khảo trong datasheet về cách tính và chọn. Để hiện thực được thời gian này thì lẽ đương nhiên phải dựa vào tần số thực thi lệnh của PIC.

Realtime conversion phụ thuộc vào cách bạn viết code, và tiêu chí "realtime" của bạn (nếu bạn muốn ngõ vào thay đổi thì sự thay đổi phải được phản ánh trong vòng 10 us thì xin thưa là không có PIC 8-bit nào làm được chuyện này).

Bạn có thể dùng 8-bit cao nhất của kết quả để hiện thị trên một port 8-bit. Tất nhiên những thay đổi trong phạm vi 2 bit thấp nhất thì không được thể hiện.

Ngay trước khi chuyển đổi một giá trị ngõ vào, bạn phải chờ một khoảng thời gian (acquisition time), sau đó mới chuyển đổi giá trị ngõ vào đã được giữ lại. Thời gian này không được quá nhỏ, cũng không nên quá lớn. Code của bạn dùng ít nhất 200 ms cho khoảng thời gian này, như vậy là quá lâu. Port B là một port nhận giá trị nhị phân, bạn lại chuyển đổi kết quả A/D thành số float, tôi không rõ bạn làm vậy để làm gì. Bạn nên dùng portb = readadc() >> 2; để hiển thị 8-bit cao nhất thì tốt hơn.

Sau mỗi lần hiển thị kết quả A/D được 100 ms thì bạn lại xuất 0 ra port B và chờ 100 ms, như vậy các LED của bạn có vẻ rung rung với tần số khoảng 5 Hz là điều dễ hiểu.

Thân,

nhong 09-04-2008 01:25 AM

1 Attachment(s)
Em viết lại code như bác namqn chỉ dẫn, bỏ cái đoạn tắt led với cả float đi thì chạy ngon roài, thanx bác nhiều nhé

Nhưng có vấn đề thế này, câu lệnh "read_adc() >>2" theo em hiểu là dùng adc 8bit bỏ đi 2 bit least significant rồi, nhưng tại sao khi đưa điện áp kịch vào ngõ ANx (ANx = Vref) thì chỉ có 6 led sáng nghĩa là sao, theo em nghĩ thì nó phải sáng cả 8 bit của portB chứ.

Thêm nữa là tham khảo bài đo nhiệt độ dùng PIC của bác linhnc thì thấy có đoạn code như thế này, cái chỗ float đấy em cũng ko hiểu lắm với cả em thấy đoạn hiển thị bác ấy cũng bật led rồi tắt led đi mà(thấy nói là quét led 7 đoạn thì phải như thế), như thế là sao nhỉ


Code:

// Lay mau nhiet do lan dau tien
      value=(float)read_adc();
      value = (value - 558.5)/2.048;        // For 5V supply

hiển thị ra 2 led 7 đoạn: ở đây dùng cổng RD để kích mở cho led 7segs

Code:

void display()
{
  PORTB=temp_lowbyte;        // Gửi dữ liệu đến  LED 1
  RD0=0;                    // bật led 1, led 1 có giá trị hàng đơn vị của nhiệt độ
 
  delay_ms(2);            // Cho trễ 2ms
  RD0=1;                    // tắt LED 1

  PORTB=temp_highbyte;      // LED 2
  RD1=0;
  delay_ms(2);
  RD1=1;
}


nhong 10-04-2008 10:36 PM

chán quá, ko có ai giúp em à

namqn 11-04-2008 12:16 AM

Vì code của bạn không dùng directive #DEVICE ADC= nên tôi cũng không đoán được kết quả của hàm read_adc() là bao nhiêu bit. Theo như bạn thử nghiệm, hàm read_adc() trả về kết quả 8-bit, do đó chỉ cần dùng portb = read_adc() chứ không cần dịch phải 2 bit. Từ trước đến giờ, tôi chỉ dùng tài liệu hướng dẫn của CCS C để trả lời các câu hỏi liên quan đến CCS C của các bạn, chứ bản thân tôi chưa hề dùng CCS C (điều này cũng cho thấy các bạn có thể tự giúp mình nếu chịu khó đọc tài liệu hướng dẫn).

Thân,

nhong 11-04-2008 06:02 PM

uhm em viết thêm #device adc=8 giờ ngon rồi, ko cần dịch nữa. thanks bác nhé


Múi giờ GMT. Hiện tại là 11:10 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