Sida 1 av 1
A/D frågor AVR (C )
Postat: 27 april 2007, 18:22:55
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
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.
Postat: 27 april 2007, 18:25:03
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å.
Postat: 27 april 2007, 18:28:09
av klintan
Databladet på atmega128an säger "8 multiplexed single ended channels" och sen ger pinouten att de är alla PAx
Postat: 27 april 2007, 18:33:06
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.
Postat: 27 april 2007, 18:37:52
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.
Postat: 27 april 2007, 19:55:32
av karlstedt
Använder du WinAVR?
Postat: 28 april 2007, 00:40:26
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.
Postat: 28 april 2007, 00:49:18
av klintan
yes använder Winavr, japp hitta en funktion. Skall göra klart imorgon. tack för all hjälp

Postat: 28 april 2007, 00:53:19
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.
Re: A/D frågor AVR (C )
Postat: 28 april 2007, 11:30:25
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.
Postat: 28 april 2007, 18:41:24
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.