Sida 1 av 1

Hantering av signed integers i C

Postat: 13 juni 2005, 23:54:59
av frejo
Tänkte att det var lika bra att starta en ny tråd när det är ett nytt problem. Det är fortfarande en atmega32.

Håller på och samplar en signal i differential mode på AD0 och AD1 då den svänger runt nollan och jag vill ha med tecknet.

Problemet är att från AD:n får jag ett 10-bitars signed värde och det ska jag lagra i en signed 16-bitars integer så jag måste flytta tecknet.
Trodde att det bara var att göra på följande sätt:

Kod: Markera allt

s16 buffert[250];

Kod: Markera allt

		
buffert[samplecounter] = a2dConvert10bit(ADC_CH_1_0_DIFF10X);
// Check if sign bit is set
if((buffert[samplecounter] & 0b0000001000000000)==0b0000001000000000) 
{     // move the sign to the 16th bit instead of the 10th
	buffert[samplecounter] &=~0b0000001000000000;
	buffert[samplecounter] |=0b1000000000000000;
}
Men de negativa värdena tenderar att hamna på -500, dvs nära min för ett 10-bitars signed värde. Jag misstänker att det är nån form av två-komplementsrepresentation som jag missar... men är alldeles för trött av en dags trial and error ;)
Vore tacksam för lite hjälp.

Postat: 14 juni 2005, 08:21:48
av Icecap
För att få det rätta värde gäller detta:
0b0000001xxxxxxxxx ska konverteras till 0b1111111xxxxxxxxx - 1 för att värdet ska bli rätt. (sök på one's complement)

Alltså:
if(buffert[samplecounter] >= 0b0000001000000000)
{ // move the sign to the 16th bit instead of the 10th
buffert[samplecounter] = 512 - (buffert[samplecounter] & 511);
}

Postat: 14 juni 2005, 09:19:18
av frejo
Tackar!

Även om den koden inte funkade direkt, kan det ha att göra med att - har högre prioritet än & kanske?

Hur som helst jag gjorde så här:

Kod: Markera allt

buffert[samplecounter] |= 0b1111111000000000;
buffert[samplecounter]--;
Den samplade sinusvågen gick från att ha sett ut så här:
Bild

Till att se ut så här:
Bild

Så himla underbar start på dagen :D

Postat: 14 juni 2005, 09:27:24
av simon78
Vilken samplingsfrekvens lyckas du komma upp i?

Postat: 14 juni 2005, 09:38:21
av frejo
Nu kör jag i 8khz vilket är tillräckligt då den högsta signalen jag ska sampla är 1.6khz.
Vet inte hur effektiv min adc kod är men omvandligen tar ca 30uS (med en prescaler på 32) av den 125uS långa perioden som blir mellan varje interrupt.

Har en polare som precis skrivit en fft för avr:n, han kör i närmare 30khz.

Postat: 14 juni 2005, 10:27:50
av Icecap
Vad bra att det blev löst. Det är ju faktisk en aning skillnad på kurvorna :humm: