Men eftersom jag skrev ett inlägg i början så ska jag följa upp det:
Divisorn ska vara 1024, annars blir det fel!jesse skrev:om Aref = 5.0 volt, ska man då räkna med att Aref motsvaras av 1024 eller 1023 ?
dvs. ska det vara:
eller ska det varaKod: Markera allt
float volt; int analog; ... analog = ADC; // läs in från ADC volt = analog * 5.00 / 1024;
Kod: Markera allt
float volt; int analog; ... analog = ADC; // läs in från ADC volt = analog * 5.00 / 1023;
Ta exempelvis en tvåbitars AD-omvandlare som exempel, så är det lättare att se vad som händer:
Det binära talet, "rådatan" från omvandlaren kan då anta fyra värden, från 0 till 3.
(De båda bitarna kan bara anta dessa fyra värden: 00, 01, 10 och 11)
om U är referensspänningen så får vi dessa värden ut:
vid spänning mellan 0 och U/4 volt in får vi 00 ut.
vid spänning mellan U/4 och U*2/4 volt in får vi 01 ut.
vid spänning mellan U*2/4 och U*3/4 volt in får vi 10 ut.
vid spänning mellan U*3/4 och U volt in får vi 11 ut.
Då U = 5.0 får vi enligt formeln volt = analog * 5.00 / 4 :
00 --> 0.00 volt
01 --> 1.25 volt
10 --> 2.50 volt
11 --> 3.75 volt
Detta kan se väldigt fel ut i första anblicken, eftersom resultatet bara kan variera mellan 0 och 3.75 volt. Orsaken är att ADC:n alltid avrundar resultatet neråt. Hade vi dividerat med 3 istället så hade vi fått följande resultat:
00 --> 0.00 volt
01 --> 1.667 volt
10 --> 3.333 volt
11 --> 5.000 volt
Vilket ger en mer korrekt fördelning av resultatet, men ändå inte riktigt bra.
Jag anser alltså att det är division med fyra som gäller, men att man istället avrundar till närmaste heltal i stället för att avrunda neråt.
Så resultatet 00 , som alltså motsvarar en verklig inspänning nånstans mellan 0.00-1.25 volt borde ge svaret 0.625 volt - det är medeltalet mellan 0 och 1.25 och är det tal som bäst motsvarar den verkliga spänningen. Formeln blir då:
volt = (analog + 0.5) * 5.0 / 4
och resultaten blir:
00 --> 0.625 volt
01 --> 1.875 volt
10 --> 3.125 volt
11 --> 4.375 volt
På motsvarande sätt, för att få ett så korrekt resultat som möjligt från en 10-bitars ADC, så blir formeln:
volt = (analog + 0.5) * 5.0 / 1024
Man kan göra motsvarande beräkningar med enbart heltal (vilket rekommenderas) istället för med flyttal, men då måste man flytta decimalpunkten några steg, och t.ex. låta resultatet redovisas i millivolt istället för volt. Heltalsoperationer kräver att man tänker till några gånger extra, då alla delresutat avrundas neråt och man kan råka ut för owerflow, så det gäller att ha tungan rätt i mun här.
Det skulle kunna se ut så här:
int analog;
int volt;
...
analog = ADC;
volt = (((uint32_t)analog * 5000 + 2500) / 1024
-------------------------------------------------------
kommentar:
(uint32_t) är en så kallad "typecast"... Då 1023 * 5000 > 5.1 miljoner så får det inte plats i ett 16-bitars heltal (int). Därför omvandlas "analog" till ett 32-bitars heltal innan man utför multiplikationen. Annars skulle man få owerflow och det skulle bli fel. uint32_t är ett sätt att skriva att det är ett 32-bitars heltal och inget annat, och det används bl.a. när man programmerar AVR-processorer. För att förtydliga att det är 16-bitars heltal man arbetar med annars, kan man skriva uint16_t istället för int.