www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

ADC library

 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Microchip PIC
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
grecko453
Član
Član



Pridružen-a: Pet 24 Sep 2010 13:02
Prispevkov: 86
Aktiv.: 0.45
Kraj: Ljubljana

PrispevekObjavljeno: Pon Jan 31, 2011 10:24 am    Naslov sporočila:  ADC library Odgovori s citatom

Za programiranje uporabljam mikropascal, vendar sem pri uporabi ADC knjižnice naletel na omejitev.
V help fajlu je za ADC knjižnico naslednje opozorilo:
Note : This function doesn't work with the external voltage reference source, only with the internal voltage reference.
Torej v prevodu;
ne morem uporabiti obstoječe knjižnice, če želim določiti, da Vref ne bo Vcc, ampak napetost na nekem od AN pinov.
Sicer sem pregledal datasheet za PIC16F886, kjer z bitom VCFG0 (ADCON1 register) določaš z 0 = Vdd, z 1 = Vref+ pin. Vendar mi to nič ne koristi, ker pascalova knjižnjica ne omogoča izbire Vref pina.

Če je kdo tako prijazen bi prosil za pomoč.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
grecko453
Član
Član



Pridružen-a: Pet 24 Sep 2010 13:02
Prispevkov: 86
Aktiv.: 0.45
Kraj: Ljubljana

PrispevekObjavljeno: Pon Jan 31, 2011 11:04 am    Naslov sporočila:   Odgovori s citatom

Našel sem en podoben primer za dsPIC30F6014. Vendar preveč zame, da bi priredil za 16F886.

Koda:
function My_Adc_Read(ch: byte): word;
// Will use external Vref+ on pin RA10 instead of internal Vdd Vref
// as done by ADC_Read. Tested on dsPICPRO with dsPIC30F6014 mikroPascal 4.0.0.0
// library ADC_Read destroys ADCON2 before converting thus making impossibile
// to use external VREF+
begin
  ch := ch and $000F;  // ch must be in range 00..15 (Dec)
  SetBit(TRISB,ch);    // Configures pin on PORTB as input
  ADPCFG := 0;
  ClearBit(ADPCFG,ch); // Chth channel will be sampled and converted
  ADCON1 := $00E0;     // ADC=off, Output_format=INTEGER,
                       // automatic start of conversion after end of sampling,
                       // manual start of sampling
  ADCHS  := ch;        // Connect RBch on ANch as DAC +input (-input at Vref-)
  ADCSSL := 0;         // No scan
  ADCON3 := $1F1B;     // ADCS=27 (27*Tcy = 337 ns > 333 required)
                       // Value is right for FOsc = 80 MHz.
  ADCON2 := $2000;     // Interrupt on completation of 1 sample
                       // External VRef+
  ADCON1.15 := 1;      // ADC on
  ADCON1.1  := 1;      // SAMP=1, start sampling
  while ADCON1.0 = 0 do nop;  // Wait for DONE bit in ADCON1
  result := ADCBUF0;   // Returns the result
end;
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
gumby
Član
Član



Pridružen-a: Sob 28 Apr 2007 12:32
Prispevkov: 4066
Aktiv.: 17.60

PrispevekObjavljeno: Pon Jan 31, 2011 11:50 am    Naslov sporočila:  Re: ADC library Odgovori s citatom

grecko453 je napisal/a:
Note : This function doesn't work with the external voltage reference source, only with the internal voltage reference.

Tole je dovolj dober razlog, da nehaš uporabljat debilne knjižnice in napišeš svoje rutine za AD pretvorbo...

Nastaviti moraš naslednje registre:
TRISx (vse analogne pine nastavi na vhod)
ANSEL, ANSELH (analogni vhodi)
ADCON0 (hitrost pretvorbe, izbira vhoda, vklop AD)
ADCON1 (poravnava, +/- referenca)
INTCON, PIE1, PIR1 (če uporabljaš prekinitev za AD)
Pretvorbo štartaš z postavitvijo bita GO/DONE v ADCON0.
Rezultat pretvorbe bo v ADRESH/ADRESL...

Sicer pa poglej datasheet (poglavje 9.2), je vse lepo napisano Wink

_________________
Tule nisem več aktiven.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
grecko453
Član
Član



Pridružen-a: Pet 24 Sep 2010 13:02
Prispevkov: 86
Aktiv.: 0.45
Kraj: Ljubljana

PrispevekObjavljeno: Tor Feb 01, 2011 7:09 pm    Naslov sporočila:   Odgovori s citatom

koda gre takole:

Koda:
program vaja;

