AD-omvandlings problem med pic18

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

AD-omvandlings problem med pic18

Inlägg av rävekorre »

Min output funktion som är testad i en mängd fall fungerar fint med char-argument. Antingen ställer jag upp AD-omvandlingen fel eller så castar jag fel i output. Jag kan inte se något fel i endera. ;)

Gör jag något uppenbart fel? Output() skriver ut 64.

C18, pic18f4431.

Kod: Markera allt

void output(unsigned char);

void initADC(void)
{
		OpenADC( ADC_FOSC_2 & ADC_RIGHT_JUST & ADC_8_TAD,
		ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS,ADC_16ANA);
		Delay10TCYx(50);
	return;
}

unsigned int ADC(void)
{
		Delay10TCYx(50); // Jag blev desperat.
		ConvertADC(); 
		while(BusyADC());
	return ReadADC();
}

void main(void)
{

/*  */
	initADC();
/*  */

	output((char)(ADC()/16)); // Skriver ut värdet
}
EDIT: Tog bort en dum float-cast.
Senast redigerad av rävekorre 12 december 2005, 21:51:06, redigerad totalt 1 gång.
Användarvisningsbild
Icecap
Inlägg: 26641
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Ush vad jag ogillar float. det har all tid ställd till det för mig!

output((char)(((float)ADC()/1024)*64)); // Skriver ut värdet ?????
varför inte:
output((char)(ADC()/16)); // Skriver ut värdet !!!
(1024/64 = 16 om du undrar)
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

Inlägg av rävekorre »

Hehe, jo, jag har provat både 16 och 20. ;) float-castingen borde fungera? Jag skulle gärna behålla det som det står nu (trots förlusten).
Kanske ska tillägga att jag har AN0 pinnen kopplad till en potentiometer som kan variera spänningen mellan 5 och 0 äpplen.
Användarvisningsbild
Icecap
Inlägg: 26641
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Float-castingen innebär att du måste inkludera <float.h> eller vad det nu heter plus att du förlorar mycket minne och hastighet så jag ser INGEN anledning till att float-casta, enbart nackdelar.

Men om du nu vill ha det som det är får du väl acceptera att det inte fungerar...
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

Inlägg av rävekorre »

Är (jag vet inte vad det heter) float en primitiv datatyp? Jag använder float för att bland annat definiera pi (kanske finns detta redan gjort) och det fungerar alldeles ypperligt.

Jag tar bort float, det betyder endast något för mig. Dumt att ta med det här. ;)
Användarvisningsbild
Icecap
Inlägg: 26641
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Jag har enbart haft strul med floats så jag använder dom aldrig!

Jag har programmerat en "otrolig" massa program med uträkninger som heter duga och det går kanonbra utan floats.

Sakern är att du fint kan definierat en float, det som ställer till det är räkningen med dom som är besvärligt, det kräver ofta en hel del datorkraft som jag inte vill offra.

Jag har just avslutat ett stort projekt som utför en seriös stor styrning där en timer ger en 10Hz interrupt och det räknas än hit och än dit med AD-värden osv och tack vara en noga genomgång av uträkninger håller jag timer-ISR'en nere på 60µs!

Så om du vill ha vissa värden av pädagogiska skäl finns det en kommentar-möjlighet....
sodjan
EF Sponsor
Inlägg: 43250
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Om man har float i en kod för en mikrokontroller kan det betyda två saker :

1. Man har efter mycket analys kommit fram till att man *måste* köra med float.
2. Man behöver göra punkt 1 ovan.

Vilket är det ?

I 99 fall av 100 är det alternativ 2 som stämmer... :-)

Det är mycket ovanligt att inte en vanlig fixed point räcker bra.
Behöver du den extra dynamik som en float ger ? Notera att
du inte får högre precision, bara mer dynamik.

Och pi kan säkert aproximeras eller helt plockas bort genom att skala
de andra variablerna på lämpligt sätt. Det är ju bara en konstant i alla fall...

> "...mellan 5 och 0 äpplen."

???
Ser inga andra referenser till äpplen här, kan du förtydliga ?
Användarvisningsbild
flippy
Inlägg: 110
Blev medlem: 10 december 2005, 13:49:44

Inlägg av flippy »

rävekorre skrev:Är (jag vet inte vad det heter) float en primitiv datatyp? Jag använder float för att bland annat definiera pi (kanske finns detta redan gjort) och det fungerar alldeles ypperligt.

Jag tar bort float, det betyder endast något för mig. Dumt att ta med det här. ;)
Jo det är det, och man behöver inte inkludera nån header för att använda den. Pi finns redan definierad som en double i math.h, heter M_PI.
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

Inlägg av rävekorre »

Floaten i det här exemplet är skrotad, men samma fel uppträder. Den behövdes inte, men pi vill jag exempelvis ha som ett flyttal även om det varken är relevant eller nödvändigt.

Jag har (ADC_VREFPLUS_VDD och ADC_VREFMINUS_VSS) som referenser till ADn och har kopplat en potentiometer mellan dem för att kunna variera spänningen mellan alla fall som kan uppträda. Dvs 5 och 0 volt.
sodjan
EF Sponsor
Inlägg: 43250
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> men pi vill jag exempelvis ha som ett flyttal även om det varken är relevant eller nödvändigt.

OK, ingen anledning att tjata, du lär dig (kanske) med tiden...

Vilken pinne sitter insignalen på ?
Du har ingen SetChanADC(chan), och jag vet inte vad som är default.
Om jag har förstått rätt så får du alltså 1023 från ADC'n hela tiden ?
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

Inlägg av rävekorre »

Double finns ju trots allt. ;)

Potentiometern är kopplad till ben/pinne 2 (RA0/AN0).

Jag provade med SetChanADC(ADC_CH0); , men den ska användas till att byta kanal så jag tog bort den. (Slösar tid om något).

ADC_CH0 sätter jag i OpenADC().

Ja, det tyder på att jag får 1023 från ADC hela tiden.
sodjan
EF Sponsor
Inlägg: 43250
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Du har väll kollat assembler koden som genereras av OpenADC så att det ser OK ut ?
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

Inlägg av rävekorre »

Nej, att följa den fixar jag inte. Det genereras "löjligt" mycket kod. Jag måste väl mer eller mindre kunna förutsätta att den genereras "rätt"?
sodjan
EF Sponsor
Inlägg: 43250
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Jag måste väl mer eller mindre kunna förutsätta att den genereras "rätt"?

Jo, om dina parametrar till OpenADC är "rätt"...

Jag får inte ihop det riktigt mot manualen...

Hur som helst, OpenADC i sig bör inte generera mer än ca 10-20 rader.
Och det är ju lätt att leta efter de rellevanta registeren och se hur de sätts
upp (ADCON0, ADCON1 och ADCON2, om de heter så på din processor).
Det är det snabbaste sättet att kolla vad kompilatorn har för sig...

Ger inte C18 en assembler listning där C-raderna ligger som kommenterar ?
Så att det är lätt att hitta ?

Hur som helst, du får nog välja dig med att läsa assembler listor från C18,
det är en viktig del av debuggning...

> Det genereras "löjligt" mycket kod.

En av orsakerna att undvika float...
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

Inlägg av rävekorre »

Lite saker kom tyvärr imellan, men nu är jag tillbaka. Rev bort en skog med kablar bara för att isolera.

Jag provade med detta exempel, men samma resultat som tidigare. Jag är dock övertygad om att jag är felet. Visst initierar jag ADCn fel? Tyvärr har jag stirrat mig blind och ser inget fel.

Nedan vill jag bara ha LSBsen ut på PORTB samt att analog in just nu är satt till AN2. Såga mig inte för hårt, jag inser att jag är dum när jag postar detta. Klockan är för tidigt för att jag ska fungera.

Kod: Markera allt

void initADC(void)
{
	// CONFIG
	TRISA 	= 0b11111111;
	ANSEL0  = 0b11111111;
	ANSEL1  = 0b00000000;
	ADCON0	= 0b00001000;
	ADCON1	= 0b00000000;
	ADCON2	= 0b10110010;
	ADCON3	= 0b11000000;
	ADCHS	= 0b00000000;
	
	ADCON0bits.ADON = 1;

	Delay10KTCYx(50);		//5-10uSec needed
	
	ADCON0bits.GO_DONE = 1;
}

void convertADC(void)
{
 	ADCON0bits.GO_DONE = 1;
 	return;
}

char busyADC(void)
{
 	return ADCON0bits.GO_DONE;
}

int readADC(void)
{
 	//return (ADRESH << 8) | 	ADRESL;
 	return ADRESL;
}

unsigned int doADC(void)
{
		Delay10KTCYx(50);
		convertADC(); // Start conversion
		Delay10KTCYx(50);
		while(busyADC()); // Wait for completion
	return readADC();
}

unsigned char i = 0;

void main(void)
{
	OSCCON = OSCCON | 0b01110000; // 8MHz
	initADC();
	TRISB = 0x00;
	
	PORTB = ADRESL;
		while(1)
		{
			for(i=0;i<128;i++)
			{
				doADC();
				PORTB = ADRESL;
			}
		}

}
http://ww1.microchip.com/downloads/en/D ... 39616b.pdf
Sid 243-259
Senast redigerad av rävekorre 16 december 2005, 14:04:18, redigerad totalt 1 gång.
Skriv svar