A/D frågor AVR (C )

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
klintan
Inlägg: 307
Blev medlem: 13 juni 2003, 01:59:05
Ort: Ekerö

A/D frågor AVR (C )

Inlägg av klintan »

Har lite frågor angående A/D och c kodning på AVR.

Fråga 1.
Tänkte först fråga om det går att känna av 3 kanaler samtidigt och/eller hämta deras register eller om man måste göra det var för sig? Alltså läs första hämta i ADC, sen hämta nästa läsa osv. eller om det går att göra samtidigt för alla ? i olika register. kör atemga 128.

Fråga 2.
När jag hämtar mitt värde på det sätt de står i databladet alltså med

Kod: Markera allt

x = ((5*ADC)/1024);
där 5 är AREF.
Då får jag endast ut ett helttal med koden

Kod: Markera allt

int temp = checkacc();

stdout=&mystdout;
printf("%d",temp);
men då undrar jag dels vad som returneras? Har definerat x som int variabel. Men jag är inte så haj på vad de i C innebär med en vanlig int. får jag ut ett decimal tal ? Eller returneras ett värde men min kod skriver inte ut rätt värde ? med printf kommandot?

Fråga 3.
Kan man använda free running mode för att överföra värden till en tabell på datorn till exempel en txt fil i realtid? Det är det jag vill åstadkomma med min kod, men tänkte att man kanske som fråga 1 berör, köra en kanal i taget å sedan plocka värden en efter en så nära realtid de går.




Mkt av dessa frågor finns säkert att läsa, har läst en hel del C tutorials och sådant men är ännu nybörjare på språket. Samma sak med A/Dn på AVRen.
v-g
EF Sponsor
Inlägg: 7875
Blev medlem: 25 november 2005, 23:47:53
Ort: Kramforce

Inlägg av v-g »

Vet ej 100% hur det är på AVR men på de andra µc jag träffat på är det iaf så att du har en kanal som du kan välja från vilken pinne den skall ta. Man kan få flera än dessa genom tex en switch om man så önskar.

Ett exempel på den typ av switch jag menar är denna, därmed inte sagt att just denna är så lämpad för det har jag inte 100% koll på.
Senast redigerad av v-g 27 april 2007, 18:28:53, redigerad totalt 1 gång.
klintan
Inlägg: 307
Blev medlem: 13 juni 2003, 01:59:05
Ort: Ekerö

Inlägg av klintan »

Databladet på atmega128an säger "8 multiplexed single ended channels" och sen ger pinouten att de är alla PAx
ASTRX
Inlägg: 68
Blev medlem: 12 januari 2005, 16:58:13

Inlägg av ASTRX »

en int är en integer = heltal.

x måste definieras som en double alt. float för att vara flyttal. då används %f i printf() istället för %d.

Kod: Markera allt

double x;
x = (5.0*ADC)/1024.0;
printf("%f",x);
vad gäller multiplexningen så skriver du till ADMUX-registrets 3 lägsta bitar vilken av de 8 (0-7) kanalerna du vill mäta på. kolla i databladet.
klintan
Inlägg: 307
Blev medlem: 13 juni 2003, 01:59:05
Ort: Ekerö

Inlägg av klintan »

aha ok . tack det löste en del. Men nu vill inte UART funktionen skriva ut double värdet, de blir bara massa frågetecken . Ska testa att bara göra om värdet till char och sen skicka de på vanligt sätt till UARTen.
Användarvisningsbild
karlstedt
EF Sponsor
Inlägg: 966
Blev medlem: 14 oktober 2003, 16:55:23
Ort: Lund
Kontakt:

Inlägg av karlstedt »

Använder du WinAVR?
ASTRX
Inlägg: 68
Blev medlem: 12 januari 2005, 16:58:13

Inlägg av ASTRX »

klintan skrev:aha ok . tack det löste en del. Men nu vill inte UART funktionen skriva ut double värdet, de blir bara massa frågetecken . Ska testa att bara göra om värdet till char och sen skicka de på vanligt sätt till UARTen.
tänk på att du måste göra om VARJE siffra till character "char" och sen skicka till UART. finns algoritmer för detta, ganska enkla att implementera. sök på atmels sida.
klintan
Inlägg: 307
Blev medlem: 13 juni 2003, 01:59:05
Ort: Ekerö

Inlägg av klintan »

yes använder Winavr, japp hitta en funktion. Skall göra klart imorgon. tack för all hjälp :)
Användarvisningsbild
dayzleaper
Inlägg: 128
Blev medlem: 15 januari 2007, 10:25:24
Ort: Sundsvall
Kontakt:

Inlägg av dayzleaper »

En lite fulare lösning (som dock tar mer plats) är att du helt enkelt använder sprintf, istället för att skriva en egen algoritm för det. Bör bara vara att länka till biblioteket vid kompilering.

Jag har en rätt fin generell Makefile till mega128 och WinAVR dessutom, om du skulle behöva.
Användarvisningsbild
$tiff
Inlägg: 4941
Blev medlem: 31 maj 2003, 19:47:52
Ort: Göteborg
Kontakt:

Re: A/D frågor AVR (C )

Inlägg av $tiff »

klintan skrev:Fråga 1.
Tänkte först fråga om det går att känna av 3 kanaler samtidigt och/eller hämta deras register eller om man måste göra det var för sig?
(...)
Nej, det är inte individuella kanaler, de är muxade ihop. Om du vill använda flera samtidigt så kan du slänga ihop ett litet bibliotek som ser till att ADCn automagiskt sekventiellt läser igenom de kanaler du är intresserad av och slänger upp det i exempelvis en tabell. Detta görs effektivt via avbrottshantering.
klintan skrev: Fråga 3.
Kan man använda free running mode för att överföra värden till en tabell på datorn till exempel en txt fil i realtid? Det är det jag vill åstadkomma med min kod, men tänkte att man kanske som fråga 1 berör, köra en kanal i taget å sedan plocka värden en efter en så nära realtid de går.
I realtid; det beror på vilken upplösning och uppdateringsfrekvens du vill åt. Ska du köra ADCn på full fräs kontinuerligt tror jag du kommer få problem med överföringskapaciteten. Däremot, om du bara ska ha några värden i sekunden så är det lätt gjort.
klintan
Inlägg: 307
Blev medlem: 13 juni 2003, 01:59:05
Ort: Ekerö

Inlägg av klintan »

ja så många värden i sekunden som möjligt utan att överföringen blir lidande är väl den farten jag vill uppnå. Har kommit en bit på vägen men jag får inte rätt värden ut från min ADC. Måste man tömma ADC registret sjelv på något sätt innan man testar nästa kanal?
min kod:

Kod: Markera allt


float checkz() 
{ 
float z = 0;
  ADMUX |= _BV(MUX1);
  //ADCSRA |= _BV(ADATE);
    //Start conversion
    ADCSRA |= _BV(ADSC);
    
    // wait until converstion completed
    while (ADCSRA & _BV(ADSC) ) {}
    
    // get converted value
    z = ((5.0*ADC)/1024.0);
    return z;
}

osv. för x, y,z

int main(void){
_delay_ms(500);
init_uart();
ADCSRA |= _BV(ADEN);
while(1){

   char x[8]; 
   float x1;
   x1 = checkx();
   dtostrf( x1, 6, 3, x ); 
    uart_putc('x');
   uart_puts( x );

osv för x,y, z.

resultatet blir värden som går mot 1.381. men börjar på 2,7 v vilket är värdet för z kanalen?

värdena skall vara ungefär: z(AD2) = 2,75 x = 1,65 och y = 1,65 så jag förstår inte hur de kan bli 1.381.


edit1: dtostrf funktionen och koden fick jag från tutorialen på mikrokontroller.net.
Skriv svar