procedure ad();
begin
ADCON0.7-6:=01;  //fosc/8
ADCON0.0:=1;  //enable ADc
ADCON1:=%00010000;  //adfm=0, Vref- = Vss, Vref+ = pin
delay_us(5);        //required acquisition time
ADCON0.1:=1;  //start conversion
repeat
until ADCON0.1=0;   //wait for ADC conversion to complete
end;


var adc:integer;
    txt:string[16];
   
begin
TRISA:= %11111111;  //RA0-7 as input
ANSEL:= %11111111;  //AN0-7 are enabled
ANSELH:=%00000000;  //AN8-13 are disabled
LCD_Config(PORTB,3,2,1,0,PORTB,4,7,5); //configure LCD on portA
LCD_Cmd(LCD_CLEAR);      // clear display
LCD_Cmd(LCD_CURSOR_OFF); // turn cursor off

while true do
begin
ADCON0.3-0:=%0010;   //read from AN2 pin
ad();
adc:=ADRESH*4; //read upper 8 bits of 10bit conversion and multiply by 4 (ADRESH register)
intToStr(adc,txt);
LCD_Out(1,11,txt);
end;
end.


nekaj nejasnosti kljub prebranemu poglavju 9.2 še vedno imam.
1. v datasheetu je neka formula za minimalni čas potreben med nastavitvijo ADCON1 registra in trenutkom ko poženeš konverzijo. Zanima me ali je 5us? V formulo se nisem poglabljal je pa v formuli uporabljena napetost Vapplied in Vchold
2. druga stvar, ali rabim kakšen kondenzator na vhodu AN pinov? Zato ker v datasheetu je nek graf med kapativnostjo in časom in omenjo je nekaj glede puščanja pin (pin leakage).
3. nekaj težav imam pri branju iz registra ADRESH in ADRESL. nastavil sem levo poravnavo kar pomeni da imam v registru ADRESH zgornjih 8bitov in številka gre 0d 0 do 255 (logično glede na to da je 2^8, 255), nejasno pa mi je zakaj če berem samo ADRESL register mi da vrednost med 0 in 192, čeprav bi morala biti tu samo dva spodnja bita, torej od 0 do 4.
Formulo za branje ADC vrednosti sem si zamislil takole: adc:=ADRESH*4+ADRESL, vendar kot rečeno ADRESL gre vse do 192.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
gumby
Član
Član



Pridružen-a: Sob 28 Apr 2007 12:32
Prispevkov: 4066
Aktiv.: 17.60

PrispevekObjavljeno: Tor Feb 01, 2011 7:50 pm    Naslov sporočila:   Odgovori s citatom

1: kondenzator rabi par us, da se napolni na vrednost, ki je na vhodu... zato po izbiri analognega vhoda (CHSx biti v ANSEL) počakaj par us, preden zaženeš pretvorbo (če ne spreminjaš vhodnega pina, potem ni treba čakat)
2: prikazan je model analognega vhoda, tistih 500nA predstavlja izgube... tu je najbolj pomembno, da imaš nizko impedanco na vhodu, kondenzator načeloma ni potreben
3: poglej, kje sta tista dva bita v registru ADRESL, ko imaš levo poravnavo Wink

Če misliš uporabit vseh 10 bitov je bolj praktično imet desno poravnavo, takrat samo ADRESH pomnožiš z 256 (shift levo za 8 bitov) in prišteješ ADRESL. Za 8 bitov je pa bolj praktična leva poravnava, takrat je rezultat kar ADRESH (spodnja dva bita ignoriraš).

_________________
Tule nisem več aktiven.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
gumby
Član
Član



Pridružen-a: Sob 28 Apr 2007 12:32
Prispevkov: 4066
Aktiv.: 17.60

PrispevekObjavljeno: Tor Feb 01, 2011 8:01 pm    Naslov sporočila:   Odgovori s citatom

Še nekaj glede programa: načeloma se nastavitev parametrov za AD pretvornik izvede samo enkrat. Nato v zanki določiš vhodni kanal in štartaš pretvorbo (ter odčitaš rezultat). Če vedno bereš isti kanal, potem niti kanala ni treba vedno znova nastavljat v zanki, ampak to storiš samo 1x med nastavitvijo ostalih parametrov.
_________________
Tule nisem več aktiven.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
grecko453
Član
Član



Pridružen-a: Pet 24 Sep 2010 13:02
Prispevkov: 86
Aktiv.: 0.45
Kraj: Ljubljana

PrispevekObjavljeno: Sre Feb 02, 2011 12:37 am    Naslov sporočila:   Odgovori s citatom

Prvo Hvala za vso pomoč!

Drugo a bi bilo takole ok?
ali bi bilo v obliku funkcije boljše? (na mikroE forumu so mi svetovali naj naredim raje v obliku funkcije) =>
Both solutions are acceptable, though a function with result of type word seems more convenient (Lo(result):=ADRESL, Hi(result):=ADRESH). The input number to be used may be set as function parameter
vendar nisem ravno razumel ta "lo" in "hi", ker lo(ADRESL) bi vrnil 0ti in prvi bit vrednosti registra ADRESL, hi(ADRESH) pa 00, v primeru desne poravnave (ali se motim)?

Koda:
program vaja;

procedure ad();
begin
delay_ms(10); //alow acquisition time
ADCON0.1:=1;  //start conversion
repeat
until ADCON0.1=0;   //wait for ADC conversion to complete
end;


var adc1,adc2:integer;
    txt:string[16];
   
begin
TRISA:= %11111111;  //RA0-7 as input
TRISC:=$ff;
ANSEL:= %11111111;  //AN0-7 are enabled
ANSELH:=%00000000;  //AN8-13 are disabled
ADCON0.7-6:=01;     //fosc/8
ADCON1:=%10010000;  //adfm=1, Vref- = Vss, Vref+ = pin
ADCON0.0:=1;        //enable ADC
LCD_Config(PORTB,3,2,1,0,PORTB,4,7,5); //configure LCD on portB
LCD_Cmd(LCD_CLEAR);      // clear display
LCD_Cmd(LCD_CURSOR_OFF); // turn cursor off

while true do
begin
ADCON0.3-0:=%0000;   //read from AN0 pin
ad();
adc1:=ADRESH*256 + ADRESL; //read ADRESH & ADRESL registers to get 10 bit ADC value
intToStr(adc1,txt);
LCD_Out(1,1,txt);

ADCON0.3-0:=%0010;   //read from AN2 pin
ad();
adc2:=ADRESH*256 + ADRESL; //read ADRESH & ADRESL registers to get 10 bit ADC value
intToStr(adc2,txt);
LCD_Out(2,1,txt);
end;
end.


imam pa še eno praktično vprašanje. Trenutna ploščica, ki je že izdelana ima na ADC priključeno temperaturno tipalo tipa KTY10. Tipalo je vezano v napetostni delilnik z 3.24k pull down uporom. Napetost med merjenim območjem (-10 do 100°C) tako niha med cca 2.5 in 3.5V, torej diferenca je samo 1V.
Zanima pa me slednje.
Zahteva ni natančnost na decimalke, zgolj absolutna in relativna točnost na nekaj stopinj celzija. Torej pri diferenci 1V koristim 20% širine 10 bitnega AD konverterja kar je za moje pojme dovolj, da dobiš točno teperaturo. Formulo za temperaturo sem dobil tako da sem s pomočjo excela, narisal graf odvisnosti upornosti od temperature.
V prvi stolpec sem vnesel vrednosti ADCja od 0 do 1023, v drugem računam upornost senzorja po formuli Rs=R2*1023/ADC-R2 in v tretjem temperaturo po T=25+(sqrt(a*a-4*b+4*b*Rs/R25)-a)/(2*b). vrednosti a, b, R2 in R25 so konstante.
Sedaj sem ta graf razdelil pri temperaturi 55°C na dve linearni funkciji in to sta moji formuli za računanje temperature.

Temperaturo zaokrožam na celo številko, vseeno pa mi zadeva deluje zelo čudno, saj trenutna temperatura niha tudi do 3°C. Kar pomeni da recimo kaže 20, potem 22 in nato 19....
Torej tu nekaj ne štima.
Napetosni delilnik je napajan iz istega izvora (Vcc) kot dobi ADC referenčno napetost, tako da nihanje napetosti ne bi smelo vplivati. Prav tako je upor in temp senzor na stalni temperaturi, tako da tudi ne bi smel nihati.

Zastavlja se mi vprašanje, če bom z nastavljanjem referenčnih napetosti ADCja na Vref+=3.5 in Vref-=2.5V, sploh kaj pridobil. Res je da bom imel na razpolago več vrednosti pretvorbe, vendar če je zahteva natančnost na nekaj stopinj ali je to sploh smiselno, saj imam pri trenutnem 20% izkoristku vrednosti ADCja 2 vrednosti na vsako stopinjo.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
gumby
Član
Član



Pridružen-a: Sob 28 Apr 2007 12:32
Prispevkov: 4066
Aktiv.: 17.60

PrispevekObjavljeno: Sre Feb 02, 2011 8:35 am    Naslov sporočila:   Odgovori s citatom

Preračunaj, koliko znaša 1 bit v stopinjah. Malo šuma bo namreč nonstop prisotnega, torej bo rezultat pretvorbe skakal gor-dol.
Za zmanjšanje tega se boš moral malo potrudit glede samega analognega dela vezja... ločitev napajanja, filtriraneje motenj, precizne reference za Vref+ in Vref-, itd. Na to temo je že par debat na forumu (in tudi drugje), malo preišči...
Poleg tega lahko AD pretvorbo izvedeš v sleep-u, kjer se procesor v bistvu ustavi in se na ta način eliminira večina motenj, ki jih povzroča (poglej datasheet, kako to izvesti).
Na koncu lahko rezultat pretvorbe tudi povprečiš, da še nekoliko zmanjšaš skakanje rezultata...

_________________
Tule nisem več aktiven.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
GJ
Član
Član



Pridružen-a: Čet 02 Nov 2006 15:51
Prispevkov: 946
Aktiv.: 3.99
Kraj: Ljubljana

PrispevekObjavljeno: Sre Feb 02, 2011 9:30 pm    Naslov sporočila:   Odgovori s citatom

Ahh…
No ja za hobi temometrček je tole vezje verjetno čisto ok, pač odvisno s čim boš (si) zadovoljen.
Z 10 bitnim ADC-jem se da doseči bistveno boljše meritve kot si jih navedel ti.
Metoda vzorčenja, ki jo uporabljaš ni ravno ustrezna. Vzorčenje z internim MCPU ADC-jem se ponavadi ne vrši v sami aplikaciji temveč v prekinitveni rutini. Recimo, da je frekvenca oscilatorja 16MHz, v tem primeru koristiš recimo prekinitev TMR0, ki jo nastaviš tako, da se izvede vsakih 128us oziroma 512 strojnih ciklov, Pic potrebuje 4 nihaje oscilatorja, da izvede en strojni cikel. V prekinitveni rutini bereš, multipleksiraš in prožiš ADC, rezultate posameznega kanala v sami prekinitveni rutini integriraš (seštevaš) v 24 bitni variabli. Po recimo 1000 pretvorbah pa prekopira prekinitvena rutina ta rezultat v novo variablo in pobriše variablo integratorja, hkrati pa postaviš zastavico aplikaciji, da ve, da je seštevek tisočih zaporednih meritev pripravljen. Aplikacija termometra v ozadju čaka, da se zastavica postavi nakar prebere vrednost in pobriše zastavico, nakar vrednost preko enačb spremeni v temperaturo. Takšna prekinitvena rutina, če je lepo napisana porabi okoli 10% procesorskega časa ostalo pa ostane za aplikacijo termometra. In seveda, čas takšnega prečenja (če izvajaš le eno meritev) je 128us * 1000 torej 0.128s v tem času pa mora tudi aplikacija narediti svoj del naloge.
Če želiš uporabiti KTY10 tako, da boš iztisnil iz njega maksimalno boš potreboval še dva operacijska ojačevalnika (Rail to Rail in/out; recimo: MCP6002), prvi ti mora generirati konstanten tok za napajanje KTY10 senzorja in ta je ponavadi med 0.2 do 1mA, drugi mostiček pa ti pretvori merilno območje v napetostno območje merjenja ADC-ja. In ne potrebuješ nikakršnih hudih napetostnih referenc ali pa ločenih napajanj, za napajanje ADC-ja, skupnih 5V iz LM1117 je povsem dovolj stabilnih, če boš mostičke operacijskih ojačevalcev krmilil z isto napetostjo. Natančnost takšnega termometra v območju od -30 pa do 120oC lahko dosežeš, če ga predhodno dobro programsko umeriš, na 0.2oC. Največji problem je sam KTY10 in njegovo staranje in nelinearnost, če pa uporabiš Pt1000 boš brez problema dosegel natančnost 0.1oC.

LP GJ
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Microchip PIC Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Stran 1 od 1

 
Pojdi na:  
Ne, ne moreš dodajati novih tem v tem forumu
Ne, ne moreš odgovarjati na teme v tem forumu
Ne, ne moreš urejati svojih prispevkov v tem forumu
Ne, ne moreš brisati svojih prispevkov v tem forumu
Ne ne moreš glasovati v anketi v tem forumu
Ne, ne moreš pripeti datotek v tem forumu
Ne, ne moreš povleči datotek v tem forumu

Uptime: 233 dni


Powered by phpBB © 2001, 2005 phpBB Group